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.properties
ao 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-xdebug
Todos 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 oapt-get
para 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
phpunit
na 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
push
das alterações ao ficheiro de configurações para o servidor.Antes de enviares as alterações, adiciona o diretórioci
ao 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
ci
criado.
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.projectName
esonar.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órioapp
porque aí estará todo o nosso código.Não faz sentido incluir o diretório
vendor
,node_components
oubower_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.reportPath
esonar.php.tests.reportPath
: Indicam quais os caminhos do output dos testes do PHPUnit. Deves definir os mesmo caminhos já definidos no ficheirophpunit.xml
, no ponto anterior.sonar.exclusions
: Permite definir exclusões de ficheiros ou diretórios existentes que pertencam ao diretório definido emsonar.sources
. No nosso caso e especificamente para efeitos de testes excluimos o diretórioProviders
. 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
app
continha 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