Birleştirilmiş kapsama raporu vermek için çoklu modül Maven + Sonar + JaCoCo nasıl yapılandırılır?


128

Bunun için internette aşağı yukarı aradım. Maven gibi özellikleriyle hiç orada yarım cevapları çok şey vardır ${sonar.jacoco.reportPath}, ya org.jacoco:jacoco-maven-plugin:prepare-agentya ayar maven-surefire-plugin argLineile -javaagent.

Bazıları, bu yanıtların hiçbiri, kendi başlarına veya kombinasyon halinde, peşinde olduğum şeyi üretmiyor: Kullanılan varlıklar gibi yığının üstündeki testlerde kullanılıyorsa, bir sınıfı kapsanmış gibi gösteren bir kapsam raporu DAO'lar tarafından, kendi modülünde tamamen test edilmemiş olmasına rağmen.

Bunu başarmak için bir yerde kesin bir yapılandırma var mı lütfen?

Yanıtlar:


165

Ben de sizinle aynı durumdaydım, İnternet'e dağılmış yarım cevaplar oldukça sinir bozucuydu, çünkü pek çok insanın aynı sorunu yaşadığı görülüyordu, ancak hiç kimse bunu nasıl çözdüklerini tam olarak açıklamaya zahmet edemiyordu.

Sonar dokümanlar bakın örneklerle bir GitHub proje faydalıdır. Bunu çözmek için yaptığım şey, entegrasyon testleri mantığını normal birim testlerine uygulamaktı (uygun birim testleri alt modüle özgü olsa da, bu her zaman böyle değildir).

Ana pom.xml'de şu özellikleri ekleyin:

<properties>
    <!-- Sonar -->
    <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
    <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
    <sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
    <sonar.language>java</sonar.language>
</properties>

Bu, Sonar'ın tüm alt modüller için aynı yerde (ana projede bir hedef klasör) birim test raporlarını almasını sağlayacaktır. Ayrıca Sonar'a kendi raporlarını döndürmek yerine manuel olarak çalıştırılan raporları yeniden kullanmasını söyler. Sadece jacoco-maven-eklentisini tüm alt modüller için çalıştırmalıyız, bunu build / plugins içine ana pom'a yerleştirerek:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.6.0.201210061924</version>
    <configuration>
        <destFile>${sonar.jacoco.reportPath}</destFile>
        <append>true</append>
    </configuration>
    <executions>
        <execution>
            <id>agent</id>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
    </executions>
</plugin>

destFilerapor dosyasını Sonar'ın arayacağı yere yerleştirir ve appendüzerine yazmak yerine dosyaya eklemesini sağlar. Bu, tüm alt modüller için tüm JaCoCo raporlarını aynı dosyada birleştirecektir.

Sonar, her alt modül için bu dosyaya bakacak, çünkü onu yukarıda gösterdiğimiz şey, Sonar'daki çoklu modül dosyaları için bize birleşik birim test sonuçları veriyor.


Muhteşem! Bu işe yaradı. En sonunda! Bence kaçırdığım sihirli eksik hayati büyülü <append> doğru </append>
Stewart

İşe yarıyor! Oluşturulan yeni rapor yolunu almak için mvn packageçalıştırmadan önce yeni bir şey yapmam gerekiyordu mvn sonar:sonar.
thomasa88

2
Örneğe göre, "sonar.jacoco.itReportPath" özelliği, birleştirilmiş sonuçları "genel kod kapsamına" almak için kullanılmalıdır. Lütfen yanıtı güncelleyin.
Yves Martin

4
"sonar.dynamicAnalysis" de kullanımdan kaldırıldı: docs.sonarqube.org/display/SONAR/Release+4.3+Upgrade+Notes
Yves Martin


23

SSS

Jacob ile çıldırdığım zamandan beri kafamın tepesinden gelen sorular.

Irak, Suriye'de bulunan uygulama sunucum (jBoss, Glassfish ..), her neyse .. Üzerinde entegrasyon testleri çalıştırırken çoklu modül kapsamı almak mümkün müdür? Jenkins ve Sonar da farklı sunucularda.

Evet. Modda çalışan jacoco ajanını kullanmalısınız output=tcpserver, jacoco ant lib. Temelde iki jars. Bu size% 99 başarı sağlayacaktır.

Jacob ajanı nasıl çalışır?

Bir dize eklersiniz

-javaagent:[your_path]/jacocoagent.jar=destfile=/jacoco.exec,output=tcpserver,address=*

