João Guilherme - 130011126

Victor Henrique - 13/0145700

Introdução

editar

Finalidade

editar

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

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

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.

editar

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

Integraçã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

editar

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

GitLab CI - O Gitlab CI é o ambiente de Integração Contínua do GitLab.

Criação de ambiente de desenvolvimento portátil

editar

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

Vagrant - Ferramenta para criação de máquinas virtuais.

Criação de testes funcionais

editar

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

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
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

Integração Contínua

editar

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

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

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

É 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

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

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
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

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

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.