如何用 Gradle 覆盖 android 测试路径?
How to override android tests path with Gradle?
由于历史原因,仪器测试未存储在 androidTests
目录 as required 中,我无法更改目录结构(实际上整个应用程序是对所用库的测试)。我能够使用 gradle 构建和安装 apk,但未找到测试:
:app-tests:connectedDebugAndroidTest
Tests on test_avd(AVD) - 4.1.2 failed: Instrumentation run failed due to 'java.lang.ClassNotFoundException'
com.android.builder.testing.ConnectedDevice > No tests found.[test_avd(AVD) - 4.1.2] FAILED
No tests found. This usually means that your test classes are not in the form that your test runner expects (e.g. don't inherit from TestCase or lack @Test annotations).
:app-tests:connectedDebugAndroidTest FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app-tests:connectedDebugAndroidTest'.
> There were failing tests. See the report at: file:///Users/asmirnov/Documents/dev/src/project/app-tests/build/reports/androidTests/connected/index.html
实际上测试在 src
文件夹中,正确编写并且可以 built/runned 使用 Ant:
public abstract class BaseTest extends AndroidTestCase
{
...
public class AppInfoTest extends BaseTest
{
@Test
public void testAllProperties()
{
...
...
如何使 Gradle 处理 src
文件夹作为 android(仪器)测试?
这是我当前的 build.gradle
文件(它使用 experimental Android Gradle plugin 版本 0.7.2,因为我们有一个 NDK 库):
apply plugin: 'com.android.model.application'
allprojects {
repositories {
mavenLocal()
mavenCentral()
}
}
repositories {
mavenLocal()
mavenCentral()
}
model {
android {
compileSdkVersion 16
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "app.tests"
minSdkVersion.apiLevel 9
targetSdkVersion.apiLevel 16
versionCode 359
versionName "1.3"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
sources {
main {
// overriding paths from default ones to actual ones
// what about 'androidTests' ?
manifest { source {
srcDir '.'
include 'AndroidManifest.xml'
} }
java { source { srcDirs = ['src'] } }
res { source { srcDirs = ['res'] } }
jni {
dependencies {
project ":library" // native library dependency
}
}
}
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile project(':library')
}
更新 1(对于 sschuberth):
配置:
apply plugin: 'com.android.model.application'
allprojects {
repositories {
mavenLocal()
mavenCentral()
}
}
repositories {
mavenLocal()
mavenCentral()
}
model {
android {
compileSdkVersion 16
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "app.tests"
minSdkVersion.apiLevel 9
targetSdkVersion.apiLevel 16
versionCode 359
versionName "1.3"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
sourceSets {
androidTest {
manifest.srcFile 'AndroidManifest.xml' // error here
java.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile project(':library')
}
错误
FAILURE: Build failed with an exception.
* Where:
Build file '/Users/asmirnov/Documents/dev/src/project/app-tests/build.gradle' line: 32
* What went wrong:
A problem occurred configuring project ':app-tests'.
> Exception thrown while executing model rule: android { ... } @ app-tests/build.gradle line 16, column 5
> Could not find property 'manifest' on source set 'android test'.
不完全确定这是否适用于您的方案,但您可以像这样更新 androidTest
sourceSet 的根目录
android {
sourceSets {
androidTest.setRoot('src')
}
}
还有一个 test
源集,如果它只是 Java 代码,没有 Android 特定内容。
您也可以使用 java.srcDir
设置...
以上设置将查看这些文件的位置。
<project>/<module>/src/AndroidManifest.xml
<project>/<module>/src/java
如果您想将两者都移动到 /src
目录中,您可以使用
sourceSets {
androidTest {
setRoot 'src'
java.srcDirs = ['src']
}
}
更多Android Gradle详情可在Configuring the Structure
阅读
欢迎您使用此设置自行调试这些设置
sourceSets {
androidTest {
setRoot 'src'
java.srcDirs = ['./src']
}
println "androidTest.manifest.srcFile = ${androidTest.manifest.srcFile}"
println "androidTest.java.srcDirs = ${androidTest.java.srcDirs}"
}
当您清理项目时,您会看到这些行被打印到控制台
您应该使用 sourceSets {}
和 androidTest
源集来自定义测试源代码位置,而不是 sources {}
:
model { // Required for experimental plugin.
android {
sourceSets {
androidTest {
manifest.srcFile '../AppTest/AndroidManifest.xml'
java.srcDirs = ['../AppTest/src']
res.srcDirs = ['../AppTest/res']
assets.srcDirs = ['../AppTest/assets']
}
}
}
}
请注意,这不适不适 适用于单元测试。对于单元测试(与 Robolectric 一样),请使用 test
源集。
这是一个棘手的解决方案:使用实验性 gradle 插件通过 NDK 编译本机代码,并使用常规 gradle 插件来测试应用程序。
build.gradle:
buildscript {
repositories {
mavenLocal()
mavenCentral()
jcenter()
}
dependencies {
// experimental gradle plugin for the library to compile native code with NDK
classpath "com.android.tools.build:gradle-experimental:0.7.2"
// regular gradle plugin for the tests
classpath 'com.android.tools.build:gradle:2.1.2'
}
}
subprojects {
task listAllDependencies(type: DependencyReportTask) {}
}
库gradle(实验):
apply plugin: 'com.android.model.library'
...
model {
android {
...
ndk {
moduleName = "library-jni"
cppFlags.add("-std=c++11")
cppFlags.add("-fexceptions")
stl = "c++_static"
abiFilters.addAll(['armeabi-v7a', 'x86']) // supported abis only
}
...
}
...
}
app/build.gradle(常规):
apply plugin: 'com.android.application'
allprojects {
repositories {
mavenLocal()
mavenCentral()
}
}
repositories {
mavenLocal()
mavenCentral()
}
android {
compileSdkVersion 16
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "app.tests"
minSdkVersion 9
targetSdkVersion 16
versionCode 359
versionName "1.3"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
}
androidTest {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
jni {
dependencies {
project ":library"
}
}
}
}
}
dependencies {
androidTestCompile project(':library')
androidTestCompile fileTree(include: ['*.jar'], dir: 'libs')
}
由于历史原因,仪器测试未存储在 androidTests
目录 as required 中,我无法更改目录结构(实际上整个应用程序是对所用库的测试)。我能够使用 gradle 构建和安装 apk,但未找到测试:
:app-tests:connectedDebugAndroidTest
Tests on test_avd(AVD) - 4.1.2 failed: Instrumentation run failed due to 'java.lang.ClassNotFoundException'
com.android.builder.testing.ConnectedDevice > No tests found.[test_avd(AVD) - 4.1.2] FAILED
No tests found. This usually means that your test classes are not in the form that your test runner expects (e.g. don't inherit from TestCase or lack @Test annotations).
:app-tests:connectedDebugAndroidTest FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app-tests:connectedDebugAndroidTest'.
> There were failing tests. See the report at: file:///Users/asmirnov/Documents/dev/src/project/app-tests/build/reports/androidTests/connected/index.html
实际上测试在 src
文件夹中,正确编写并且可以 built/runned 使用 Ant:
public abstract class BaseTest extends AndroidTestCase
{
...
public class AppInfoTest extends BaseTest
{
@Test
public void testAllProperties()
{
...
...
如何使 Gradle 处理 src
文件夹作为 android(仪器)测试?
这是我当前的 build.gradle
文件(它使用 experimental Android Gradle plugin 版本 0.7.2,因为我们有一个 NDK 库):
apply plugin: 'com.android.model.application'
allprojects {
repositories {
mavenLocal()
mavenCentral()
}
}
repositories {
mavenLocal()
mavenCentral()
}
model {
android {
compileSdkVersion 16
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "app.tests"
minSdkVersion.apiLevel 9
targetSdkVersion.apiLevel 16
versionCode 359
versionName "1.3"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
sources {
main {
// overriding paths from default ones to actual ones
// what about 'androidTests' ?
manifest { source {
srcDir '.'
include 'AndroidManifest.xml'
} }
java { source { srcDirs = ['src'] } }
res { source { srcDirs = ['res'] } }
jni {
dependencies {
project ":library" // native library dependency
}
}
}
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile project(':library')
}
更新 1(对于 sschuberth):
配置:
apply plugin: 'com.android.model.application'
allprojects {
repositories {
mavenLocal()
mavenCentral()
}
}
repositories {
mavenLocal()
mavenCentral()
}
model {
android {
compileSdkVersion 16
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "app.tests"
minSdkVersion.apiLevel 9
targetSdkVersion.apiLevel 16
versionCode 359
versionName "1.3"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
sourceSets {
androidTest {
manifest.srcFile 'AndroidManifest.xml' // error here
java.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile project(':library')
}
错误
FAILURE: Build failed with an exception.
* Where:
Build file '/Users/asmirnov/Documents/dev/src/project/app-tests/build.gradle' line: 32
* What went wrong:
A problem occurred configuring project ':app-tests'.
> Exception thrown while executing model rule: android { ... } @ app-tests/build.gradle line 16, column 5
> Could not find property 'manifest' on source set 'android test'.
不完全确定这是否适用于您的方案,但您可以像这样更新 androidTest
sourceSet 的根目录
android {
sourceSets {
androidTest.setRoot('src')
}
}
还有一个 test
源集,如果它只是 Java 代码,没有 Android 特定内容。
您也可以使用 java.srcDir
设置...
以上设置将查看这些文件的位置。
<project>/<module>/src/AndroidManifest.xml
<project>/<module>/src/java
如果您想将两者都移动到 /src
目录中,您可以使用
sourceSets {
androidTest {
setRoot 'src'
java.srcDirs = ['src']
}
}
更多Android Gradle详情可在Configuring the Structure
阅读欢迎您使用此设置自行调试这些设置
sourceSets {
androidTest {
setRoot 'src'
java.srcDirs = ['./src']
}
println "androidTest.manifest.srcFile = ${androidTest.manifest.srcFile}"
println "androidTest.java.srcDirs = ${androidTest.java.srcDirs}"
}
当您清理项目时,您会看到这些行被打印到控制台
您应该使用 sourceSets {}
和 androidTest
源集来自定义测试源代码位置,而不是 sources {}
:
model { // Required for experimental plugin.
android {
sourceSets {
androidTest {
manifest.srcFile '../AppTest/AndroidManifest.xml'
java.srcDirs = ['../AppTest/src']
res.srcDirs = ['../AppTest/res']
assets.srcDirs = ['../AppTest/assets']
}
}
}
}
请注意,这不适不适 适用于单元测试。对于单元测试(与 Robolectric 一样),请使用 test
源集。
这是一个棘手的解决方案:使用实验性 gradle 插件通过 NDK 编译本机代码,并使用常规 gradle 插件来测试应用程序。
build.gradle:
buildscript {
repositories {
mavenLocal()
mavenCentral()
jcenter()
}
dependencies {
// experimental gradle plugin for the library to compile native code with NDK
classpath "com.android.tools.build:gradle-experimental:0.7.2"
// regular gradle plugin for the tests
classpath 'com.android.tools.build:gradle:2.1.2'
}
}
subprojects {
task listAllDependencies(type: DependencyReportTask) {}
}
库gradle(实验):
apply plugin: 'com.android.model.library'
...
model {
android {
...
ndk {
moduleName = "library-jni"
cppFlags.add("-std=c++11")
cppFlags.add("-fexceptions")
stl = "c++_static"
abiFilters.addAll(['armeabi-v7a', 'x86']) // supported abis only
}
...
}
...
}
app/build.gradle(常规):
apply plugin: 'com.android.application'
allprojects {
repositories {
mavenLocal()
mavenCentral()
}
}
repositories {
mavenLocal()
mavenCentral()
}
android {
compileSdkVersion 16
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "app.tests"
minSdkVersion 9
targetSdkVersion 16
versionCode 359
versionName "1.3"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
}
androidTest {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
jni {
dependencies {
project ":library"
}
}
}
}
}
dependencies {
androidTestCompile project(':library')
androidTestCompile fileTree(include: ['*.jar'], dir: 'libs')
}