JAVA_OPTS uygulama sunucunuza bağlayın ve yeniden başlatın. Bu dizede yalnızca [your_path], uygulama sunucusunun çalıştığı sanal makinenizde depolanan (saklayın!) Jacocoagent.jar yolu ile değiştirilmesi gerekir. Uygulama sunucusunu başlattığınız andan itibaren, dağıtılan tüm uygulamalar dinamik olarak izlenecek ve etkinlikleri (kod kullanımı anlamında) tcl isteği ile jacocos .exec biçiminde almanız için hazır olacaktır.

Jacoco aracısını, yalnızca testim başladığından beri yürütme verilerini toplamaya başlayacak şekilde sıfırlayabilir miyim?

Evet, bu amaçla jacocoant.jar ve jenkins çalışma alanınızda bulunan ant build betiğine ihtiyacınız var.

Yani temelde http://www.eclemma.org/jacoco/ adresinden ihtiyacım olan şey jenkins çalışma alanımda bulunan jacocoant.jar ve uygulama sunucusu sanal makinemde bulunan jacocoagent.jar mı?

Doğru.

Ant kullanmak istemiyorum, jacoco maven eklentisinin de her şeyi yapabileceğini duydum.

Bu doğru değil, jacoco maven eklentisi birim test verilerini ve bazı entegrasyon testleri verilerini toplayabilir ( bkz.Arquillian Jacoco ), ancak örneğin jenkins'te ayrı bir yapı olarak testlerden eminseniz ve çoklu modül kapsamını göstermek istiyorsanız, Maven eklentisinin size nasıl yardımcı olabileceğini göremiyorum.

Jacoco ajanı tam olarak ne üretir?

Yalnızca .execformattaki kapsama verileri . Sonar daha sonra okuyabilir.

Jacoco'nun java sınıflarımın nerede olduğunu bilmesi gerekiyor mu?

Hayır, sonar yok ama jacoco değil. Bunu yaptığınızda mvn sonar:sonarsınıflara yolunu devreye giriyor.

Peki ya karınca senaryosu?

Jenkins çalışma alanınızda sunulmalıdır. Benim karınca senaryosu, buna jacoco.xmlbenziyor dedim :

<project name="Jacoco library to collect code coverage remotely" xmlns:jacoco="antlib:org.jacoco.ant">
    <property name="jacoco.port" value="6300"/>
    <property name="jacocoReportFile" location="${workspace}/it-jacoco.exec"/>

    <taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml">
        <classpath path="${workspace}/tools/jacoco/jacocoant.jar"/>
    </taskdef>

    <target name="jacocoReport">
            <jacoco:dump address="${jacoco.host}" port="${jacoco.port}" dump="true" reset="true" destfile="${jacocoReportFile}" append="false"/>
    </target>

    <target name="jacocoReset">
            <jacoco:dump address="${jacoco.host}" port="${jacoco.port}" reset="true" destfile="${jacocoReportFile}" append="false"/>
        <delete file="${jacocoReportFile}"/>
    </target>
</project>

Bu komut dosyasını çalıştırırken geçmeniz gereken iki zorunlu parametre, bunu -Dworkspace=$WORKSPACE jenkins çalışma alanınıza ve -Djacoco.host=yourappserver.comana makinenize işaret etmek için kullanın.http://

Ayrıca jacocoant.jar$ {workspace} /tools/jacoco/jacocoant.jar'a koyduğuma dikkat edin

Sonra ne yapmalıyım?

Uygulama sunucunuzu jacocoagent.jar ile mi başlattınız?

Jenkins çalışma alanınıza ant script ve jacocoant.jar eklediniz mi?

Cevabınız evet ise, son adım bir jenkins yapısı yapılandırmaktır. İşte strateji:

  1. jacocoResetÖnceden toplanan tüm verileri sıfırlamak için karınca hedefini çağırın .
  2. Testlerinizi çalıştırın
  3. jacocoReportRapor almak için karınca hedefini çağırın

Her şey doğruysa, it-jacoco.execderleme çalışma alanınızda göreceksiniz .

Ekran görüntüsüne bakın, ben de antçalışma alanıma direk yükledim $WORKSPACE/tools/ant, ancak jenkins'inizde kurulu olanı kullanabilirsiniz.

görüntü açıklamasını buraya girin

Bu raporu sonarda nasıl itebilirim?

