No artigo anterior instalámos e configurámos o SonarQube e o SonarQube Runner. Agora que temos as ferramentas instaladas, vamos analisar o projeto Laravel 5 que criámos no segundo artigo da série “Como criar um servidor de integração contínua”.
Esta série de artigos sobre Integração Contínua começou com o artigo Ferramentas para servidor de integração continua (CI) e mostra como criar um servidor de integração contínua para projetos PHP.
Este artigo encontra-se dividido nas seguintes secções:
- Instalar PHPUnit e configurar o phpunit.xml
- Adicionar o ficheiro sonar-project.propertiesao projeto
- Executar análise do projeto com o SonarQube Runner
1. Instalar PHPUnit e configurar o phpunit.xml
Para que o SonarQube seja capaz de interpretar a nossa aplicação, nomeadamente a cobertura de testes ao código, vamos usar o PHPUnit. O PHPUnit vem incluído por defeito com o Laravel, mas vamos ter de o instalar no servidor e alterar as definições do phpunit.xml. Para isso, segue os seguintes passos.
- Vamos começar por instalar o PHPUnit globalmente, através dos comandos: - cd ~/Downloads wget https://phar.phpunit.de/phpunit.phar chmod +x phpunit.phar sudo mv phpunit.phar /usr/local/bin/phpunit
- Para que o PHPUnit consiga exportar e guardar os resultados dos testes é necessário que tenhas a extensão XDebug ativa no PHP. Para instalares a extensão deves executar o comando abaixo. - sudo apt-get install php5-xdebugTodos os comandos especificados neste artigo foram executados num Linux Mint baseado em Ubunto. Caso utilizes outra distribuição é provável que apenas tenhas de alterar o- apt-getpara o gestor de dependências correto. No entanto, é possível que os nomes das dependências sejam diferentes.
- Para que o resultado dos testes seja interpretado pelo SonarQube, como já indiquei, é necessário ajustar a configuração do PHPUnit. Por defeito o Laravel já inclui o ficheiro de configuração - phpunit.xml, na raiz do projeto, e é esse ficheiro que vamos alterar para o seguinte conteúdo:- <?xml version="1.0" encoding="UTF-8"?> <phpunit backupGlobals="false" backupStaticAttributes="false" bootstrap="bootstrap/autoload.php" colors="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false" syntaxCheck="false"> <testsuites> <testsuite name="Application Test Suite"> <directory>./tests/</directory> </testsuite> </testsuites> <php> <env name="APP_ENV" value="testing"/> <env name="CACHE_DRIVER" value="array"/> <env name="SESSION_DRIVER" value="array"/> <ini name="memory_limit" value="2048M"/> </php> <logging> <log type="coverage-html" target="./ci/codeCoverage/" charset="UTF-8" yui="true" highlight="false" lowUpperBound="35" highLowerBound="70"/> <log type="coverage-clover" target="./ci/codeCoverage/codeCoverage.xml"/> <log type="metrics-xml" target="./ci/codeCoverage/metrics.xml"/> <log type="test-xml" target="./ci/codeCoverage/logfile.xml" logIncompleteSkipped="false"/> </logging> </phpunit>- As configurações que alterei, em relação à verão original do ficheiro, foram: - No grupo <php>incluí a propriedade<ini name="memory_limit" value="2048M"/>que permite aumentar o limite da memória do PHP quando os testes estão a ser executados. Embora esta propriedade não seja obrigatória eu recomendo que a adiciones para que o processo PHP tenha memória suficiente quando os testes são executados.
- Adicionei o grupo - <logging>que é o que realmente interessa. Esta configuração permite registar o resultado dos testes que será lido pelo SonarRunner.- É importante registar a informação resultante do PHPUnit para que seja possível saber qual a percentagem de cobertura de testes do teu código. Ou seja, com este output do PHPUnit o SonarQube consegue detetar qual a percentagem do teu código que está testado. - Para efeitos desta demonstração o resultado dos testes é guardado num novo diretório, em - «project_root»/ci/codeCoverage.
 
