Android Firebase测试实验室为/jacoco.exec抛出文件NotFound

Android Firebase测试实验室为/jacoco.exec抛出文件NotFound,android,firebase,jacoco,firebase-test-lab,Android,Firebase,Jacoco,Firebase Test Lab,我正在尝试使用Android Espresso测试设置代码覆盖率,并在Firebase测试实验室上运行测试 测试是在Firebase上执行的,所以我认为一切都应该“正常”。但是,Firebase测试实验室生成的coverage.ec文件不包含任何覆盖率信息 不管我怎么做,我都看不到如何让它真正生成覆盖信息 在查看Firebase测试实验室日志时,我看到以下堆栈跟踪: 10-02 23:55:37.746: W/System.err(7917): java.io.FileNotFoundExcep

我正在尝试使用Android Espresso测试设置代码覆盖率,并在Firebase测试实验室上运行测试

测试是在Firebase上执行的,所以我认为一切都应该“正常”。但是,Firebase测试实验室生成的coverage.ec文件不包含任何覆盖率信息

不管我怎么做,我都看不到如何让它真正生成覆盖信息

在查看Firebase测试实验室日志时,我看到以下堆栈跟踪:

10-02 23:55:37.746: W/System.err(7917): java.io.FileNotFoundException: /jacoco.exec (Read-only file system)
10-02 23:55:37.746: W/System.err(7917):     at java.io.FileOutputStream.open0(Native Method)
10-02 23:55:37.746: W/System.err(7917):     at java.io.FileOutputStream.open(FileOutputStream.java:287)
10-02 23:55:37.746: W/System.err(7917):     at java.io.FileOutputStream.<init>(FileOutputStream.java:223)
10-02 23:55:37.746: W/System.err(7917):     at org.jacoco.agent.rt.internal_8ff85ea.output.FileOutput.openFile(FileOutput.java:67)
10-02 23:55:37.746: W/System.err(7917):     at org.jacoco.agent.rt.internal_8ff85ea.output.FileOutput.startup(FileOutput.java:49)
10-02 23:55:37.746: W/System.err(7917):     at org.jacoco.agent.rt.internal_8ff85ea.Agent.startup(Agent.java:122)
10-02 23:55:37.746: W/System.err(7917):     at org.jacoco.agent.rt.internal_8ff85ea.Agent.getInstance(Agent.java:50)
10-02 23:55:37.746: W/System.err(7917):     at org.jacoco.agent.rt.internal_8ff85ea.Offline.<clinit>(Offline.java:31)
10-02 23:55:37.746: W/System.err(7917):     at org.jacoco.agent.rt.internal_8ff85ea.Offline.getProbes(Offline.java:51)
10-02 23:55:37.746: W/System.err(7917):     at com.example.idea.MainActivity.$jacocoInit(Unknown Source:12)
10-02 23:55:37.746: W/System.err(7917):     at com.example.idea.MainActivity.<init>(Unknown Source:0)
10-02 23:55:37.746: W/System.err(7917):     at java.lang.Class.newInstance(Native Method)
10-02 23:55:37.746: W/System.err(7917):     at android.app.Instrumentation.newActivity(Instrumentation.java:1174)
10-02 23:55:37.746: W/System.err(7917):     at android.support.test.runner.MonitoringInstrumentation.newActivity(MonitoringInstrumentation.java:754)
10-02 23:55:37.746: W/System.err(7917):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2669)
10-02 23:55:37.746: W/System.err(7917):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
10-02 23:55:37.746: W/System.err(7917):     at android.app.ActivityThread.-wrap11(Unknown Source:0)
10-02 23:55:37.747: W/System.err(7917):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
10-02 23:55:37.747: W/System.err(7917):     at android.os.Handler.dispatchMessage(Handler.java:106)
10-02 23:55:37.747: W/System.err(7917):     at android.os.Looper.loop(Looper.java:164)
10-02 23:55:37.747: W/System.err(7917):     at android.app.ActivityThread.main(ActivityThread.java:6494)
10-02 23:55:37.747: W/System.err(7917):     at java.lang.reflect.Method.invoke(Native Method)
10-02 23:55:37.747: W/System.err(7917):     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
10-02 23:55:37.747: W/System.err(7917):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
在我的应用程序的build.gradle文件中

