简体   繁体   English

Travis CI和CodeCov Android

[英]Travis CI & CodeCov Android

I am trying to use Travis CI and get it to run through the tests to see the results on codecov. 我正在尝试使用Travis CI并让它运行测试以查看codecov上的结果。

.travis.yml: .travis.yml:

language: android
sudo: required
jdk: oraclejdk8

before_cache:
 - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
 - rm -fr $HOME/.gradle/caches/*/plugin-resolution/

cache:
 directories:
 - $HOME/.gradle/caches/
 - $HOME/.gradle/wrapper/

env:
 global:
 - ANDROID_API=25
 - EMULATOR_API=21
 - ANDROID_BUILD_TOOLS=25.0.0
 - ADB_INSTALL_TIMEOUT=5 # minutes

android:
 components:
 - tools
 - platform-tools
 - build-tools-$ANDROID_BUILD_TOOLS
 - android-$ANDROID_API
 - android-$EMULATOR_API_LEVEL
 - extra-google-m2repository
 - extra-android-m2repository # for design library
 - addon-google_apis-google-19 # google play services
 - sys-img-armeabi-v7a-addon-google_apis-google-$ANDROID_API_LEVEL
 - sys-img-armeabi-v7a-addon-google_apis-google-$EMULATOR_API_LEVEL

licenses:
 - android-sdk-preview-license-.+
 - android-sdk-license-.+
 - google-gdk-license-.+

before_install:
- mkdir "$ANDROID_HOME/licenses" || true
- echo -e "\n8933bad161af4178b1185d1a37fbf41ea5269c55" > "$ANDROID_HOME/licenses/android-sdk-license"
- echo -e "\n84831b9409646a918e30573bab4c9c91346d8abd" > "$ANDROID_HOME/licenses/android-sdk-preview-license"
- chmod +x gradlew
#- ./gradlew dependencies || true # DON'T ADD unless you are getting "Install missing components using SDK manager"
#Source: https://medium.com/@oldergod/constraint-layout-and-circleci-travis-d50342696d2



script:
  - ./gradlew build jacocoTestReport assembleAndroidTest
  - echo no | android create avd --force -n test -t android-21 --abi armeabi-v7a
  - emulator -avd test -no-skin -no-audio -no-window &
  - android-wait-for-emulator
  - adb shell setprop dalvik.vm.dexopt-flags v=n,o=v
  - ./gradlew connectedCheck

after_success:
- bash <(curl -s https://codecov.io/bash)

build.gradle: 的build.gradle:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.2'
        classpath 'com.dicedmelon.gradle:jacoco-android:0.1.1'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

build.gradle(app): 的build.gradle(APP):

apply plugin: 'com.android.application'
apply plugin: 'jacoco-android'

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.3"
    defaultConfig {
        applicationId "<ID>"
        minSdkVersion 15
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        vectorDrawables.useSupportLibrary = true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            testCoverageEnabled true
        }
    }
    testOptions {
        unitTests.returnDefaultValues = true
    }
    lintOptions {
        abortOnError false
    }
    productFlavors {
        free {}
        paid {}
    }


    packagingOptions {
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
    }
}

dependencies {
    compile files('libs/httpclient-4.5.1.jar')
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:24.2.1'
    compile 'com.android.support:support-v4:24.2.1'
    compile 'com.android.support:design:24.2.1'
    compile 'com.android.support:support-vector-drawable:24.2.1'
    testCompile 'junit:junit:4.12'
    compile files('libs/themoviedbapi-4.3.jar')
    compile files('libs/api-common-2.0.jar')
    compile files('libs/commons-codec-1.9.jar')
    compile files('libs/commons-lang3-3.4.jar')
    compile files('libs/httpcore-4.4.3.jar')
    compile files('libs/jackson-annotations-2.7.1.jar')
    compile files('libs/jackson-core-2.7.1.jar')
    compile files('libs/jackson-databind-2.7.1.jar')
    compile files('libs/slf4j-api-1.7.16.jar')
}

The test we are trying to run is an instrumented test. 我们试图运行的测试是一个仪器化测试。 The output on the Travis log looks like this: Travis日志的输出如下所示:

com.example.fabian.tinf15b4_lsmf.SeeMovieDetailsTest > seeMovieDetails[test(AVD) - 5.0.2] [31mFAILED [0m
    java.lang.NoSuchMethodError: No virtual method releaseConnection()V in class Lorg/apache/http/client/methods/HttpRequestBase; or its super classes (declaration of 'org.apache.http.client.methods.HttpRequestBase' appears in /system/framework/ext.jar)

    at org.yamj.api.common.http.DigestedResponseReader.processRequest(DigestedResponseReader.java:119)

Tests on test(AVD) - 5.0.2 failed: Instrumentation run failed due to 'java.lang.NoSuchMethodError'
:app:connectedFreeDebugAndroidTest FAILED

Also there was the autogenerated Test which simply adds two numbers and checks the result but Travis did not even go through it. 还有自动生成的测试,只需添加两个数字并检查结果,但特拉维斯甚至没有通过它。

Can anyone please help fixing this mess? 有人可以帮忙解决这个烂摊子吗?

Read this related question about HTTPClient - NoSuchMethodError for .releaseConnection . 阅读有关HTTPClient的 相关问题 - .releaseConnection的 NoSuchMethodError for .releaseConnection

The method HttpRequestBase#releaseConnection() definetely was added at 4.2 version . 方法HttpRequestBase#releaseConnection() definetely在4.2版本中添加。

Probably you have jar hell. 可能你有罐头地狱。 If the compiler has no compilation errors another version of the class can be loaded at runtime. 如果编译器没有编译错误,则可以在运行时加载该类的另一个版本。 The real cause depends on your build tool. 真正的原因取决于您的构建工具。 If you are using maven/gradle, there can be some transitive dependency. 如果您使用maven / gradle,则可能存在一些传递依赖。

So actually HttpRequestBase#releaseConnection() method just proxy invocation to AbstractExecutionAwareRequest#reset() . 所以实际上HttpRequestBase#releaseConnection()方法只是代理调用AbstractExecutionAwareRequest#reset() And AbstractExecutionAwareRequest#reset() just cancel method execution. AbstractExecutionAwareRequest#reset()只是取消方法执行。 Probably it is not what do you need. 可能不是你需要什么。

The correct way to execute and release httpClient resources is to close httpResponse, which means you can release Thread in httpClient's internal threadPool. 执行和释放httpClient资源的正确方法是关闭httpResponse,这意味着您可以在httpClient的内部threadPool中释放Thread。

private static String makeRequest(HttpUriRequest httpRequest) throws IOException {
        CloseableHttpResponse httpResponse = httpClient.execute(httpRequest);
        try {
            HttpEntity httpEntity = httpResponse.getEntity();
            StringWriter writer = new StringWriter();
            IOUtils.copy(httpEntity.getContent(), writer, "UTF-8");
            return writer.toString();
        } finally {
            httpResponse.close();
        }
    }

In the quickstart you'll see that .releaseConnection() is no longer used (it is deprecated), instead the response object is closed to ensure connections are closed. 快速入门中,您将看到不再使用.releaseConnection() (不推荐使用),而是关闭响应对象以确保关闭连接。

Try a different httpclient or httpcore version (from here ): 尝试不同的httpclienthttpcore版本(从这里 ):

It looks like you have a jar file with an old/newer version of BasicHttpContext. 看起来你有一个带有旧版/新版BasicHttpContext的jar文件。 If there were a direct conflict, you'd receive a ClassNotFoundException. 如果存在直接冲突,则会收到ClassNotFoundException。 ClassLoaders are typically jerks about this kind of thing. ClassLoader通常是关于这种事情的混蛋。 In this case, the class exists, however, does not have the method that another library (I believe it's httpclient that's invoking the Context) was compiled against. 在这种情况下,该类存在,但是,没有另一个库(我相信它是调用Context的httpclient)被编译的方法。

For API 23+ you can also add the removed apache library in your /app/build.gradle like this : 对于API 23+,您还可以在/app/build.gradle中添加已删除的apache库如下所示

android {
compileSdkVersion 24
buildToolsVersion "24.0.3"
    useLibrary 'org.apache.http.legacy'
    ...
}

Android 6.0 release removes support for the Apache HTTP client. Android 6.0版本删除了对Apache HTTP客户端的支持。 If your app is using this client and targets Android 2.3 (API level 9) or higher, use the HttpURLConnection class instead. 如果您的应用使用此客户端并定位到Android 2.3(API级别9)或更高版本,请改用HttpURLConnection类。 This API is more efficient... 这个API效率更高......

this article and this sample seem useful to configure Codecov for Android and Travis-ci: 本文此示例似乎对配置Codecov for Android和Travis-ci很有用:

Generating instrumentation tests code coverage reports requires a minor change to the build script. 生成检测测试代码覆盖率报告需要对构建脚本进行微小更改。

android {
  buildTypes {
    debug {
      testCoverageEnabled true
    }
  }
}

To avoid ignoring our tests by the coverage report, we need to configure the following settings: 为避免覆盖报告忽略我们的测试,我们需要配置以下设置:

android {
  testOptions {
    unitTests.all {
      jacoco {
        includeNoLocationClasses = true
      }
    }
  }
}

Next, we need to configure report output: 接下来,我们需要配置报告输出:

 jacocoAndroidUnitTestReport {
  csv.enabled false
  html.enabled true
  xml.enabled true
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM