FlossCoach

Fonte: Wikiversidade

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.