您还可以在此处看到完整的jacoco配置:

apply plugin: 'jacoco'
jacoco {
    toolVersion = "0.8.4"
}
def coverageSourceDirs = [
        'src/main/java',
        'src/debug/java'
]

tasks.withType(Test) {
    jacoco.includeNoLocationClasses = true
    jacoco.destinationFile = file("$buildDir/jacoco/jacocoTest.exec")
}

task jacocoTestReport(type : JacocoReport, dependsOn : 'testDebugUnitTest') {
    group       = 'Reporting'
    description = 'Generate JaCoCo coverage reports'

    reports {
        xml.enabled  = true
        html.enabled = true
    }

    classDirectories = fileTree(
            dir      : 'build/intermediates/classes/debug',
            excludes : [
                    '**/R.class',
                    '**/R$*.class',
                    '**/*$ViewInjector*.*',
                    '**/*$ViewBinder*.*',
                    '**/BuildConfig.*',
                    '**/Manifest*.*',
                    '**/*RealmProxy.*',
                    '**/*ColumnInfo.*',
                    '**/*RealmModule*.*',
                    '**/AutoValue_*.*',
                    '**/Dagger*.*',
                    '**/*Module_Provide*Factory.*',
                    '**/*_Factory.*',
                    '**/*_MembersInjector.*',
                    '**/*_LifecycleAdapter.*'
            ]
    )

    sourceDirectories = files(coverageSourceDirs)
    executionData     = fileTree(
            dir     : "$buildDir",
            include : [ 'jacoco/testDebugUnitTest.exec', 'outputs/code-coverage/connected/*coverage.ec' ]
    )

    doFirst {
        files('build/intermediates/classes/debug').getFiles().each { file ->
            if (file.name.contains('$$')) {
                file.renameTo(file.path.replace('$$', '$'))
            }
        }
    }
}

task jacocoTestReportLocal(type : JacocoReport, dependsOn : ['testDebugUnitTest', 'createDebugCoverageReport']) {
    group       = 'Reporting'
    description = 'Generate JaCoCo coverage reports'

    reports {
        xml.enabled  = true
        html.enabled = true
    }

    classDirectories = fileTree(
            dir      : 'build/intermediates/classes/debug',
            excludes : [
                    '**/R.class',
                    '**/R$*.class',
                    '**/*$ViewInjector*.*',
                    '**/*$ViewBinder*.*',
                    '**/BuildConfig.*',
                    '**/Manifest*.*',
                    '**/*RealmProxy.*',
                    '**/*ColumnInfo.*',
                    '**/*RealmModule*.*',
                    '**/AutoValue_*.*',
                    '**/Dagger*.*',
                    '**/*Module_Provide*Factory.*',
                    '**/*_Factory.*',
                    '**/*_MembersInjector.*',
                    '**/*_LifecycleAdapter.*',
                    '**/models/**'
            ]
    )

    sourceDirectories = files(coverageSourceDirs)
    executionData     = fileTree(
            dir     : "$buildDir",
            include : [ 'jacoco/testDebugUnitTest.exec', 'outputs/code-coverage/connected/*coverage.ec' ]
    )

    doFirst {
        files('build/intermediates/classes/debug').getFiles().each { file ->
            if (file.name.contains('$$')) {
                file.renameTo(file.path.replace('$$', '$'))
            }
        }
    }
}
以及完整的应用程序build.gradle:

apply plugin: 'com.android.application'
apply from: '../jacoco.gradle'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.idea"
        minSdkVersion 22
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        debug { testCoverageEnabled true }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:support-media-compat:28.0.0'
    implementation 'com.android.support:support-v4:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.google.firebase:firebase-analytics:15.0.0'