Maven sonar:sonarişi yapacak (yapılandırmayı unutmayın), ana pom.xml'ye işaret ederek tüm modülleri çalıştıracaktır. sonar.jacoco.itReportPath=$WORKSPACE/it-jacoco.execSonara entegrasyon testi raporunuzun nerede olduğunu söylemek için parametreyi kullanın . Yeni modül sınıflarını her analiz ettiğinde, kapsamı hakkında bilgi arayacaktır it-jacoco.exec.

"Target" dizinimde jacoco.exec zaten var, "mvn sonar: sonar" yok sayıyor / kaldırıyor

Varsayılan olarak hedef dizininizi mvn sonar:sonaryapar cleanve siler, sonar.dynamicAnalysis=reuseReportsbunu önlemek için kullanın .


20

0.7.7 SÜRÜMÜNDEN BERİ YENİ YOL

0.7.7 Sürümünden bu yana, toplu bir rapor oluşturmanın yeni bir yolu var:

Gerekli tüm raporları toplayan ayrı bir 'rapor' projesi oluşturursunuz (Toplayıcı projedeki herhangi bir hedef , modüllerinden önce yürütülür , bu nedenle kullanılamaz).

aggregator pom
  |- parent pom
  |- module a
  |- module b
  |- report module 

Kök pom böyle görünüyor (modüllerin altında yeni rapor modülü eklemek unutmayın):

<build>
<plugins>
  <plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.7.8</version>
    <executions>
      <execution>
        <id>prepare-agent</id>
        <goals>
          <goal>prepare-agent</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
</plugins>

Her bir alt modülden gelen pomların hiç değiştirilmesine gerek yoktur. Rapor modülündeki pom şuna benzer:

<!-- Add all sub modules as dependencies here -->
<dependencies>
  <dependency>
    <module a>
  </dependency>
  <dependency>
    <module b>
  </dependency>
 ...

  <build>
    <plugins>
      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.7.8</version>
        <executions>
          <execution>
            <id>report-aggregate</id>
            <phase>verify</phase>
            <goals>
              <goal>report-aggregate</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

Tam bir örnek burada bulunabilir .


3
Bu çalışıyor. Toplu rapor, tüm modüller için kümülatif kod kapsamını gösterir. Bu kümülatif raporu Sonar'da görüntülemeyi hiç denediniz mi? Tek tek raporlar için jacoco.exec okumak için sonar-qube kullandım, ancak bu rapor toplamıyla, rapor modülünde birleştirilmiş jacoco.exec görmüyorum.
Swetha V

@SwethaV Bu konuda herhangi bir başarı var mı? Aynı konumdayız ve birleştirilmiş exec oluşturmanın bir yolunu bulmamız gerekiyor :)
Vinky

Kendi test kapsama sayfası olan sonar qube sürüm 6.X'i kullanıyoruz, bu yüzden orada jacoco'ya ihtiyacım yok. Daha eski bir sürüm için, bu işlevi de sağlayan cobertura eklentisini yükledik ...
Lonzak

12

Çözümümü diğerlerinden biraz farklı olduğu için göndereceğim ve ayrıca mevcut cevapların yardımıyla doğruya ulaşmam için sağlam bir gün geçirdim.

Çok modüllü bir Maven projesi için:

ROOT
|--WAR
|--LIB-1
|--LIB-2
|--TEST

Nerede WARproje ana web uygulaması, LIB1 ve 2 ek modüller şunlardır WARbağlıdır ve TESTentegrasyon testleri canlı yerdir. TESTgömülü bir Tomcat örneğini (Tomcat eklentisi aracılığıyla değil) döndürür ve WARprojeyi çalıştırır ve bir dizi JUnit testi aracılığıyla bunları test eder. WARveLIB projeler hem kendi birim testleri var.

Tüm bunların sonucu, entegrasyon ve birim testi kapsamının ayrılması ve SonarQube'de ayırt edilebilmesidir.

ROOT pom.xml

<!-- Sonar properties-->
<sonar.jacoco.itReportPath>${project.basedir}/../target/jacoco-it.exec</sonar.jacoco.itReportPath>
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
<sonar.language>java</sonar.language>
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>

<!-- build/plugins (not build/pluginManagement/plugins!) -->
<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.7.6.201602180812</version>
    <executions>
        <execution>
            <id>agent-for-ut</id>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
            <configuration>
                <append>true</append>
                <destFile>${sonar.jacoco.reportPath}</destFile>
            </configuration>
        </execution>
        <execution>
            <id>agent-for-it</id>
            <goals>
                <goal>prepare-agent-integration</goal>
            </goals>
            <configuration>
                <append>true</append>
                <destFile>${sonar.jacoco.itReportPath}</destFile>
            </configuration>
        </execution>
    </executions>
