2015-06-22 24 views
6

chúng tôi đang xây dựng một ứng dụng Android được kiểm tra bằng cách sử dụng Appium. Bây giờ tôi muốn xem thử nghiệm về các thử nghiệm Appium của chúng tôi. Tôi nghĩ rằng điều này là có thể, bởi vì Jacoco hỗ trợ thiết bị ngoại tuyến (http://www.eclemma.org/jacoco/trunk/doc/offline.html).Android Gradle Jacoco: thiết bị đo đạc trực tuyến cho các bài kiểm tra tích hợp

Và ngay cả những tài liệu của các plugin jacoco gradle nói:

Trong khi tất cả các nhiệm vụ của loại hình thử nghiệm được tự động tăng cường cung cấp thông tin bảo hiểm khi các plugin java đã được áp dụng, bất kỳ công việc mà thực hiện JavaForkOptions thể được tăng cường bởi plugin JaCoCo. Đó là, bất kỳ nhiệm vụ nào có thể sử dụng các quy trình Java có thể được sử dụng để tạo ra thông tin vùng phủ sóng.

thấy https://docs.gradle.org/current/userguide/jacoco_plugin.html

Nhưng làm thế nào để tôi phải viết build.gradle nên hương vị chấp nhận debug của chúng tôi được trang bị và tập tin exec được ghi vào điện thoại thông minh khi các bài kiểm tra Appium được thực hiện hoặc thậm chí trường hợp kiểm tra thủ công được thực hiện? Bởi vì sau đó tôi có thể giải nén tập tin exec và gửi nó để SonarQube để phân tích thêm.

Cảm ơn Bến

Trả lời

1

Cuối cùng tôi quản lý nó để làm cho nó làm việc và tôi muốn chia sẻ giải pháp với bạn:

phép đo đạc cho buildType của bạn và cấu hình phù hợp SonarQube ví dụ

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

thêm dòng sau vào AndroidManifest.xml của bạn

<receiver 
android:name=".util.CoverageDataDumper" 
tools:ignore="ExportedReceiver"> 
<intent-filter> 
    <action android:name="org.example.DUMP_COVERAGE_DATA"/> 
</intent-filter> 
</receiver> 

CoverageDataDumper nên xem xét như thế:

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); 
     } 
    } 
} 

Sau đó chạy trường hợp thử nghiệm Appium của bạn với các ứng dụng hương vị chấp nhận (với các lớp instrumented). Trước khi bạn gọi "Reset App" hoặc "Close Application" đảm bảo để gọi các phương thức sau (chỉ là một dự thảo, nhưng tôi nghĩ rằng bạn sẽ có được ý tưởng):

// 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 có thể là ví dụ:/sdcard/Android /data/org.example.acceptance/files/coverage.ec

Bây giờ dữ liệu Jacoco được ghi vào điện thoại thông minh. Tiếp theo, chúng tôi cần tải xuống tệp đó. Bạn có thể sử dụng

appiumDriver.pullFile(logFilePath); 

Bây giờ bạn cần phải sao chép các tập tin "jacoco-it.exec" (mà nên luôn luôn nối khi bạn kéo file) vào xây dựng/jacoco/jacoco-it.exec thấy gradle .build trên và chạy

gradlew sonarRunner 

Trong SonarQube thêm tích hợp thử nghiệm bảo hiểm widget và bạn sẽ thấy tại một số giá trị ...

Đáng tiếc là mã số bảo hiểm sẽ không hoạt động nếu bạn đang sử dụng retrolambda (như chúng ta làm).Retrolambda sẽ tạo ra các lớp vô danh mà không phải là một phần của tập tin nguồn - vì vậy SonarQube không thể phù hợp với chúng một cách chính xác và hiển thị một phạm vi mã thấp hơn nhiều so với nó thực sự là. Nếu ai đó tìm thấy một giải pháp cho điều đó, tôi sẽ rất hạnh phúc :-)

+0

Tôi có thiếu thứ gì đó hoặc bạn đang sử dụng cả emma và jacoco ở đây? Tôi có một vấn đề tương tự nên câu trả lời này rất thú vị - nhưng tôi không thể hiểu được. – Vish

0

