Android单元测试官方介绍文档地址:
http://developer.android.com/intl/zh-cn/reference/android/test/InstrumentationTestRunner.html
常用的三条命令:
1.跑所有测试:
adb shell am instrument -w com.android.foo/android.test.InstrumentationTestRunner
例如跑Android上的keystore测试程序:
$ adb shell am instrument -w android.security.tests/android.test.InstrumentationTestRunner
android.security.AndroidKeyPairGeneratorTest:...............
android.security.AndroidKeyStoreTest:.................................................................
android.security.KeyPairGeneratorSpecTest:.
Error in testBuilder_Success:
java.lang.IllegalAccessError: Method 'int android.security.KeyPairGeneratorSpec.getFlags()' is inaccessible to class 'android.security.KeyPairGeneratorSpecTest' (declaration of 'android.security.KeyPairGeneratorSpecTest' appears in /data/app/android.security.tests-2/base.apk)
at android.security.KeyPairGeneratorSpecTest.testBuilder_Success(KeyPairGeneratorSpecTest.java:87)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1862)
........
android.security.KeyStoreTest:...........
Failure in testGenerate_grantedUid_Wifi_Success:
junit.framework.AssertionFailedError
at android.security.KeyStoreTest.testGenerate_grantedUid_Wifi_Success(KeyStoreTest.java:380)
at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1862)
...................................
android.security.SystemKeyStoreTest:
Failure in testBasicAccess:
junit.framework.AssertionFailedError
at android.security.SystemKeyStoreTest.testBasicAccess(SystemKeyStoreTest.java:68)
at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1862)
Test results for InstrumentationTestRunner=.........................................
.........................................
E....................F.....................
...............F
Time: 36.381
FAILURES!!!
Tests run: 138, Failures: 2, Errors: 1
2.跑单个测试类:
adb shell am instrument -w -e class com.android.foo.FooTest com.android.foo/android.test.InstrumentationTestRunner
例如跑Android keystore中的一个测试类android.security.KeyStoreTest,注意不是android.security.tests.KeyStoreTest,注意看测试类的package字段:
$ adb shell am instrument -w -e class android.security.KeyStoreTest android.security.tests/android.test.InstrumentationTestRunner
android.security.KeyStoreTest:...........
Failure in testGenerate_grantedUid_Wifi_Success:
junit.framework.AssertionFailedError
at android.security.KeyStoreTest.testGenerate_grantedUid_Wifi_Success(KeyStoreTest.java:380)
at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1862)
...................................
Test results for InstrumentationTestRunner=............F.............................
......
Time: 8.145
FAILURES!!!
Tests run: 47, Failures: 1, Errors: 0
3.跑单个测试方法:
adb shell am instrument -w -e class com.android.foo.FooTest#testFoo com.android.foo/android.test.InstrumentationTestRunner
例如跑Android keystore cts中AndroidKeyPairGeneratorTest测试类中的方法testKeyPairGenerator_GenerateKeyPair_DSA_2048_Unencrypted_Success
$ adb shell am instrument -w -e class android.keystore.cts.AndroidKeyPairGeneratorTest#testKeyPairGenerator_GenerateKeyPair_DSA_2048_Unencrypted_Success com.android.cts.keystore/android.support.test.runner.AndroidJUnitRunner
android.keystore.cts.AndroidKeyPairGeneratorTest:
Error in testKeyPairGenerator_GenerateKeyPair_DSA_2048_Unencrypted_Success(android.keystore.cts.AndroidKeyPairGeneratorTest):
java.security.InvalidKeyException: error:0A071003:dsa routines:DSA_do_verify:BN lib
at com.android.org.conscrypt.NativeCrypto.X509_verify(Native Method)
at com.android.org.conscrypt.OpenSSLX509Certificate.verifyOpenSSL(OpenSSLX509Certificate.java:349)
at com.android.org.conscrypt.OpenSSLX509Certificate.verify(OpenSSLX509Certificate.java:384)
at android.keystore.cts.AndroidKeyPairGeneratorTest.assertKeyPairCorrect(AndroidKeyPairGeneratorTest.java:471)
at android.keystore.cts.AndroidKeyPairGeneratorTest.testKeyPairGenerator_GenerateKeyPair_DSA_2048_Unencrypted_Success(AndroidKeyPairGeneratorTest.java:165)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:115)
at junit.framework.TestResult.runProtected(TestResult.java:133)
at android.support.test.internal.runner.junit3.DelegatingTestResult.runProtected(DelegatingTestResult.java:90)
at junit.framework.TestResult.run(TestResult.java:118)
at android.support.test.internal.runner.junit3.AndroidTestResult.run(AndroidTestResult.java:52)
at junit.framework.TestCase.run(TestCase.java:124)
at android.support.test.internal.runner.junit3.NonLeakyTestSuite$NonLeakyTest.run(NonLeakyTestSuite.java:63)
at junit.framework.TestSuite.runTest(TestSuite.java:243)
at junit.framework.TestSuite.run(TestSuite.java:238)
at android.support.test.internal.runner.junit3.DelegatingTestSuite.run(DelegatingTestSuite.java:103)
at android.support.test.internal.runner.junit3.AndroidTestSuite.run(AndroidTestSuite.java:52)
at android.support.test.internal.runner.junit3.JUnit38ClassRunner.run(JUnit38ClassRunner.java:90)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:24)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:245)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1862)
.E
Time: 5.235
There was 1 failure:
1) testKeyPairGenerator_GenerateKeyPair_DSA_2048_Unencrypted_Success(android.keystore.cts.AndroidKeyPairGeneratorTest)
java.security.InvalidKeyException: error:0A071003:dsa routines:DSA_do_verify:BN lib
at com.android.org.conscrypt.NativeCrypto.X509_verify(Native Method)
at com.android.org.conscrypt.OpenSSLX509Certificate.verifyOpenSSL(OpenSSLX509Certificate.java:349)
at com.android.org.conscrypt.OpenSSLX509Certificate.verify(OpenSSLX509Certificate.java:384)
at android.keystore.cts.AndroidKeyPairGeneratorTest.assertKeyPairCorrect(AndroidKeyPairGeneratorTest.java:471)
at android.keystore.cts.AndroidKeyPairGeneratorTest.testKeyPairGenerator_GenerateKeyPair_DSA_2048_Unencrypted_Success(AndroidKeyPairGeneratorTest.java:165)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:115)
at junit.framework.TestResult.runProtected(TestResult.java:133)
at android.support.test.internal.runner.junit3.DelegatingTestResult.runProtected(DelegatingTestResult.java:90)
at junit.framework.TestResult.run(TestResult.java:118)
at android.support.test.internal.runner.junit3.AndroidTestResult.run(AndroidTestResult.java:52)
at junit.framework.TestCase.run(TestCase.java:124)
at android.support.test.internal.runner.junit3.NonLeakyTestSuite$NonLeakyTest.run(NonLeakyTestSuite.java:63)
at junit.framework.TestSuite.runTest(TestSuite.java:243)
at junit.framework.TestSuite.run(TestSuite.java:238)
at android.support.test.internal.runner.junit3.DelegatingTestSuite.run(DelegatingTestSuite.java:103)
at android.support.test.internal.runner.junit3.AndroidTestSuite.run(AndroidTestSuite.java:52)
at android.support.test.internal.runner.junit3.JUnit38ClassRunner.run(JUnit38ClassRunner.java:90)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:24)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:245)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1862)
FAILURES!!!
Tests run: 1, Failures: 1
常见的错误:
$ adb shell am instrument -w android.security.tests/android.test.InstrumentationTestRunner
a.a.a:.
a.a.b:.
a.a.c:.
Test results for InstrumentationTestRunner=...
Time: 0.027
OK (3 tests)
跑成功了么?明显不是,apktool解压这个apk,可以发现类名就是a.a.a、b、c,明显这个apk编译的时候做了混淆。
这个时候,跑单个单元测试会出现死活找不到类的情况:
$ adb shell am instrument -w -e class android.security.KeyStoreTest android.security.tests/android.test.InstrumentationTestRunner
INSTRUMENTATION_RESULT: shortMsg=java.lang.RuntimeException
INSTRUMENTATION_RESULT: longMsg=java.lang.RuntimeException: Could not find test class. Class: android.security.KeyStoreTest
INSTRUMENTATION_CODE: 0
在Android.mk文件中加入
LOCAL_PROGUARD_ENABLED := disabled
disable掉proguard代码混淆重编再运行即可。
全部运行成功,会是下面这样子的,有完整的类名显示:
$ adb shell am instrument -w -e class android.security.AndroidKeyStoreTest android.security.tests/android.test.InstrumentationTestRunner
android.security.AndroidKeyStoreTest:.................................................................
Test results for InstrumentationTestRunner=.........................................
........................
Time: 5.918
OK (65 tests)