</plugin>

WAR, LIB Ve TEST pom.xmlJaCoCo eklentileri yürütülmesine devralır.

TEST pom.xml

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.19.1</version>
    <executions>
        <execution>
            <goals>
                <goal>integration-test</goal>
                <goal>verify</goal>
            </goals>
            <configuration>
                <skipTests>${skip.tests}</skipTests>
                <argLine>${argLine} -Duser.timezone=UTC -Xms256m -Xmx256m</argLine>
                <includes>
                    <includes>**/*Test*</includes>
                </includes>
            </configuration>
        </execution>
    </executions>
</plugin>

Ayrıca Petri Kainulainens blog gönderisinin 'JaCoCo Maven Eklentisiyle Birim ve Entegrasyon Testleri için Kod Kapsamı Raporları Oluşturma' yazısının JaCoCo kurulum tarafı için değerli olduğunu gördüm.


Aslında biraz yetersiz olduğu için bu gönderiyi bir aşamada güncellemem gerekiyor. agent-for-itsadece TESTmodüldeki testleri çalıştırırken gereklidir, ancak mevcut konfigürasyon, hiçbir değerinin olmadığı diğer tüm modüller için çalışmasını sağlar. İyileştirme, agent-for-utdiğer tüm modüllerde agent-for-itçalıştırılmış ve yalnızca çalıştırılmış olacaktır TEST.
markdsievers

8

Bunu başarmanın bir yolu var. Sihir, birleşik bir jacoco.exec dosyası oluşturmaktır. Ve maven 3.3.1 ile bunu elde etmenin kolay bir yolu var. İşte benim profilim:

<profile>
    <id>runSonar</id>
    <activation>
        <property>
            <name>runSonar</name>
            <value>true</value>
        </property>
    </activation>
    <properties>
        <sonar.language>java</sonar.language>
        <sonar.host.url>http://sonar.url</sonar.host.url>
        <sonar.login>tokenX</sonar.login>
        <sonar.jacoco.reportMissing.force.zero>true</sonar.jacoco.reportMissing.force.zero>
        <sonar.jacoco.reportPath>${jacoco.destFile}</sonar.jacoco.reportPath>
        <jacoco.destFile>${maven.multiModuleProjectDirectory}/target/jacoco_analysis/jacoco.exec</jacoco.destFile>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>default-prepare-agent</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                        <configuration>
                            <append>true</append>
                            <destFile>${jacoco.destFile}</destFile>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.sonarsource.scanner.maven</groupId>
                    <artifactId>sonar-maven-plugin</artifactId>
                    <version>3.2</version>
                </plugin>
                <plugin>
                    <groupId>org.jacoco</groupId>
                    <artifactId>jacoco-maven-plugin</artifactId>
                    <version>0.7.8</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</profile>

Bu profili ebeveyninize eklerseniz ve ararsanız mvn clean install sonar:sonar -DrunSonar , tüm kapsamı alırsınız.

Buradaki sihir maven.multiModuleProjectDirectory. Bu klasör her zaman maven derlemenizi başlattığınız klasördür.


Bu, başka birçok çözümden geçtikten sonra benim için çalıştı.
Jimson Kannanthara James

Tek sorun, hata mvn org.sonarsource.scanner.maven:sonar-maven-plugin:3.4.0.905:sonar -DrunSonarnedeniyle sonarı komutla çalıştırmam gerekti A required class was missing while executing org.sonarsource.scanner.maven:sonar-maven-plugin:3.0.1:sonar: org/sonar/batch/bootstrapper/IssueListener.
Jimson Kannanthara James

1
Bu sihri kullanma. Verilen özellik bir uygulama detayıdır ve güvenilmeyecektir. - Maven Geliştirici Ekibi
Michael-O

6

Ayrı birim ve entegrasyon test aşamalarına sahip olduğum üst düzey pom'umda kullandığım yapılandırma.

Üst POM Özelliklerinde aşağıdaki özellikleri yapılandırıyorum

    <maven.surefire.report.plugin>2.19.1</maven.surefire.report.plugin>
    <jacoco.plugin.version>0.7.6.201602180812</jacoco.plugin.version>
    <jacoco.check.lineRatio>0.52</jacoco.check.lineRatio>
    <jacoco.check.branchRatio>0.40</jacoco.check.branchRatio>
    <jacoco.check.complexityMax>15</jacoco.check.complexityMax>
    <jacoco.skip>false</jacoco.skip>
    <jacoco.excludePattern/>
    <jacoco.destfile>${project.basedir}/../target/coverage-reports/jacoco.exec</jacoco.destfile>

    <sonar.language>java</sonar.language>
    <sonar.exclusions>**/generated-sources/**/*</sonar.exclusions>
    <sonar.core.codeCoveragePlugin>jacoco</sonar.core.codeCoveragePlugin>
    <sonar.coverage.exclusions>${jacoco.excludePattern}</sonar.coverage.exclusions>
    <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
    <sonar.jacoco.reportPath>${project.basedir}/../target/coverage-reports</sonar.jacoco.reportPath>

    <skip.surefire.tests>${skipTests}</skip.surefire.tests>
    <skip.failsafe.tests>${skipTests}</skip.failsafe.tests>