Tôi giải quyết vấn đề này bằng cách thêm bộ thu phát sóng vào ứng dụng bạn kiểm tra! (Bạn có thể thêm người nhận chỉ vào thư mục debug gây không cần nó cho là tồn tại trong nguồn chính)

public class CoverageReceiver extends BroadcastReceiver { 
    private static final String EXEC_FILE_PATH = "/mnt/sdcard/coverage.exec"; 
    private static final String TAG = "CoverageJacoco"; 
    private static final String BROADCAST_RECEIVED_MESSAGE = "EndJacocoBroadcast broadcast received!"; 
    private static final String EMMA_CLASS = "com.vladium.emma.rt.RT"; 
    private static final String EMMA_DUMP_METHOD = "dumpCoverageData"; 
@Override 
public void onReceive(Context context, Intent intent) { 
    try { 
     Log.d(TAG, BROADCAST_RECEIVED_MESSAGE); 
     Class.forName(EMMA_CLASS) 
       .getMethod(EMMA_DUMP_METHOD, File.class, boolean.class, 
         boolean.class) 
       .invoke(null, new File(EXEC_FILE_PATH), true, 
         false); 
    } catch (Exception e) { 
     Log.d(TAG, e.getMessage()); 
    } 
} 
} 

Trong add manefist (bạn có thể thêm thư mục debug này vì vậy nó sẽ không tồn tại trong nguồn chính)

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" > 


    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 


    <application> 

     <receiver android:name=".CoverageReceiver"> 
      <intent-filter> 
       <action android:name="com.example.action" /> 
      </intent-filter> 
     </receiver> 
    </application> 

trong build.gradle của ứng dụng tôi đã thêm

apply plugin: 'jacoco' 

jacoco { 
    toolVersion = "0.7.4+" 
} 

model { 
    android { 
     compileSdkVersion 23 
     buildToolsVersion "23.0.2" 
    defaultConfig { 
     applicationId "com.example.app" 
     minSdkVersion.apiLevel 23 
     targetSdkVersion.apiLevel 23 
     versionCode 12 
     versionName "1.11" 

    } 
    buildTypes { 

     debug { 
      testCoverageEnabled true 

     } 
    } 

bạn xây dựng của bạn ứng dụng như gỡ lỗi, hơn là cài đặt và chạy nó.

gửi phát sóng thông qua ADB "adb shell pm phát sóng -a com.example.action" để tạo coverage.exec bảo hiểm kéo từ thiết bị - kéo adb /mnt/sdcard/coverage.exec

sau khi bạn chạy này bạn cần tạo độ che phủ từ tập tin

** 
* This task is used to create a code coverage report via the Jcoco tool. 
*/ 
task jacocoTestReport(type: JacocoReport) { 
    def coverageSourceDirs = [ 
      'src/main/java',    
    ] 
    group = "Reporting" 
    description = "Generates Jacoco coverage reports" 
    reports { 
     csv.enabled false 
     xml{ 
      enabled = true 
      destination "${buildDir}/jacoco/jacoco.xml" 
     } 
     html{ 
      enabled true 
      destination "${buildDir}/jacocoHtml" 
     } 
    } 
    classDirectories = fileTree(
      dir: 'build/intermediates/classes', 
      excludes: ['**/R.class', 
         '**/R$*.class', 
         '**/BuildConfig.*', 
         '**/Manifest*.*', 
         '**/*Activity*.*', 
         '**/*Fragment*.*' 
      ] 
    ) 
    sourceDirectories = files(coverageSourceDirs) 
    executionData = files('build/coverage.exec') 
} 

nhiệm vụ này là một cách để tạo ra các file bảo hiểm trong coverageSourceDirs thêm tất cả các vị trí của mã nguồn Application của bạn, vì vậy nó sẽ biết được mã để mất và tạo vùng phủ sóng dựa trên chúng thực thiData là vị trí nơi bạn đặt vùng phủ sóng. bạn đã kéo từ thiết bị

Chạy tác vụ các tệp sẽ được tạo cho html và xml bạn cũng có thể thêm csv (thông báo nó sẽ được tạo trong thư mục xây dựng của ứng dụng)!

Cần biết, bạn phải chạy tác vụ đối với cùng mã bạn đã tạo phiên bản gỡ lỗi ứng dụng của mình

Các vấn đề liên quan