FlossCoach
João Guilherme - 130011126
Victor Henrique - 13/0145700
Introdução
[editar | editar código-fonte]Finalidade
[editar | editar código-fonte]O 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
[editar | editar código-fonte]O 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
[editar | editar código-fonte]O 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
[editar | editar código-fonte]O 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
[editar | editar código-fonte]Integração continua
[editar | editar código-fonte]“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
[editar | editar código-fonte]A 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
[editar | editar código-fonte]GitLab CI - O Gitlab CI é o ambiente de Integração Contínua do GitLab.
Criação de ambiente de desenvolvimento portátil
[editar | editar código-fonte]Com 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
[editar | editar código-fonte]Vagrant - Ferramenta para criação de máquinas virtuais.
Criação de testes funcionais
[editar | editar código-fonte]Como 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
[editar | editar código-fonte]Cucumber/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
[editar | editar código-fonte]Perí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
[editar | editar código-fonte]Integração Contínua
[editar | editar código-fonte]A 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
[editar | editar código-fonte]O 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
[editar | editar código-fonte]O 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 | editar código-fonte]É 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
[editar | editar código-fonte]Existia 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.
[editar | editar código-fonte]Todas 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
[editar | editar código-fonte]staging:
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
[editar | editar código-fonte]O 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
[editar | editar código-fonte]Para 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.