Eklenti tanımlarını eklenti yönetimi altına yerleştiriyorum.

Jacoco'nun javaagent'i her testte çalışacak şekilde yapılandırmasına izin vermek için surefire (surefireArgLine) ve failsafe (failsafeArgLine) argümanları için bir özellik tanımladığımı unutmayın.

Eklenti Yönetimi altında

  <build>
     <pluginManagment>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <fork>true</fork>
                    <meminitial>1024m</meminitial>
                    <maxmem>1024m</maxmem>
                    <compilerArgument>-g</compilerArgument>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19.1</version>
                <configuration>
                    <forkCount>4</forkCount>
                    <reuseForks>false</reuseForks>
                    <argLine>-Xmx2048m ${surefireArgLine}</argLine>
                    <includes>
                        <include>**/*Test.java</include>
                    </includes>
                    <excludes>
                        <exclude>**/*IT.java</exclude>
                    </excludes>
                    <skip>${skip.surefire.tests}</skip>
                </configuration>
            </plugin>
            <plugin>
                <!-- For integration test separation -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.19.1</version>
                <dependencies>
                    <dependency>
                        <groupId>org.apache.maven.surefire</groupId>
                        <artifactId>surefire-junit47</artifactId>
                        <version>2.19.1</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <forkCount>4</forkCount>
                    <reuseForks>false</reuseForks>
                    <argLine>${failsafeArgLine}</argLine>
                    <includes>
                        <include>**/*IT.java</include>
                    </includes>
                    <skip>${skip.failsafe.tests}</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>integration-test</id>
                        <goals>
                            <goal>integration-test</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>verify</id>
                        <goals>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <!-- Code Coverage -->
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>${jacoco.plugin.version}</version>
                <configuration>
                    <haltOnFailure>true</haltOnFailure>
                    <excludes>
                        <exclude>**/*.mar</exclude>
                        <exclude>${jacoco.excludePattern}</exclude>
                    </excludes>
                    <rules>
                        <rule>
                            <element>BUNDLE</element>
                            <limits>
                                <limit>
                                    <counter>LINE</counter>
                                    <value>COVEREDRATIO</value>
                                    <minimum>${jacoco.check.lineRatio}</minimum>
                                </limit>
                                <limit>
                                    <counter>BRANCH</counter>
                                    <value>COVEREDRATIO</value>
                                    <minimum>${jacoco.check.branchRatio}</minimum>
                                </limit>
                            </limits>
                        </rule>
                        <rule>
                            <element>METHOD</element>
                            <limits>
                                <limit>
                                    <counter>COMPLEXITY</counter>
                                    <value>TOTALCOUNT</value>
                                    <maximum>${jacoco.check.complexityMax}</maximum>
                                </limit>
                            </limits>
                        </rule>
                    </rules>
                </configuration>
                <executions>
                    <execution>
                        <id>pre-unit-test</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                        <configuration>
                            <destFile>${jacoco.destfile}</destFile>
                            <append>true</append>
                            <propertyName>surefireArgLine</propertyName>
                        </configuration>
                    </execution>
                    <execution>
                        <id>post-unit-test</id>
                        <phase>test</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                        <configuration>
                            <dataFile>${jacoco.destfile}</dataFile>
                            <outputDirectory>${sonar.jacoco.reportPath}</outputDirectory>
                            <skip>${skip.surefire.tests}</skip>
                        </configuration>
                    </execution>
                    <execution>
                        <id>pre-integration-test</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>prepare-agent-integration</goal>
                        </goals>
                        <configuration>
                            <destFile>${jacoco.destfile}</destFile>
                            <append>true</append>
                            <propertyName>failsafeArgLine</propertyName>
                        </configuration>
                    </execution>
                    <execution>
                        <id>post-integration-test</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>report-integration</goal>
                        </goals>
                        <configuration>
                            <dataFile>${jacoco.destfile}</dataFile>
                            <outputDirectory>${sonar.jacoco.reportPath}</outputDirectory>
                            <skip>${skip.failsafe.tests}</skip>
                        </configuration>
                    </execution>
                    <!-- Disabled until such time as code quality stops this tripping
                    <execution>
                        <id>default-check</id>
                        <goals>
                            <goal>check</goal>
                        </goals>
                        <configuration>
                            <dataFile>${jacoco.destfile}</dataFile>
                        </configuration>
                    </execution>
                    -->
                </executions>
            </plugin>
            ...