- No grupo 
- Executa o comando - phpunitna raiz do teu projeto para garantir que está tudo a funcionar corretamente. Deves ver a informação da criação do output e os diretórios serão criados automaticamente:  
- Agora faz - pushdas alterações ao ficheiro de configurações para o servidor.Antes de enviares as alterações, adiciona o diretório- ciao ficheiro- .gitignore. Os ficheiros apenas são úteis para a análise do SonarQube e não existe qualquer necessidade de os colocares no repositório.
- Depois de enviares as alterações, será executada a configuração no TeamCity e, caso acedas à aplicação, deves ver qualquer coisa como:   - Aguarda que a execução termine antes de procederes ao passo seguinte. 
- Vamos verificar que os testes são executados no servidor e que o resultado é armazenado no diretório - ci. Para isso, acede ao servidor através do terminal, ao diretório que contem o código no Teamcity Agent, como apresentado de seguida. Lembra-te de substituir a {hash} pelo nome correto do diretório.- cd /opt/TeamcityAgent/work/{hash} phpunit- Se tudo correu bem, deves ver uma informação semelhante à da imagem seguinte e deverás ter o diretório - cicriado.  
2. Adicionar o ficheiro sonar-project.properties ao projeto
O teu projeto ainda não é visível no SonarQube porque ainda não foi executada nenhuma análise. Para que a análise seja feita corretamente, deves adicionar um novo ficheiro, com nome sonar-project.properties à raiz do teu projeto, com o seguinte conteúdo:
# Required metadata
sonar.projectKey=testproject
sonar.projectName=testproject
sonar.projectVersion=1.0.0
# Path to the parent source code directory.
sonar.sources=app
# Language
# We've commented this out, because we want to analyse both PHP and Javascript
#sonar.language=php
# Encoding of the source code
sonar.sourceEncoding=UTF-8
# Reusing PHPUnit reports
sonar.php.coverage.reportPath=ci/codeCoverage/codeCoverage.xml
sonar.php.tests.reportPath=ci/testResults.xml
# Here, you can exclude all the directories that you don't want to analyse.
# As an example, I'm excluding the Providers directory
sonar.exclusions=app/Providers/**
# Additional parameters
#sonar.my.property=value
Este ficheiro contem a informação necessária para a análise do projeto. Segue uma breve descrição das configurações do ficheiro.
- sonar.projectKey,- sonar.projectNamee- sonar.projectVersion: são valores obrigatórios e permitem identificar o projeto no SonarQube (nomeadamente o projectKey).
- sonar.sources: Indica qual o diretório que contém o código fonte da tua aplicação. No nosso caso apontamos para o diretório- appporque aí estará todo o nosso código.- Não faz sentido incluir o diretório - vendor,- node_componentsou- bower_components, uma vez que estes diretórios já contém código testado e o código não é mantido por ti, pelo que a análise a este código causaria uma perda de tempo e poderia causar análises irrealistas. Apenas interessa o código da tua aplicação e é esse que deve ser testado e analisado.
- sonar.language: Indica qual a linguagem de programação a usar na análise. Como podes ver, temos esta propriedade comentada (com o caracter #) porque pretendemos ter uma análise a mais que uma linguagem (PHP e Javascript).
- sonar.php.coverage.reportPathe- sonar.php.tests.reportPath: Indicam quais os caminhos do output dos testes do PHPUnit. Deves definir os mesmo caminhos já definidos no ficheiro- phpunit.xml, no ponto anterior.
- sonar.exclusions: Permite definir exclusões de ficheiros ou diretórios existentes que pertencam ao diretório definido em- sonar.sources. No nosso caso e especificamente para efeitos de testes excluimos o diretório- Providers. Num caso real deves remover esta propriedade ou definir diretórios ou ficheiros que não devam ser usados na análise.- Como nota, esta propriedade era útil com projetos Laravel 4, porque o diretório - appcontinha ficheiros relativos a base de dados (- database), a traduções (- langs), ao armazenamento (- storage) e a vistas (- views), todos eles irrelevantes para a análise que pretendemos com o SonarQube.
- sonar.my.property: Esta propriedade está comentada e serve apenas para perceberes que podes definir propriedades especificas do teu projeto, que poderão depois ser usadas no SonarQube.
Existe mais informação passível de colocar neste ficheiro de configurações e existe informação específica mediante a linguagem e o tipo de projetos. Podes ver na página do GitHub exemplos do ficheiro de configuração, bastando
- Selecionar a linguagem que pretendes
- Procurar pelo diretório que termina em sonar-runner
- Visualizar o conteúdo do ficheiro sonar-project.properties
Depois de adicionares o ficheiro ao projeto e o preencheres corretamente, envia as alterações para o repositório Git (git push).
3. Executar análise do projeto com o SonarQube Runner
Vamos executar o SonarQube Runner pela primeira vez, para que o projeto seja adicionado ao SonarQube. Para o efeito acede ao diretório da aplicação, no servidor, e executa o comando para efetuar a análise
cd /opt/TeamcityAgent/work/{hash}
sudo /opt/sonar-runner-2.4/bin/sonar-runner -e -X
Este comando deve terminar com a informação EXECUTION SUCCESS. Agora, quando acederes ao SonarQube, já deverás ver o teu projeto:
 
  
Se carregares no nome do projeto, és direcionado para uma página que contem os seus detalhes. No entanto, a informação apresentada ainda não é real
 
  
Isto acontece porque a análise feita ao nosso projeto foi Java (lembra-te que comentámos a propriedade sonar.language no ponto anterior e, como tal, o SonarQube Runner não sabe a linguagem que deve usar na analise.
Temos então de indicar ao SonarQube quais as linguagens que queremos analisar. Para isso, deves aceder a Settings » System » Update Center, como apresentado na imagem abaixo
 
  
Nesta página é possível instalar vários plugins e, para o nosso caso, vamos instalar três: PHP, Javascript (ambos dentro do grupo Languages) e Redmine (dentro do grupo Integration). Para instalares os plugins deves carregar sobre o nome do plugin e carregar no botão Install.
 
  
Depois de instalados os três plugins, reinicia o SonarQube com o comando
/opt/sonarqube-5.1.1/bin/linux-x86-64/sonar.sh restart
A análise ao projeto é feita através de Perfis de Qualidade. Estes perfis podem ser pré-configurados (como, por exemplo, o PSR-2) ou podem ser definidos por ti. Podes gerir os perfis no menu Quality Profiles.
 
  
Vamos agora associar os perfis de qualidade ao nosso projeto. Para o efeito, acede ao Dashboard e clica no nome do teu projeto. Dentro do teu projeto, acede ao menu Settings » Quality Profiles. Define, nessa página, o perfil Sonar way para Javascript e PSR-2 para PHP.
 
  
 
  
Agora volta a executar manualmente a análise do projeto com o comando:
cd /opt/TeamcityAgent/work/{hash}
sudo /opt/sonar-runner-2.4/bin/sonar-runner -e -X
Neste momento já deves ver o número de linhas de código, a quantidade de problemas que tens para resolver e quais os ficheiros em que os tens de resolver. Existe uma panóplia de informação disponível e de formas de visualizar essa informação, que deixo para explorares.
 
  
 
  
 
  
 
  
Com isto consegues analisar o teu projeto e perceber a complexidade da tua aplicação. A minha recomendação é que faças um acompanhamento periódico à qualidade da tua aplicação e à Divida Técnica.
No próximo e último artigo desta série de Integração Contínua, vamos integrar o SonarQube com o TeamCity e com o Redmine.
Este artigo faz parte da série Como criar um servidor de integração contínua
- Ferramentas para servidor de integração continua (CI)
- Instalar SSH e Git em Linux e configuração da máquina de desenvolvimento Windows
- Instalação do Git e integração com o Redmine
- Instalação do TeamCity 9 em Linux
- Instalar e configurar TeamCity Agent em servidor Linux Mint
- Instalar SonarQube e SonarQube Runner em Linux Mint
- Analisar projeto Laravel 5 (PHP) com o SonarQube - Estás a ler este artigo
- Integrar SonarQube com TeamCity e Redmine
