FlossCoach
João Guilherme - 130011126
Victor Henrique - 13/0145700
Introdução
editarFinalidade
editarO presente documento tem como objetivo definir um plano de gerenciamento para a configuração de software em um projeto escolhido, no caso, o FlossCoach.
Escopo
editarO plano de GCS tem como escopo a definição de técnicas e ferramentas a serem aplicadas ao FlossCoach a fim da sua melhora em relação a conceitos de Gerência de configuração de software.
Visão Geral
editarO documento está dividido da seguinte forma:
Projeto Escolhido - Breve descrição sobre o projeto escolhido pela dupla.
Ferramentas e técnicas a serem aplicadas - Definição e descrição de quais conceitos, ferramentas e técnicas foram esolhidas para serem aplicadas no projeto
Cronograma - Definição de datas para as atividades do projeto e marcos do mesmo.
Projeto Escolhido - Link Repositório
editarO projeto escolhido pela dupla foi o FlossCoach.
O FlossCoach pode ser definido como um portal de apoio a novatos com dificuldades em adentrar à comunidade de projetos de software livre.
Ferramentas e técnicas a serem aplicadas
editarIntegração continua
editar“Integração Contínua é uma pratica de desenvolvimento de software onde os membros de um time integram seu trabalho frequentemente, geralmente cada pessoa integra pelo menos diariamente – podendo haver multiplas integrações por dia. Cada integração é verificada por um build automatizado (incluindo testes) para detectar erros de integração o mais rápido possível. Muitos times acham que essa abordagem leva a uma significante redução nos problemas de integração e permite que um time desenvolva software coeso mais rapidamente.” Martin Fowler
Deploy Automático
editarA fim de se evitar trabalho com o deploy do software a toda nova versão do mesmo, será implantado o deploy automático, juntamente com o Gitlab CI.
Ferramenta
editarGitLab CI - O Gitlab CI é o ambiente de Integração Contínua do GitLab.
Criação de ambiente de desenvolvimento portátil
editarCom a criação de uma box (box é o nome que o Vagrant utilizada para definir cada máquina virtual), qualquer novo desenvolvedor que queira ajudar no crescimento do projeto terá muita facilidade para começar a trabalhar com o FlossCoach
Ferramenta
editarVagrant - Ferramenta para criação de máquinas virtuais.
Criação de testes funcionais
editarComo o Flosscoach é um projeto ainda no início de seu desenvolvimento, o mesmo não conta com uma suíte de testes funcionais, logo será criado os testes para as funcionalidades já existentes no projeto, contribuindo assim para uma melhor qualidade do software.
Ferramenta
editarCucumber/Selenium - Através do cucumber são criados os testes, e o selenium é responsável por realizar a simulação em um navegador web.
Cronograma
editarPeríodo | Atividade |
---|---|
26/09 a 02/10 | Definição do plano de projeto |
03/10 a 09/10 | Estudos sobre integração continua e deploy automático com o GitLab CI |
10/10 a 17/10 | Estruturação e implantação das técnicas de deploy automático e integração continua |
18/10 a 26/10 | Implementação dos testes funcionais |
27/10 a 02/11 | Estudo e criação da box com o vagrant |
03/11 a 06/11 | Conclusão, análise e revisão dos resultados |
07/11 a 13/11 | Criação da apresentação final e abertura do Merge-Request para o repositório oficial |
Resultados
editarIntegração Contínua
editarA integração continua foi feita com o GitLab CI e sua aplicação foi rápida e fácil. O processo necessário para aplicar a integração continua com essa ferramenta foi somente criar um arquivo .yml(o que pode ser feito na própria página do GitLab) contendo as configurações desejadas e salvá-lo. Após feito o commit, se tudo estiver correto, a integração contínua já estará implementada.
O arquivo .gitlab-ci.yml ficou configurado da seguinte forma:
before_script:
- apt-get update -qq && apt-get install -y -qq sqlite3 libsqlite3-dev nodejs
- ruby -v
- which ruby
- gem install bundler --no-ri --no-rdoc
- bundle install --jobs $(nproc) "${FLAGS[@]}"
rspec:
script:
- bundle exec rspec
Deploy Automático
editarO deploy automático foi feito utilizando o Heroku para a hospedagem do FlossCoach e o GitLabCi para a automatização do deploy.
Para isso, seria somente necessário a adição de linhas indicando o deploy no arquivo .gitlab-ci.yml. Porém, foram necessárias várias modificações nas configurações do FlossCoach para prepará-lo pro ambiente de produção.
Os problemas encontrados, suas soluções e o resultado final se encontram a seguir.
Heroku x SQLite3
editarO heroku não consegue trabalhar com o SQLite3, com isso foi necessário adicionar gems diferentes para o banco em produção, utilizando o postgresql. O gemfile ficou da seguinte forma:
group :production do
gem 'pg'
gem 'uglifier'
end
group :development do
gem 'sqlite3'
end
Necessidade de adicionar Gemfile.lock ao resposítório.
editarÉ necessário adicionar o Gemfile.lock para o repositório, para assegurar que as versões da gem do deploy são as mesma versões das gems encontradas na versão local da aplicação.
Arquivo do projeto com classe duplicada
editarExistia uma model no projeto, com uma classe (project), duplicada. Esse problema não se mostrava na aplicação em desenvolvimento por que o próprio rails suprimia esse erro. Já com o projeto em produção, o erro não era suprimido e não era possível subir o mesmo para o servidor. Após ser excluída a classe, foi possível subir o projeto.
Falta de preparação do projeto para ambiente de produção.
editarTodas essas gems e dependecias forma necessárias serem adicionadas no projeto, para que o mesmo ficasse apto ao ambiente de produção:
- Gems
- Uglifier
- Production (Separação do banco para desenvolvimento e produção)
- Resolv.conf (Dependencia necessária adicionada ao application.rb)
- Secret Key (Não existia, somente foi adicionada uma referencia a key para produção)
Resultado Final
editarstaging:
type: deploy
script:
- gem install dpl
- dpl --provider=heroku --app=deploygcs --api-key=df17f508-fe8c-4e83-8bb5-c68763b573db
only:
- master
production:
type: deploy
script:
- gem install dpl
- dpl --provider=heroku --api-key=$df17f508-fe8c-4e83-8bb5-c68763b573db
only:
- tags
Link para conferencia do deploy automático : https://deploygcs.herokuapp.com/
Criação de ambiente de desenvolvimento portátil
editarO ambiente de desenvolvimento foi feito no Vagrant.
Para isso deve ser criado o VagrantFile, no qual se encontram todas as dependencias necessárias para rodar o sistema.
O VagrantFile e os scripts usados foram os se seguintes :
VagrantFile:
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/xenial64"
config.vm.network "forwarded_port", guest: 3000, host: 3000
config.vm.provider "virtualbox" do |vb|
# Display the VirtualBox GUI when booting the machine
# vb.gui = true
# Customize the amount of memory on the VM:
vb.memory = "1024"
end
# SHELL
config.vm.provision :shell, path: "install_rvm.sh", args: "stable", privileged: false
config.vm.provision :shell, path: "install_ruby.sh", args: "2.3.1", privileged: false
config.vm.provision :shell, path: "install_ruby.sh", args: "2.3.1 rails haml", privileged: false
config.vm.provision :shell, path: "provision.sh", args: "2.3.1 rails haml", privileged: false
end
install_rvm.sh:
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
curl -sSL https://get.rvm.io | bash -s $1
install_ruby.sh:
#!/usr/bin/env bash
source $HOME/.rvm/scripts/rvm
rvm use --default --install $1
shift
if (( $# ))
then gem install $@
fi
rvm cleanup all
provision.sh:
#!/usr/bin/env bash
sudo apt-get update
sudo apt-get install -y nodejs nodejs-legacy postgresql-common postgresql-9.5
sudo apt-get install -y git curl automake build-essential bison
sudo apt-get install -y libpq-dev libssl-dev libtool libcurl4-openssl-dev
sudo apt-get install -y libyaml-dev libreadline-dev libxml2-dev libxslt1-dev
sudo apt-get install -y libffi-dev libffi-dev libgdbm-dev libncurses5-dev
sudo apt-get install -y libsqlite3-dev sqlite3 zlib1g-dev
sudo apt-get install -y python-software-properties
rvm default ruby-2.3.1
gem install bundler
gem install nokogiri -v '1.6.8'
gem install rails
sudo apt-get autoremove
sudo apt-get autoclean
sudo apt-get update
cd /vagrant/
bundle install
Para executar o ambiente virtual, devem ser executados os seguintes comandos, em sequência:
- vagrant up
- vagrant provision
- vagrant ssh
Criação de testes funcionais
editarPara criação/execução dos testes foram usadas as ferramentas selenium/cucumber, onde podemos ter uma simulação do uso da aplicação em um navegador web de maneira automatizada.
Como o software a ser analisado, já possui muitas funcionalidades, e no contexto do projeto, demandaria muito tempo para testar toda a aplicação, foram selecionadas apenas três para realização dos testes, que são:
- F01- Editar perfil do usuário;
- F02- Pesquisar projeto;
- F03- Efetuar login/logout;
Para cada funcionalidade descrita anteriormente, são especificados alguns cenários, os quais contemplam 100% da funcionalidade. Ou seja, a funcionalidade só é considerada 100% testada, caso todos os cenários estejam testados.Esse cenários são descritos em linguagem natural através de steps que simulam o uso da aplicação. Abaixo encontra-se a descrição dos cenários referentes a cada feature:
edit_profile.feature:
Feature: Edit profile user
Scenario: Editing user profile filling all fields correctly
Given I am logged into the application
And is on the profile editing page
And fill in all fields correctly
When I click in button "Submit"
Then I should see the message "User was successfully updated."
Scenario: Editing user profile by filling in all fields except the name field
Given I am logged into the application
And is on the profile editing page
And fill in all fields correctly except the name field
When I click in button "Submit"
Then I should see the message "Name can't be blank"
Scenario: Editing user profile by filling in all fields except the email field
Given I am logged into the application
And is on the profile editing page
And fill in all fields correctly except the email field
When I click in button "Submit"
Then I should see the message "Email can't be blank"
Scenario: Editing user profile by filling in all fields except the password field
Given I am logged into the application
And is on the profile editing page
And fill in all fields correctly except the password field
When I click in button "Submit"
Then I should see the message "Password can't be blank"
Scenario: Editing user profile by filling in all fields except the password confirmation field
Given I am logged into the application
And is on the profile editing page
And fill in all fields correctly except the password confirmation field
When I click in button "Submit"
Then I should see the message "Password confirmation doesn't match Password"
login.feature:
Feature: login in the application
Scenario: login with valid user
Given I am in the homepage
And fill in all login_fields correctly
When I click in button "submit"
Then I should see the message "Explore Flosscoach"
Scenario: login with invalid user
Given I am in the homepage
And fill in all login_fields incorrectly
When I click in button "submit"
Then I should see the message "Invalid e-mail or password."
Scenario: Logout
Given I am logged into the application
When I press button Logout
Then I should see the message "Please, visit us! Check our prototype and give us your feedback"
search_project.feature:
Feature: Search a project
Scenario: Search an existing project
Given I am logged into the application
And fill a project field with a existing project
When I press the enter button
Then I should see a project name
Scenario: Search as nonexistent project
Given I am logged into the application
And fill a project field with a nonexistent project
When I press the enter button
Then I should see the message "Explore Flosscoach"
Após criados, os cenários preenchemos os steps com instruções ruby, e temos o seguinte arquivo:
steps.rb:
Before do
@user = User.new(name: "Teste", email: "teste@gmail.com", password: "123123", email_confirmed: true)
@user.save
@project = Project.new(name: "project")
@project.save
end
Given(/^I am logged into the application$/) do
visit '/'
fill_in "user_email" , :with => "teste@gmail.com"
fill_in "user_password", :with => "123123"
click_button "submit"
end
Given(/^is on the profile editing page$/) do
visit '/users/1/edit'
end
Given(/^fill in all fields correctly$/) do
fill_in "user_name" , :with => "Teste2"
fill_in "user_email" , :with => "teste2@gmail.com"
fill_in "user_password", :with => "123123"
fill_in "user_password_confirmation", :with => "123123"
end
Given(/^fill in all fields correctly except the name field$/) do
fill_in "user_email" , :with => "teste@gmail.com"
fill_in "user_password", :with => "123123"
fill_in "user_password_confirmation", :with => "123123"
end
Given(/^fill in all fields correctly except the email field$/) do
fill_in "user_name" , :with => "Teste"
fill_in "user_password", :with => "123123"
fill_in "user_password_confirmation", :with => "123123"
end
Given(/^fill in all fields correctly except the password field$/) do
fill_in "user_name" , :with => "Teste"
fill_in "user_email" , :with => "teste@gmail.com"
fill_in "user_password_confirmation", :with => "123123"
end
Given(/^fill in all fields correctly except the password confirmation field$/) do
fill_in "user_name" , :with => "Teste"
fill_in "user_email" , :with => "teste@gmail.com"
fill_in "user_password", :with => "123123"
end
Given(/^I am in the homepage$/) do
visit '/'
end
Given(/^fill in all login_fields correctly$/) do
fill_in "user_email" , :with => "teste@gmail.com"
fill_in "user_password", :with => "123123"
end
When(/^I click in button "([^"]*)"$/) do |arg1|
click_button arg1
end
Then(/^I should see the message "([^"]*)"$/) do |arg1|
expect(page).to have_content(arg1)
end
Given(/^fill in all login_fields incorrectly$/) do
fill_in "user_email" , :with => "teste@gmail.com"
fill_in "user_password", :with => "123456"
end
When(/^I press button Logout$/) do
visit '/users/logout'
end
Given(/^fill a project field with a existing project$/) do
fill_in "search", :with => "project"
end
Then(/^I should see a project name$/) do
expect(page).to have_content("project")
end
When(/^I press the enter button$/) do
find(:id, 'inputSearch').native.send_keys(:enter)
end
Given(/^fill a project field with a nonexistent project$/) do
fill_in "search", :with => "nonexistent ---project"
end
Criados os steps, basta apena rodar o comando "cucumber" e os testes serão executados.