Schließlich schaffte ich es, um es zu arbeiten und ich möchte mit Ihnen die Lösung teilen:
Instrumentierung für Ihre buildType aktivieren und konfigurieren Sonarqube entsprechend z.B.
...
apply plugin: 'jacoco'
...
android {
...
productFlavors {
acceptance {
applicationId packageName + ".acceptance"
buildTypes {
debug {
testCoverageEnabled true
}
}
}
}
}
sonarRunner {
sonarProperties {
property "sonar.host.url", "..."
property "sonar.jdbc.url", sonarDatabaseUrl
property "sonar.jdbc.driverClassName", sonarDatabaseDriverClassName
property "sonar.jdbc.username", sonarDatabaseUsername
property "sonar.jdbc.password", sonarDatabasePassword
property "sonar.sourceEncoding", "UTF-8"
property "sonar.sources", "src/main"
property "sonar.tests", "src/test"
property "sonar.inclusions", "**/*.java,**/*.xml"
property "sonar.import_unknown_files", "true"
property "sonar.java.binaries", "build/intermediates/classes/acceptance/debug"
property "sonar.junit.reportsPath", "build/test-results/acceptanceDebug"
property "sonar.android.lint.report", "build/outputs/lint-results.xml"
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.jacoco.reportPath", "build/jacoco/testAcceptanceDebugUnitTest.exec"
// see steps below on how to get that file:
property "sonar.jacoco.itReportPath", "build/jacoco/jacoco-it.exec"
property "sonar.projectKey", projectKey
property "sonar.projectName", projectName
property "sonar.projectVersion", appVersionName
}
}
fügen Sie folgendes zu Ihrem AndroidManifest.xml
<receiver
android:name=".util.CoverageDataDumper"
tools:ignore="ExportedReceiver">
<intent-filter>
<action android:name="org.example.DUMP_COVERAGE_DATA"/>
</intent-filter>
</receiver>
CoverageDataDumper so aussehen sollte:
public class CoverageDataDumper extends BroadcastReceiver {
private static final Logger LOG = LoggerFactory.getLogger(CoverageDataDumper.class);
@Override
public void onReceive(Context context, Intent intent) {
try {
Class
.forName("com.vladium.emma.rt.RT")
.getMethod("dumpCoverageData", File.class, boolean.class, boolean.class)
.invoke(null,
new File(App.getContext().getExternalFilesDir(null) + "/coverage.ec"),
true, // merge
false // stopDataCollection
);
}
catch (Exception e) {
LOG.error("Error when writing coverage data", e);
}
}
}
Dann führen Sie Ihre Appium Testfälle mit der Annahme Geschmack app (mit instrumentierten Klassen). Bevor Sie anrufen „App Reset“ oder „Anwendung schließen“ stellen Sie sicher, die folgenden Methoden aufrufen (nur ein Entwurf, aber ich denke, Sie bekommen die Idee):
// intent is "org.example.DUMP_COVERAGE_DATA"
public void endTestCoverage(String intent) {
if (driver instanceof AndroidDriver) {
((AndroidDriver) driver).endTestCoverage(intent, "");
}
}
public void pullCoverageData(String outputPath) {
String coverageFilePath = (String) appiumDriver.getCapabilities().getCapability("coverageFilePath");
if (coverageFilePath != null) {
byte[] log = appiumDriver.pullFile(coverageFilePath);
MobileAppLog.writeLog(new File(outputPath), log);
}
else {
throw new AppiumLibraryNonFatalException(
"Tried to pull the coverage data, but the coverageFilePath wasn't specified.");
}
}
OutputPath könnte zum Beispiel:/sdcard/Android /data/org.example.acceptance/files/coverage.ec
Nun werden die Jacoco-Daten auf das Smartphone geschrieben. Als nächstes müssen wir diese Datei herunterladen. Sie können
verwenden
appiumDriver.pullFile(logFilePath);
Nun müssen Sie die Datei „jacoco-it.exec“ kopieren (die immer angehängt werden soll, wenn Sie die Datei ziehen) in build/jacoco/jacoco-it.exec sehen gradle .build oben und laufen
gradlew sonarRunner
In Sonarqube die Integration Test Coverage Widget hinzufügen und Sie sollten jetzt einige Werte ...
Leider Code-Coverage wird nicht funktionieren, wenn Sie mit retrolambda (wie wir sehen, machen).Retrolambda generiert anonyme Klassen, die nicht Teil der Quelldateien sind. Daher kann SonarQube sie nicht korrekt abgleichen und weist eine wesentlich geringere Codeabdeckung auf, als sie tatsächlich ist. Wenn jemand eine Lösung dafür findet, würde ich mich sehr freuen :-)
bin ich etwas fehlt, oder verwenden Sie beide emma und jacoco hier? Ich habe ein ähnliches Problem, daher ist diese Antwort sehr interessant - aber ich kann es nicht verstehen. – Vish