Ve inşa bölümünde

 <build>
     <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
        </plugin>

        <plugin>
            <!-- for unit test execution -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
        </plugin>
        <plugin>
            <!-- For integration test separation -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
        </plugin>
        <plugin>
            <!-- For code coverage -->
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
        </plugin>
        ....

Ve raporlama bölümünde

    <reporting>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-report-plugin</artifactId>
            <version>${maven.surefire.report.plugin}</version>
            <configuration>
                <showSuccess>false</showSuccess>
                <alwaysGenerateFailsafeReport>true</alwaysGenerateFailsafeReport>
                <alwaysGenerateSurefireReport>true</alwaysGenerateSurefireReport>
                <aggregate>true</aggregate>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>${jacoco.plugin.version}</version>
            <configuration>
                <excludes>
                    <exclude>**/*.mar</exclude>
                    <exclude>${jacoco.excludePattern}</exclude>
                </excludes>
            </configuration>
        </plugin>
     </plugins>
  </reporting>

1
Bölümlerin <append>true</append>altında yapılandırmaya sahip olduğunuzu görüyorum prepare-agent...
Stewart

Vurgu. Yorumumu başka bir cevaba oku. Diğer belgelerde bulunmayan, benim için eksik olan hayati içerikti.
Stewart

bunun için bir github bağlantınız var mı? Tam olarak benzer yapılandırmalar yapmak istiyorum
Rohit Kasat

@Rhit - hayır, en azından halka açık bir depoda değil.
sweetfa

Bu, Sonar Qube Sürüm 6.5 (yapı 27846) ile çok iyi çalışır ...: D Kod Kapsamı doğru şekilde görüntülenecektir.
udoline

4

JaCoCo'nun ikili rapor formatının (* .exec) kullanımdan kaldırıldığı ve tercih edilen formatın XML (SonarJava 5.12 ve üstü) olduğu yeni Sonar sürümleri için başka bir çözüm buldum. Çözüm çok basittir ve bu konudaki üst dizindeki * .exec raporları ile önceki çözüme benzer: https://stackoverflow.com/a/15535970/4448263 .

Proje yapımızın şöyle olduğunu varsayarsak:

moduleC - aggregate project's pom
  |- moduleA - some classes without tests
  |- moduleB - some classes depending from moduleA and tests for classes in both modules: moduleA and moduleB

Aggregate projesinin pom'unda aşağıdaki maven build eklenti yapılandırmasına ihtiyacınız var:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.5</version>
    <executions>
        <execution>
            <id>prepare-and-report</id>
            <goals>
                <goal>prepare-agent</goal>
                <goal>report</goal>
            </goals>
        </execution>
        <execution>
            <id>report-aggregate</id>
            <phase>verify</phase>
            <goals>
                <goal>report-aggregate</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.basedir}/../target/site/jacoco-aggregate</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

Ardından maven ile proje oluşturun:

mvn clean verify

Ve Sonar için, GUI yönetiminde özelliği ayarlamalısınız:

sonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml,../target/site/jacoco-aggregate/jacoco.xml

veya komut satırı kullanarak:

mvn sonar:sonar -Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml,../target/site/jacoco-aggregate/jacoco.xml

Açıklama

Bu varsayılan dizinleri her modül için ikili raporlar oluşturur: target/jacoco.exec. Ardından varsayılan dizinleri her modül için XML raporlarını oluşturur: target/site/jacoco/jacoco.xml. Daha sonra, her modül ${project.basedir}/../target/site/jacoco-aggregate/için ana dizine göre özel dizindeki her modül için bir toplu rapor oluşturur . Modül A ve modül B için bu ortak yol olacaktırmoduleC/target/site/jacoco-aggregate/ .

Modül B, modül A'ya bağlı olduğundan, modül B en son oluşturulacak ve raporu, hem A hem de B modülleri için Sonar'da bir toplu kapsama raporu olarak kullanılacaktır.

Toplu rapora ek olarak, JaCoCo toplu raporları yalnızca bağımlılıklar için kapsama verilerini içerdiğinden normal bir modül raporuna ihtiyacımız var.

Bu iki rapor türü birlikte, Sonar için tam kapsama verileri sağlar.

Küçük bir kısıtlama var: projenin ana dizinine bir rapor yazabilmelisiniz (izne sahip olmanız gerekir). Veya özelliği jacoco.skip=true, kök projenin pom.xml'sinde (moduleC) ve jacoco.skip=falsesınıflar ve testlerle (modülA ve modülB) modüllerde ayarlayabilirsiniz.


3

Sonarlar sonar.jacoco.reportPatholarak sonar.jacoco.itReportPathve sonar.jacoco.reportPathshepsi kullanımdan kaldırılmışsa , kullanmalısınızsonar.coverage.jacoco.xmlReportPaths şimdi . Sonar ve Jacoco ile çok modüllü bir maven projesi yapılandırmak istiyorsanız, bunun da bir etkisi vardır.

@Lonzak'ın da belirttiği gibi , Sonar 0.7.7'den bu yana, Sonarları rapor artırma hedefini kullanabilirsiniz. Sadece ebeveyn pomunuza aşağıdaki bağımlılığı koyun:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.5</version>
    <executions>
        <execution>
            <id>report</id>
            <goals>
                <goal>report-aggregate</goal>
            </goals>
            <phase>verify</phase>
        </execution>
    </executions>
</plugin>

Jacoco-maven-eklentisinin mevcut sürümleri xml-raporları ile uyumlu olduğundan, bu, kendi hedef klasöründeki her modül için bir site / jacoco-toplama klasörü oluşturacaktır.jacoco.xml dosya .

Sonar'ın tüm modülleri birleştirmesine izin vermek için aşağıdaki komutu kullanın:

mvn -Dsonar.coverage.jacoco.xmlReportPaths=full-path-to-module1/target/site/jacoco-aggregate/jacoco.xml,module2...,module3... clean verify sonar:sonar

Cevabımı kısa ve kesin tutmak için, maven-surefire-pluginve maven-failsafe-pluginbağımlılıklarından bahsetmedim . Bunları başka bir yapılandırma olmadan ekleyebilirsiniz:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.2</version>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.22.2</version>
    <executions>
        <execution>
        <id>integration-test</id>
            <goals>
                <goal>integration-test</goal>
            </goals>
        </execution>
    </executions>
</plugin>

2
    <sonar.language>java</sonar.language>
    <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
    <sonar.jacoco.reportPath>${user.dir}/target/jacoco.exec</sonar.jacoco.reportPath>
    <sonar.jacoco.itReportPath>${user.dir}/target/jacoco-it.exec</sonar.jacoco.itReportPath>
    <sonar.exclusions>
        file:**/target/generated-sources/**,
        file:**/target/generated-test-sources/**,
        file:**/target/test-classes/**,
        file:**/model/*.java,
        file:**/*Config.java,
        file:**/*App.java
    </sonar.exclusions>

            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.7.9</version>
                <executions>
                    <execution>
                        <id>default-prepare-agent</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                        <configuration>
                            <destFile>${sonar.jacoco.reportPath}</destFile>
                            <append>true</append>
                            <propertyName>surefire.argLine</propertyName>
                        </configuration>
                    </execution>
                    <execution>
                        <id>default-prepare-agent-integration</id>
                        <goals>
                            <goal>prepare-agent-integration</goal>
                        </goals>
                        <configuration>
                            <destFile>${sonar.jacoco.itReportPath}</destFile>
                            <append>true</append>
                            <propertyName>failsafe.argLine</propertyName>
                        </configuration>
                    </execution>
                    <execution>
                        <id>default-report</id>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>default-report-integration</id>
                        <goals>
                            <goal>report-integration</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>             

1

Birleştirme adı verilen bir karınca görevi çağırabilirsinizTüm kapsama dosyalarını (* .exec) aynı dosyaya koymak için maven'de .

Birim testleri çalıştırıyorsanız, aşama hazır paketini kullanın, entegrasyon testini çalıştırıyorsanız, entegrasyon sonrası testi kullanın .

Bu site , maven projesinde jacoco karınca görevini nasıl çağırdığına dair bir örnek içeriyor

Bu birleştirilmiş dosyayı sonar üzerinde kullanabilirsiniz.


1

birim testi VE entegrasyon testine sahip olmak için maven-surefire-eklentisini ve maven-failsafe-eklentisini kısıtlı dahil etme / hariç tutma ile kullanabilirsiniz. Sonar / jacoco ile iletişim kurarken CDI ile çalıyordum, bu yüzden bu projeye girdim:

https://github.com/FibreFoX/cdi-sessionscoped-login/

Belki sana biraz yardımcı olur. pom.xml dosyamda, belirtilen test eklentilerinin yapılandırma bölümünde argLine-seçeneğini ayarlayarak örtük olarak "-javaagent" kullanıyorum. MAVEN projelerinde ANT kullanımı açıkça denemeyeceğim bir şey, benim için iki dünyayı çok karıştırmak.

Sadece tek modüllü bir maven projem var, ama belki de kendi projenizi işe göre ayarlamanıza yardımcı olabilir.

not: belki tüm maven eklentileri up2date olmayabilir, belki sonraki sürümlerde bazı sorunlar giderilmiştir


Bunun için teşekkürler; Bir göz atacağım ve nasıl çalıştığını size bildireceğim. Yine de bu hafta olmayabilir :)
Stewart

0

Bu örnek benim için çok iyi çalışıyor:

<plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>0.8.2</version>
            <executions>
                <execution>
                    <id>pre-unit-test</id>
                    <goals>
                        <goal>prepare-agent</goal>
                    </goals>
                    <configuration>
                        <destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>
                        <propertyName>surefireArgLine</propertyName>
                    </configuration>
                </execution>
                <execution>
                    <id>pre-integration-test</id>
                    <goals>
                        <goal>prepare-agent-integration</goal>
                    </goals>
                    <configuration>
                        <destFile>${project.build.directory}/coverage-reports/jacoco-it.exec</destFile>
                        <!--<excludes>
                            <exclude>com.asimio.demo.rest</exclude>
                            <exclude>com.asimio.demo.service</exclude>
                        </excludes>-->
                        <propertyName>testArgLine</propertyName>
                    </configuration>
                </execution>
                <execution>
                    <id>post-integration-test</id>
                    <phase>post-integration-test</phase>
                    <goals>
                        <goal>report</goal>
                    </goals>
                    <configuration>
                        <dataFile>${project.build.directory}/coverage-reports/jacoco-it.exec</dataFile>
                        <outputDirectory>${project.reporting.outputDirectory}/jacoco-it</outputDirectory>
                    </configuration>
                </execution>
                <execution>
                    <id>post-unit-test</id>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>report</goal>
                    </goals>
                    <configuration>
                        <dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile>
                        <outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
                    </configuration>
                </execution>
                <execution>
                    <id>merge-results</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>merge</goal>
                    </goals>
                    <configuration>
                        <fileSets>
                            <fileSet>
                                <directory>${project.build.directory}/coverage-reports</directory>
                                <includes>
                                    <include>*.exec</include>
                                </includes>
                            </fileSet>
                        </fileSets>
                        <destFile>${project.build.directory}/coverage-reports/aggregate.exec</destFile>
                    </configuration>
                </execution>
                <execution>
                    <id>post-merge-report</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>report</goal>
                    </goals>
                    <configuration>
                        <dataFile>${project.build.directory}/coverage-reports/aggregate.exec</dataFile>
                        <outputDirectory>${project.reporting.outputDirectory}/jacoco-aggregate</outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.18.1</version>
            <configuration>
                <argLine>${surefireArgLine}</argLine>
                <!--<skipTests>${skip.unit.tests}</skipTests>-->
                <includes>
                    <include>**/*Test.java</include>
                    <!--<include>**/*MT.java</include>
                    <include>**/*Test.java</include>-->
                </includes>
            <!--    <skipTests>${skipUTMTs}</skipTests>-->
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>2.12.4</version>
            <configuration>
                <!--<skipTests>${skipTests}</skipTests>
                <skipITs>${skipITs}</skipITs>-->
                <argLine>${testArgLine}</argLine>
                <includes>
                    <include>**/*IT.java</include>
                </includes>
                <!--<excludes>
                    <exclude>**/*UT*.java</exclude>
                </excludes>-->
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>integration-test</goal>
                        <goal>verify</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

Lütfen cevabınıza bir açıklama yapın
mishsx

@mishsx Açıklama için güzel bir makale: natritmeyer.com/howto/…
SerhatTopkaya
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.