简体   繁体   English

Android Studio 中的插桩测试

[英]Instrumented Tests in Android Studio

I have been trying to run simple instrumented tests in Android Studio, without any success.我一直在尝试在 Android Studio 中运行简单的仪器测试,但没有成功。 I followed the guide for Unit Tests and it works fine.我遵循了单元测试指南,它工作正常。 Now, I would like to tests components which are difficult to mock.现在,我想测试难以模拟的组件。 When I follow the guide on instrumented tests , I end up with dependency errors.当我按照仪器测试指南进行操作时,我最终会遇到依赖项错误。

What I did:我做了什么:

  • Install the Android Testing Support Library (Android Support Repository, rev 17).安装 Android 测试支持库(Android 支持库,修订版 17)。

  • Create a directory androidTest in src.在 src 中创建一个目录 androidTest。 Add Java folder + package ending with "test".添加 Java 文件夹 + 以“test”结尾的包。

  • Add a simple Test class添加一个简单的测试类
 @RunWith(AndroidJUnit4.class) public class ServerRequestInstrumentationTest { @Test public void test(){ LogC.d("Here we go testing !"); } }
  • Add a simple TestSuit.添加一个简单的 TestSuit。
 @RunWith(Suite.class) @Suite.SuiteClasses({ServerRequestInstrumentationTest.class}) public class TestSuit { public TestSuit(){} }
  • Modify my gradle file to add dependencies.修改我的 gradle 文件以添加依赖项。
 apply plugin: 'com.android.application' android { compileSdkVersion 22 buildToolsVersion "22.0.1" defaultConfig { applicationId "com.mydomain.app" minSdkVersion 9 targetSdkVersion 22 versionCode 28 versionName "2.0.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" compileOptions { sourceCompatibility JavaVersion.VERSION_1_7 targetCompatibility JavaVersion.VERSION_1_7 } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' lintOptions { disable 'MissingTranslation' } } } sourceSets { main { java.srcDirs = ['src/main/java'] } } } dependencies { compile 'com.android.support:support-v4:22.2.0' compile 'com.android.support:appcompat-v7:22.2.0' wearApp project(':wear') compile project(':moreapps') compile project(':lib_repair') compile project(':bugreport') //testCompile 'junit:junit:4.12' testCompile 'org.mockito:mockito-core:1.10.19' androidTestCompile 'junit:junit:4.12' androidTestCompile 'org.hamcrest:hamcrest-library:1.1' androidTestCompile 'com.android.support.test:runner:0.3' androidTestCompile 'com.android.support.test:rules:0.3' }

I just added the line androidTestCompile 'junit:junit:4.12' , otherwise the annotation @RunWith(AndroidJUnit4.class) wasn't recognized.我刚刚添加了androidTestCompile 'junit:junit:4.12' ,否则无法识别注释@RunWith(AndroidJUnit4.class) Now when I launch the test, I get one Gradle build error.现在,当我启动测试时,我收到一个 Gradle 构建错误。

Error:Execution failed for task ':app:dexDebugAndroidTest'.错误:任务 ':app:dexDebugAndroidTest' 的执行失败。

com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/usr/lib/jvm/jdkoracle/bin/java'' finished with non-zero exit value 2 com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/usr/lib/jvm/jdkoracle/bin/java'' 以非零退出值 2 结束

Any suggestion ?有什么建议吗? Did I miss something about the testing library ?我是否错过了有关测试库的某些内容?

Thank you谢谢

Okay, finally got it working.好的,终于搞定了。

After a little search, I found out that the Gradle console output an error :经过一番搜索,我发现 Gradle 控制台输出了一个错误:

AGPBI: {"kind":"simple","text":"UNEXPECTED TOP-LEVEL EXCEPTION:","sources":[{}]}
AGPBI: {"kind":"simple","text":"com.android.dex.DexException: Multiple dex files define Lorg/hamcrest/TypeSafeMatcher;","sources":[{}]}

After I changed one line in my gradle build, Gradle built the project successfuly and I was able to run the simple instrumented test.在我的 gradle 构建中更改了一行之后,Gradle 成功构建了项目,并且我能够运行简单的仪器测试。

Line to change:要更改的行:

androidTestCompile 'org.hamcrest:hamcrest-library:1.1'

to

testCompile 'org.hamcrest:hamcrest-library:1.1'

I don't know why Gradle complains in one case and not the other though...我不知道为什么 Gradle 在一种情况下抱怨而不是在另一种情况下抱怨......

Instrumentation tests are different to Unit Tests.仪器测试不同于单元测试。 You have to extend your test classes by specific classes.您必须通过特定类扩展您的测试类。 For more information about that take a look atAndroid Testing Fundamentals .有关更多信息,请查看Android 测试基础知识 Also you do not need JUnit for Instrumentaion tests.此外,您不需要 JUnit 进行 Instrumentaion 测试。

Furthermore you have to switch your build variants from Unit Tests to Android Instrumentation Tests, as described here Unit testing in android studio此外,您必须将构建变体从单元测试切换到 Android Instrumentation 测试,如此处所述android studio 中的单元测试

EXAMPLE:例子:

Here an example for an instrumentaion test in android:这是一个在 android 中进行仪器测试的示例:

public class ExampleITest extends AndroidTestCase {

  @Override
  public void setUp() throws Exception {
    super.setUp();
    InputStream is = getContext().getAssets().open("test.xml");
    XmlParser parser = new XmlParser(getContext());
    parser.parse(is);
    ...
  }

  @MediumTest
  public void testSomething() throws Exception {      
    // test some data your parser extracted from the xml file
    ...
  }
}

As you can see, you can access context, etc. For this test no specific dependencies are necessary in the gradle file.如您所见,您可以访问上下文等。对于此测试,gradle 文件中不需要特定的依赖项。

I haven't heard about Instrumantation tests just with annotions.我还没有听说过带有注释的 Instrumantation 测试。 maybe i should look it up on the web ;)也许我应该在网上查一下;)

Althought @Gordark's answer will not throw any error It's not a proper solution if you want to use Hamcrest in your instrumentation tests, it will work just for your local JVM tests.尽管@Gordark 的回答不会抛出任何错误如果您想在仪器测试中使用 Hamcrest,这不是一个合适的解决方案,但它仅适用于您的本地 JVM 测试。

I found that using 1.3 version of hamcrest-library actually worked, just replace我发现使用 1.3 版本的 hamcrest-library 确实有效,只需替换

androidTestCompile 'org.hamcrest:hamcrest-library:1.1'

with

androidTestCompile 'org.hamcrest:hamcrest-library:1.3'

And it should work.它应该工作。 I think it's something about conflicting versions of junit and hamcrest.我认为这与 junit 和 hamcrest 的版本冲突有关。 I guess hamcrest 1.1 depends on a version of junit bellow 4.12, and hamcrest 1.3 depends on junit v4.12我猜 hamcrest 1.1 取决于 junit bellow 4.12 的版本,而 hamcrest 1.3 取决于 junit v4.12

Your answer contains a hint to the problem.您的回答包含对问题的提示。 You state there that Gradle gives an error.你在那里声明 Gradle 给出了一个错误。 This is because one of the other dependencies for androidTestCompile depends on hamcrest.这是因为androidTestCompile的其他依赖androidTestCompile依赖于 hamcrest。 This is called a transitive dependency.这称为传递依赖。 It also means that you can completely remove your explicit requirement for hamcrest.这也意味着您可以完全删除对 hamcrest 的明确要求。 Your change adds hamcrest as a dependency for testCompile which is used for unit tests run locally on your development machine rather than on an Android device or emulator.您的更改将 hamcrest 添加为testCompile的依赖项,用于在您的开发机器上本地运行的单元测试,而不是在 Android 设备或模拟器上运行。 If you aren't making unit tests you don't need this.如果您不进行单元测试,则不需要这个。 Even when you do start writing unit tests, you probably don't need an explicit dependency on hamcrest.即使您开始编写单元测试,您也可能不需要显式依赖 hamcrest。

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

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