1、引入espresso時報錯,hamcrest等包無法解析
原因:espresso版本與annotation版本不兼容,
解決:引用espresso與annotation是注意版本號,可以看google官方:https://github.com/googlesamples/android-testing
2、報告empty test
原因:TestRunner設置錯誤
解決:gradle:
android
{
defaultConfig
{
instrumentationRunner "android.support.test.runner.AndroidJUnitRunner"//注意不是AndroidJunit4
}
}
TestClass:
@Runwith(AndroidJunit4.class)
public class TestClass
{
@Test
public void testClass()
{
}
}
configuration:
specify instrumentationRunner :
AndroidJunitRunner //注意不是AndroidJunit4
3、使用ActivityInstrumentationTestCase2是報告No Activity Found
原因:setup僅僅覆寫,沒有改註解
方法:
@Before//添加before註解
@Override
public void setUp() throws Exception //protected改public
{
super.setUp();
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
getActivity();
}
4,、automator運行是需要依賴於apk的,也就是和apk在同一個進程:在automator中獲取包名時是apk的包名,context獲取進程也是當前apk的進程
所以如果在automator所在apk和測試apk相同時,使用命令關閉測試apk時會導致測試線程崩潰,同樣在ui線程中如果有system.exit(0)則同樣會造成進程退出,測試崩潰
5、espresso需要依賴源代碼,如果我在源代碼所在工程上新建module,則需要將application所在module作爲library,需要修改gradle改爲apply plugin ‘com.android.application’,並且刪除applicationid。但是這樣會導致application不能直接運行安裝。
6、針對上述兩個問題,我能想到的辦法是將測試用例分到兩個module中,ui代碼中放不需要測試退出的代碼,新建module中放置剩餘代碼
7、espresso官方文檔已經說明,espresso在內部已經做了同步處理,說詳細點,也就是espresso會等待UI線程的消息隊列爲空閒時纔會執行測試線程,當然還會等待所有AsyncTask執行完。就第一種情況而言,當所處頁面在不停的發消息刷新頁面時(有人說要求間隔在50ms內),則測試線程會被掛起,掛起60s還沒執行則會導致異常
AppNotIdleException
好的辦法是使用automator獲取控件替代
8、還是針對espresso和uiautomator混合使用的問題,如果需要將兩個測試框架放一起,有要求能測試關閉app,則需要新建一個module放置測試代碼,然後將application module作爲library使用,這裏如果用到androidannotation的畫需要將註解使用方式轉換
只是需要將原來的 R.資源.資源名的方式 換成使用resName的方式即可
這樣就在library 項目中使用AA 了引用:http://blog.csdn.net/soslinken/article/details/44672391
引用:https://github.com/androidannotations/androidannotations/wiki/Library-projects9、和8類似的問題,將application改爲library後使用switch(id)會出現resource ids cannot be used,因爲資源id作爲library時會變爲非final,此時不能用與switch ,通用改法是改爲ifelse
10、爲了解決espresso和uiautomator混合使用的問題,還有一種辦法,可以使用espresso在非源碼下使用
引用:http://blog.csdn.net/shandong_chu/article/details/47280255,可以看出博主是從robotium中拷過來的
經過測試發現不能通過反射實例化對象,猜測不在同一包下的原因,但是即使把測試包的包名改成和待測試apk包名一樣,運行測試時會出現待測試apk被卸載,測試包的apk被安裝的情況,導致依然無法通過反射找到activity
運行Instrumentation測試步驟:
$ adb push E:\workhome\libgdx\androidstudio\MyApplicationTest\apptest\build\outputs\apk\apptest-debug.apk /data/local/tmp/com.mystudiotest.myapplicationtest
$ adb shell pm install -r "/data/local/tmp/com.mystudiotest.myapplicationtest"
pkg: /data/local/tmp/com.mystudiotest.myapplicationtest
Success
//安裝測試所在module的apk
$ adb push E:\workhome\libgdx\androidstudio\MyApplicationTest\apptest\build\outputs\apk\apptest-debug-androidTest-unaligned.apk /data/local/tmp/com.mystudiotest.myapplicationtest.test
$ adb shell pm install -r "/data/local/tmp/com.mystudiotest.myapplicationtest.test"
pkg: /data/local/tmp/com.mystudiotest.myapplicationtest.test
Success
//安裝測試apk
Running tests
$ adb shell am instrument -w -r -e debug false -e class com.mystudiotest.myapplicationtest.AppInstrumentationTest com.mystudiotest.myapplicationtest.test/android.support.test.runner.AndroidJUnitRunner
Client not ready yet..Test running started
//運行Instrumentation測試
所以猜測是android studio自動安裝apk導致待測apk被覆蓋
但是即使我手動運行腳本,去掉上述第一步,又會出現classnotfound故障,找不到androidjunitrunner類
不管怎樣,按照上述android studio腳本,android studio已經默認將espresso放在源代碼module內部,按照github上googleandroid給出的例子,也是放在源代碼module中的androidtest中,所以還是不糾結了
11、android studio2.1可以顯示所有測試代碼而不需要設置build variant,但是android studio需要在環境中設置ANDROID_HOME也就是SDK的位置
12、junit版本衝突:自動化測試需要Junit:4.8.2,而4.8.2版本沒有org.junit.runners.model.Annitatable類,導致單元測試框架Robolectric缺少依賴,發出警告,需要在gradle配置單元測試依賴包:testCompile "junit:junit:4.12"
13、robolectric3.0有一處bug,單個單元測試運行是好的,但是多個單元測試一起運行卻報錯:
java.lang.ClassCastException: Cannot cast java.lang.Object to XXX
看源代碼,是shadow對象互相干擾的問題,應該是robolectric的bug
將robolectric升級到3.1後,有一處改動:RobolectricGradleTestRunner的
public InstrumentationConfiguration createClassLoaderConfig()
{}
改爲:
public InstrumentationConfiguration createClassLoaderConfig(Config config)
{}
也就是將測試用例的config傳進來,可以看到框架做出了處理:
public Builder withConfig(Config config) {
for (Class<?> clazz : config.shadows()) {
Implements annotation = clazz.getAnnotation(Implements.class);
if (annotation == null) {
throw new IllegalArgumentException(clazz + " is not annotated with @Implements");
}
String className = annotation.className();
if (className.isEmpty()) {
className = annotation.value().getName();
}
if (!className.isEmpty()) {
addInstrumentedClass(className);
}
}
for (String packageName : config.instrumentedPackages()) {
addInstrumentedPackage(packageName);
}
return this;
}
也就是隻加載需要模擬的shadow類,原來的則是加載所有shadow類,打出log,發現原來的shadow類在兩個測試用例中只進行一次初始化,而現在則要進行兩次,原因是原來都當做shadow類來處理,而現在是隻在config聲明的shadow當做shadow處理,而沒有聲明的則當做原始類處理
運行後發現解決了這類故障
不過升級到3.1後,建議將java升級到java8,防止發送內存溢出