//    implementation 'com.google.firebase:firebase-core:15.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    androidTestImplementation 'com.android.support.test:rules:1.0.2'
}

apply plugin: 'com.google.gms.google-services'
以及此处的config.yml:

version: 2
references:

  ## Cache

  cache_key: &cache_key
    key: cache-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
  restore_cache: &restore_cache
    restore_cache:
      <<: *cache_key
  save_cache: &save_cache
    save_cache:
      <<: *cache_key
      paths:
        - ~/.gradle
        - ~/.m2

  ## Workspace

  workspace: &workspace
               ~/workspace
  attach_debug_workspace: &attach_debug_workspace
    attach_workspace:
      at: *workspace
  attach_release_workspace: &attach_release_workspace
    attach_workspace:
      at: *workspace
  persist_debug_workspace: &persist_debug_workspace
    persist_to_workspace:
      root: *workspace
      paths:
        - app/build/outputs/androidTest-results
        - app/build/outputs/apk
        - app/build/outputs/code-coverage
        - app/build/test-results
  persist_release_workspace: &persist_release_workspace
    persist_to_workspace:
      root: *workspace
      paths:
        - app/build
  attach_firebase_workspace: &attach_firebase_workspace
    attach_workspace:
      at: *workspace
  persist_firebase_workspace: &persist_firebase_workspace
    persist_to_workspace:
      root: *workspace
      paths:
        - firebase

  ## Docker image configuration

  android_config: &android_config
    working_directory: *workspace
    docker:
      - image: circleci/android:api-28-alpha
    environment:
      TERM: dumb
      _JAVA_OPTIONS: "-Xmx2048m -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap"
      GRADLE_OPTS: '-Dorg.gradle.jvmargs="-Xmx2048m"'
  gcloud_config: &gcloud_config
    working_directory: *workspace
    docker:
      - image: google/cloud-sdk:206.0.0
    environment:
      TERM: dumb

  # Google Services

  export_gservices_key: &export_gservices_key
    run:
      name: Export Google Services key environment variable
      command: echo 'export GOOGLE_SERVICES_KEY="$GOOGLE_SERVICES_KEY"' >> $BASH_ENV
  decode_gservices_key: &decode_gservices_key
    run:
      name: Decode Google Services key
      command: echo $GOOGLE_SERVICES_KEY | base64 -di > app/google-services.json

  # Google Cloud Service

  export_gcloud_key: &export_gcloud_key
    run:
      name: Export Google Cloud Service key environment variable
      command: echo 'export GCLOUD_SERVICE_KEY="$GCLOUD_SERVICE_KEY"' >> $BASH_ENV
  decode_gcloud_key: &decode_gcloud_key
    run:
      name: Decode Google Cloud credentials
      command: echo $GCLOUD_SERVICE_KEY | base64 -di > ${HOME}/client-secret.json

