[英]Android Instrumented unit test on project library
I inherited an Android Project composed by the main app and a Library . 我继承了一个由主应用程序和一个Library组成的Android Project。 My goal is to test the whole project, so I started from the Library : first i use JUnit to test some classes/method, writing my test undeer app/src/test/java (unit test) of my Library project, also generating a code coverage report by Android Studio.
我的目标是测试整个项目,所以我从库开始:首先我使用JUnit测试一些类/方法,编写我的库项目的测试undeer app / src / test / java(单元测试),并生成一个Android Studio的代码覆盖率报告。 The problem comes when i find a Class that uses Parcel (from Android Framework), so this time I had to setup an instrumented test (app/src/androidTest/java), also within the Library project.
当我找到一个使用Parcel的类(来自Android Framework)时,问题就来了,所以这一次,我不得不在Library项目中也设置了一个已测试的测试(app / src / androidTest / java)。
When I try run the instrumented test, plugging an Android device, i got this message: 当我尝试运行检测到的测试并插入Android设备时,收到以下消息:
Started running tests
Test running failed: Instrumentation run failed due to 'java.lang.ClassNotFoundException'
Empty test suite.
I don't understand why "Empty test suite" while there're several @Test methods in my test class. 我不明白为什么在测试类中有几个@Test方法时会“清空测试套件”。 Have I to setup Gradle how to link main app and library during test o maybe I have to move all my test in the main app?!
我是否已设置Gradle如何在测试期间链接主应用程序和库,或者可能必须将所有测试都移至主应用程序中?
This is my gradle for Library module: 这是我为图书馆模块准备的:
apply plugin: 'com.android.library'
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
// Added for instrumental tests
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
debuggable true
testCoverageEnabled true
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
testOptions {
unitTests.returnDefaultValues = true
}
}
dependencies {
implementation "com.android.support:support-v4:$rootProject.supportLibraryVersion"
implementation "com.google.code.gson:gson:$rootProject.gsonVersion"
implementation "commons-io:commons-io:$rootProject.commonsioVersion"
// Dependencies for RxBinding
implementation 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
// Dependencies for Rxjava2 and RxAndroid
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation 'io.reactivex.rxjava2:rxjava:2.1.8'
// Dependencies for RxBinding
implementation 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
// Dependencies for Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-simplexml:2.3.0'
implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
implementation 'com.squareup.okhttp:okhttp:2.7.0'
// Dependencies for Room
// Room (use 1.1.0-alpha1 for latest alpha)
implementation 'android.arch.persistence.room:runtime:1.1.1'
implementation 'android.arch.persistence.room:rxjava2:1.1.1'
annotationProcessor "android.arch.persistence.room:compiler:1.1.1"
implementation "com.android.support:support-annotations:$rootProject.supportLibraryVersion"
implementation "org.apache.httpcomponents:httpcore:$rootProject.httpcoreVersion"
testImplementation 'junit:junit:4.12'
// // [Android Instrumented test]
androidTestImplementation 'junit:junit:4.12'
// androidTestImplementation 'androidx.test:runner:1.1.0'
// androidTestImplementation 'androidx.test:rules:1.1.0'
// // Optional -- Hamcrest library
androidTestImplementation 'org.hamcrest:hamcrest-library:1.3'
// // Optional -- UI testing with Espresso
// androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
// // Optional -- UI testing with UI Automator
// androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
api files('libs/lifesense_ble_v3.3.7.jar')
api files('libs/MedPixel.jar')
}
and app's: 和应用程序的:
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
buildToolsVersion '28.0.3'
defaultConfig {
applicationId "it.*******.********"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 2
versionName "1.0.2"
}
buildTypes {
release {
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
applicationIdSuffix ".debug"
debuggable true
}
}
lintOptions {
checkReleaseBuilds false
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation project(':..:Libraries:app')
implementation "com.android.support:support-v4:$rootProject.supportLibraryVersion"
implementation "com.google.code.gson:gson:$rootProject.gsonVersion"
implementation "commons-io:commons-io:$rootProject.commonsioVersion"
// Dependencies for ButterKnife
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
// Dependencies for Dagger
implementation 'com.google.dagger:dagger:2.11'
annotationProcessor 'com.google.dagger:dagger-compiler:2.11'
// Dependencies for RxBinding
implementation 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
// Dependencies for Rxjava2 and RxAndroid
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation 'io.reactivex.rxjava2:rxjava:2.1.8'
// Dependencies for Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-simplexml:2.3.0'
implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
implementation 'com.squareup.okhttp:okhttp:2.7.0'
// Dependencies for Room
implementation 'android.arch.persistence.room:runtime:1.1.1'
// Dependencies for Roboelecttic
testImplementation 'org.robolectric:robolectric:3.6.1'
testImplementation 'junit:junit:4.12'
// Dependencies for Mockito
testImplementation 'org.mockito:mockito-core:2.7.22'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
androidTestImplementation 'com.squareup.retrofit2:retrofit-mock:2.0.0'
androidTestImplementation 'com.squareup.okhttp:mockwebserver:2.7.0'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'org.mockito:mockito-android:2.7.22'
}
configurations.all {
resolutionStrategy {
force "android.arch.core:runtime:1.1.1"
force "com.android.support:support-core-utils:28.0.0"
/*force "com.android.support:support-compat:28.0.0"*/
}
}
Thanks for the attention! 感谢您的关注!
I have run into the same problem, not with Parcel
but with other android components like Context
. 我遇到了同样的问题,不是
Parcel
而是其他Android组件(如Context
。
For this issue, 对于这个问题
Empty test suite
空测试套件
Your instrumented test class in must annotated with @RunWith(AndroidJUnit4.class)
. 您的检测测试类必须使用
@RunWith(AndroidJUnit4.class)
注释 。
Initially I did write the Instrumented tests in app
. 最初,我确实在
app
编写了Instrumented测试。 But the problem with writing library's InstrumentationTests
in app
is, you will not get the coverage report for your library
. 但是在
app
编写库的InstrumentationTests
的问题是,您将不会获得library
的覆盖率报告。
So, I moved the InstrumentedTests
back to library/androidTest
folder. 因此,我将
InstrumentedTests
移回了library/androidTest
文件夹。 After a lot of research, I found a solution to get complete coverage report for library
经过大量研究,我找到了一种解决方案,可获取
library
完整覆盖率报告
Do following things in your library's build.gradle
file to get coverage 在库的
build.gradle
文件中执行以下操作以获得覆盖率
Add apply plugin: 'jacoco'
添加
apply plugin: 'jacoco'
Enable test coverage as below 启用如下测试范围
android { buildTypes { debug { testCoverageEnabled true } } ... }
Add below dependencies 添加以下依赖项
androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test:rules:1.0.2'
I believe, for any module in your project, If there are androidTests
in your module/library, there will be a default task called combinedTestReportDebug
. 我相信,对于您项目中的任何模块,如果您的模块/库中都存在
androidTests
,那么将存在一个默认任务,称为combinedTestReportDebug
。
You can find it in Gradle
menu available in vertical bar at Top right corner of Android studio. 您可以在Android Studio右上角垂直栏中的
Gradle
菜单中找到它。
Gradle menu > :your-library > Tasks > reporting > combinedTestReportDebug
or 要么
from run this command in your Terminal
> ./gradlew clean combinedTestReportDebug -p :your-library
从在您的
Terminal
> ./gradlew clean combinedTestReportDebug -p :your-library
运行此命令
After the tests are completed, you can find coverage or failed tests in following location 测试完成后,您可以在以下位置找到覆盖率或失败的测试
For failed tests: your-library/build/reports/androidTests/connected/index.html
对于失败的测试:
your-library/build/reports/androidTests/connected/index.html
For coverage report: your-library/build/reports/coverage/debug/index.html
对于覆盖率报告:
your-library/build/reports/coverage/debug/index.html
I hope this helps. 我希望这有帮助。
Sorry, I have forgot to mention the below step which is needed because if not combinedTestReportDebug
will not be visible. 抱歉,我忘了提到需要执行的以下步骤,因为如果未
combinedTestReportDebug
则看不到TestTestDebug。 Thanks to @nicoabie. 感谢@nicoabie。
In your project's build.gradle
file, do the following to make combinedTestReportDebug
task visible in your library gradle tasks. 在项目的
build.gradle
文件中,执行以下操作,以在您的库gradle任务中使combinedTestReportDebug
任务可见。
buildscript {
repositories {
jcenter()
}
dependencies {
...
classpath 'com.vanniktech:gradle-android-junit-jacoco-plugin:0.13.0'
...
}
}
...
apply plugin: 'com.vanniktech.android.junit.jacoco'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.