jobs:

  # Build debug APK for unit tests and an instrumented test APK

  build_debug:
    <<: *android_config
    steps:
      - checkout
      - *restore_cache
      - run:
          name: Download dependencies
          command: ./gradlew androidDependencies
      - *save_cache
      - *export_gservices_key
      - *decode_gservices_key
      - run:
          name: Gradle build (debug)
          command: ./gradlew -PciBuild=true :app:assembleDebug :app:assembleAndroidTest
      - *persist_debug_workspace
      - store_artifacts:
          path: app/build/outputs/apk/
          destination: /apk/

  # Build release APK

  build_release:
    <<: *android_config
    steps:
      - checkout
      - *restore_cache
      - run:
          name: Download dependencies
          command: ./gradlew androidDependencies
      - *save_cache
      - *export_gservices_key
      - *decode_gservices_key
      - run:
          name: Gradle build (release)
          command: ./gradlew -PciBuild=true :app:assembleRelease
      - *persist_release_workspace
      - store_artifacts:
          path: app/build/outputs/apk/
          destination: /apk/
      - store_artifacts:
          path: app/build/outputs/mapping/
          destination: /mapping/

  # Run unit tests

  test_unit:
    <<: *android_config
    steps:
      - checkout
      - *restore_cache
      - run:
          name: Download dependencies
          command: ./gradlew androidDependencies
      - *save_cache
      - *export_gservices_key
      - *decode_gservices_key
      - run:
          name: Run unit tests
          command: ./gradlew -PciBuild=true :app:testDebugUnitTest
      - *persist_debug_workspace
      - store_artifacts:
          path: app/build/reports/
          destination: /reports/
      - store_test_results:
          path: app/build/test-results/
          destination: /test-results/

  # Run instrumented tests

  test_instrumented:
    <<: *gcloud_config
    steps:
      - *attach_debug_workspace
      - *export_gcloud_key
      - *decode_gcloud_key
      - run:
          name: Set Google Cloud target project
          command: gcloud config set project i-de-a
      - run:
          name: Authenticate with Google Cloud
          command: gcloud auth activate-service-account firebase-adminsdk-3t8n8@i-de-a.iam.gserviceaccount.com --key-file ${HOME}/client-secret.json
      - run:
          name: Echo sha1 variable for debugging
          command: echo ${CIRCLE_SHA1}
      - run:
          name: Run instrumented test on Firebase Test Lab
          command: gcloud firebase test android run --type instrumentation --app app/build/outputs/apk/debug/app-debug.apk --test app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk --device model=Nexus6P,version=27,locale=en_US,orientation=portrait --no-use-orchestrator --environment-variables coverage=true,coverageFile="/sdcard/coverage.ec" --directories-to-pull=/sdcard --timeout 20m --results-dir=${CIRCLE_SHA1}
      - run:
          name: Create directory to store test results
          command: mkdir firebase
      - run:
          name: Download instrumented test results from Firebase Test Lab
          command: gsutil -m cp -r -U gs://test-lab-hzda62mwyy730-n7hcz7bxtxrx0/${CIRCLE_SHA1} /root/workspace/firebase/
      - *persist_firebase_workspace
      - store_artifacts:
          path: firebase/
          destination: /firebase/

  # Submit JaCoCo coverage report

  report_coverage:
    <<: *android_config
    steps:
      - checkout
      - *restore_cache
      - run:
          name: Download dependencies
          command: ./gradlew androidDependencies
      - *attach_debug_workspace
      - *attach_firebase_workspace
      - run:
          name: Move Firebase coverage report
          command: mkdir -p app/build/outputs/code-coverage/connected && cp firebase/${CIRCLE_SHA1}/Nexus6P-27-en_US-portrait/artifacts/coverage.ec app/build/outputs/code-coverage/connected/coverage.ec
      - *export_gservices_key
      - *decode_gservices_key
      - run:
          name: Generate JaCoCo report
          command: ./gradlew -PciBuild=true :app:jacocoTestReport
      - run:
          name: Upload coverage report to CodeCov
          command: bash <(curl -s https://codecov.io/bash)
      - store_artifacts:
          path: app/build/reports/
          destination: /reports/

workflows:
  version: 2
  workflow:
    jobs:
      - build_debug
      - build_release
      - test_unit
      - test_instrumented:
          requires:
            - build_debug
      - report_coverage:
          requires:
            - build_release
            - test_unit
            - test_instrumented
版本:2
参考资料:
##缓存
缓存密钥:&缓存密钥
关键字:cache-{{checksum”gradle/wrapper/gradle wrapper.properties“}}-{{{checksum”build.gradle“}}-{{checksum”app/build.gradle“}
还原\u缓存:&还原\u缓存
还原U缓存:
>$BASH_ENV
解码\u gcloud\u键:&解码\u gcloud\u键
运行:
名称:解码谷歌云凭证
命令:echo$GCLOUD_SERVICE_KEY | base64-di>${HOME}/client-secret.json
工作:
#为单元测试和仪表化测试APK构建调试APK
编译调试:
从


该解决方案在jacoco中有很好的文档记录,但对于Android用户,您需要在
/src/androidTest/resources/jacoco agent.properties
中添加文件,内容为
output=none
,这样jacoco就可以启动而不会失败,android gradle插件覆盖率实现将正常编写覆盖率,并在以后正确传输覆盖率。

请编辑问题并将所有相关代码和配置复制到问题本身,而不是链接到外部资源。这将确保即使您的代码发生了更改,问题也始终与其他问题相关。@DougStevenson编辑以包括所有相关配置。
apply plugin: 'com.android.application'
apply from: '../jacoco.gradle'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.idea"
        minSdkVersion 22
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        debug { testCoverageEnabled true }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:support-media-compat:28.0.0'
    implementation 'com.android.support:support-v4:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.google.firebase:firebase-analytics:15.0.0'
//    implementation 'com.google.firebase:firebase-core:15.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    androidTestImplementation 'com.android.support.test:rules:1.0.2'
}

apply plugin: 'com.google.gms.google-services'
version: 2
references:

  ## Cache

  cache_key: &cache_key
    key: cache-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
  restore_cache: &restore_cache
    restore_cache:
      <<: *cache_key
  save_cache: &save_cache
    save_cache:
      <<: *cache_key
      paths:
        - ~/.gradle
        - ~/.m2

  ## Workspace

  workspace: &workspace
               ~/workspace
  attach_debug_workspace: &attach_debug_workspace
    attach_workspace:
      at: *workspace
  attach_release_workspace: &attach_release_workspace
    attach_workspace:
      at: *workspace
  persist_debug_workspace: &persist_debug_workspace
    persist_to_workspace:
      root: *workspace
      paths:
        - app/build/outputs/androidTest-results
        - app/build/outputs/apk
        - app/build/outputs/code-coverage
        - app/build/test-results
  persist_release_workspace: &persist_release_workspace
    persist_to_workspace:
      root: *workspace
      paths:
        - app/build
  attach_firebase_workspace: &attach_firebase_workspace
    attach_workspace:
      at: *workspace
  persist_firebase_workspace: &persist_firebase_workspace
    persist_to_workspace:
      root: *workspace
      paths:
        - firebase

  ## Docker image configuration

  android_config: &android_config
    working_directory: *workspace
    docker:
      - image: circleci/android:api-28-alpha
    environment:
      TERM: dumb
      _JAVA_OPTIONS: "-Xmx2048m -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap"
      GRADLE_OPTS: '-Dorg.gradle.jvmargs="-Xmx2048m"'
  gcloud_config: &gcloud_config
    working_directory: *workspace
    docker:
      - image: google/cloud-sdk:206.0.0
    environment:
      TERM: dumb

  # Google Services

  export_gservices_key: &export_gservices_key
    run:
      name: Export Google Services key environment variable
      command: echo 'export GOOGLE_SERVICES_KEY="$GOOGLE_SERVICES_KEY"' >> $BASH_ENV
  decode_gservices_key: &decode_gservices_key
    run:
      name: Decode Google Services key
      command: echo $GOOGLE_SERVICES_KEY | base64 -di > app/google-services.json

  # Google Cloud Service

  export_gcloud_key: &export_gcloud_key
    run:
      name: Export Google Cloud Service key environment variable
      command: echo 'export GCLOUD_SERVICE_KEY="$GCLOUD_SERVICE_KEY"' >> $BASH_ENV
  decode_gcloud_key: &decode_gcloud_key
    run:
      name: Decode Google Cloud credentials
      command: echo $GCLOUD_SERVICE_KEY | base64 -di > ${HOME}/client-secret.json

jobs:

  # Build debug APK for unit tests and an instrumented test APK

  build_debug:
    <<: *android_config
    steps:
      - checkout
      - *restore_cache
      - run:
          name: Download dependencies
          command: ./gradlew androidDependencies
      - *save_cache
      - *export_gservices_key
      - *decode_gservices_key
      - run:
          name: Gradle build (debug)
          command: ./gradlew -PciBuild=true :app:assembleDebug :app:assembleAndroidTest
      - *persist_debug_workspace
      - store_artifacts:
          path: app/build/outputs/apk/
          destination: /apk/

  # Build release APK

  build_release:
    <<: *android_config
    steps:
      - checkout
      - *restore_cache
      - run:
          name: Download dependencies
          command: ./gradlew androidDependencies
      - *save_cache
      - *export_gservices_key
      - *decode_gservices_key
      - run:
          name: Gradle build (release)
          command: ./gradlew -PciBuild=true :app:assembleRelease
      - *persist_release_workspace
      - store_artifacts:
          path: app/build/outputs/apk/
          destination: /apk/
      - store_artifacts:
          path: app/build/outputs/mapping/
          destination: /mapping/

  # Run unit tests

  test_unit:
    <<: *android_config
    steps:
      - checkout
      - *restore_cache
      - run:
          name: Download dependencies
          command: ./gradlew androidDependencies
      - *save_cache
      - *export_gservices_key
      - *decode_gservices_key
      - run:
          name: Run unit tests
          command: ./gradlew -PciBuild=true :app:testDebugUnitTest
      - *persist_debug_workspace
      - store_artifacts:
          path: app/build/reports/
          destination: /reports/
      - store_test_results:
          path: app/build/test-results/
          destination: /test-results/

  # Run instrumented tests

  test_instrumented:
    <<: *gcloud_config
    steps:
      - *attach_debug_workspace
      - *export_gcloud_key
      - *decode_gcloud_key
      - run:
          name: Set Google Cloud target project
          command: gcloud config set project i-de-a
      - run:
          name: Authenticate with Google Cloud
          command: gcloud auth activate-service-account firebase-adminsdk-3t8n8@i-de-a.iam.gserviceaccount.com --key-file ${HOME}/client-secret.json
      - run:
          name: Echo sha1 variable for debugging
          command: echo ${CIRCLE_SHA1}
      - run:
          name: Run instrumented test on Firebase Test Lab
          command: gcloud firebase test android run --type instrumentation --app app/build/outputs/apk/debug/app-debug.apk --test app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk --device model=Nexus6P,version=27,locale=en_US,orientation=portrait --no-use-orchestrator --environment-variables coverage=true,coverageFile="/sdcard/coverage.ec" --directories-to-pull=/sdcard --timeout 20m --results-dir=${CIRCLE_SHA1}
      - run:
          name: Create directory to store test results
          command: mkdir firebase
      - run:
          name: Download instrumented test results from Firebase Test Lab
          command: gsutil -m cp -r -U gs://test-lab-hzda62mwyy730-n7hcz7bxtxrx0/${CIRCLE_SHA1} /root/workspace/firebase/
      - *persist_firebase_workspace
      - store_artifacts:
          path: firebase/
          destination: /firebase/

  # Submit JaCoCo coverage report

  report_coverage:
    <<: *android_config
    steps:
      - checkout
      - *restore_cache
      - run:
          name: Download dependencies
          command: ./gradlew androidDependencies
      - *attach_debug_workspace
      - *attach_firebase_workspace
      - run:
          name: Move Firebase coverage report
          command: mkdir -p app/build/outputs/code-coverage/connected && cp firebase/${CIRCLE_SHA1}/Nexus6P-27-en_US-portrait/artifacts/coverage.ec app/build/outputs/code-coverage/connected/coverage.ec
      - *export_gservices_key
      - *decode_gservices_key
      - run:
          name: Generate JaCoCo report
          command: ./gradlew -PciBuild=true :app:jacocoTestReport
      - run:
          name: Upload coverage report to CodeCov
          command: bash <(curl -s https://codecov.io/bash)
      - store_artifacts:
          path: app/build/reports/
          destination: /reports/

workflows:
  version: 2
  workflow:
    jobs:
      - build_debug
      - build_release
      - test_unit
      - test_instrumented:
          requires:
            - build_debug
      - report_coverage:
          requires:
            - build_release
            - test_unit
            - test_instrumented