背景
這兩天把 app 中的一個模組拆分出來寫了一個 library,寫完後滿心歡喜的寫個測試用例測一下,直接右鍵選擇 “Run testDataFileByMin” 執行測試,結果提示找不到測試用例,Run 控制檯輸出如下:
Testing started at 16:21 ...
08/10 16:21:54: Launching testDataFileByMin()
$ adb push /Users/panpf/Workspace/AppSample/app/build/outputs/apk/app-lollipop-debug.apk /data/local/tmp/com.sample.app
$ adb shell pm install -r "/data/local/tmp/com.sample.app"
pkg: /data/local/tmp/com.sample.app
Success
$ adb push /Users/panpf/Workspace/AppSample/app/build/outputs/apk/app-lollipop-debug-androidTest.apk /data/local/tmp/com.sample.app.test
$ adb shell pm install -r "/data/local/tmp/com.sample.app.test"
pkg: /data/local/tmp/com.sample.app.test
Success
Running tests
$ adb shell am instrument -w -r -e debug false -e class com.sample.library.stat.DataFileTest#testDataFileByMin com.sample.app.test/android.support.test.runner.AndroidJUnitRunner
Client not ready yet..
Started running tests
Tests ran to completion.
Empty test suite.
複製程式碼
一時間有些懵逼了,沒遇到過這問題啊,咋就會找不到測試用例呢。另一個專案中也寫過 library 的測試用例,能跑起來啊
懷疑一切
本著懷疑一切的精神首先懷疑是不是測試相關的配置
有問題,然後就開始了各種檢查,並且照著另一個專案的配置一一比對,不一樣的都改成一樣的,再跑測試,結果還是找不到測試用例
然後懷疑測試相關依賴的版本
是不是有問題,因為另一個專案中用的是最新的
1.0.0 的 runner 和 rules,而當前用的是 0.5 版本的,改成 1.0.0 後再跑測試,結果依然是找不到測試用例
接下來懷疑是不是測試用例寫的有問題,就把測試用例拷貝到另一個專案中,跑一下結果能找到,看來用例寫的沒問題
再懷疑是不是用的是 Canary 版本的 Android Studio (3.0 Canary 8)的 bug,就換回 2.3 Stable 版的 Android Studio 再跑,仍舊是找不到測試用例
柳暗花明
正當一愁莫展的時候無意間發現 Run 控制檯輸出的資訊中顯示安裝的是我的 app module,注意這行:
$ adb push /Users/panpf/Workspace/AppSample/app/build/outputs/apk/app-lollipop-debug-androidTest.apk /data/local/tmp/com.sample.app.test
複製程式碼
感覺有些奇怪,就去另一個專案中跑一下其 library 的測試,看其 Run 控制檯輸出如下:
Testing started at 10:31 ...
08/11 10:31:01: Launching testReadApkIcon()
$ adb push /Users/panpf/Workspace/sketch/sketch/build/outputs/apk/sketch-debug-androidTest.apk /data/local/tmp/me.xiaopan.sketch.test
$ adb shell pm install -t -r "/data/local/tmp/me.xiaopan.sketch.test"
pkg: /data/local/tmp/me.xiaopan.sketch.test
Success
Running tests
$ adb shell am instrument -w -r -e debug false -e class me.xiaopan.sketch.androidtest.SketchUtilsTest#testReadApkIcon me.xiaopan.sketch.test/android.support.test.runner.AndroidJUnitRunner
Client not ready yet..
Started running tests
Tests ran to completion.
複製程式碼
sketch-debug-androidTest.apk 是 sketch module 的測試 APK,sketch module 是一個 library
一對比發現後者輸出的資訊中 安裝的是 library 的 測試 APK ,而前者輸出的資訊中安裝的是 app 的測試 APK
到這裡問題似乎也就呼之欲出了,但為什麼我在 library 中執行測試用例會跑到 app 中呢,想到這裡就立馬進入執行配置中找到剛剛建立的執行配置檢視
一看就驚呆了,這指定的 module 怎麼是 app 啊,應該是 library 才對啊,果斷改為 library
再跑測試,這下終於成功了
Testing started at 10:55 ...
08/11 10:55:48: Launching testDataFileByMin()
$ adb push /Users/panpf/Workspace/AppSample/library/build/outputs/apk/library-debug-androidTest.apk /data/local/tmp/com.sample.library.test
$ adb shell pm install -t -r "/data/local/tmp/com.sample.library.test"
pkg: /data/local/tmp/com.sample.library.test
Success
Running tests
$ adb shell am instrument -w -r -e debug false -e class com.sample.library.stat.DataFileTest#testDataFileByMin com.sample.library.stat.test/android.support.test.runner.AndroidJUnitRunner
Client not ready yet..
Started running tests
Tests ran to completion.
複製程式碼
總結
1. 究竟是什麼導致的 “Empty test suite.”
根本原因是測試用例的配置指向了 app module,而測試用例程式碼是在 library module 中,當然會找不到
2. 為什麼在測試用例中右鍵選擇 “Run ***” 執行測試用例預設會指向 app module
目前還沒找到具體的答案,但肯定這是 Android Studio 的一個BUG
3. 為什麼另一個專案中同樣的方式可以執行,沒有被指向 app module
這個問題尚未找到準確的答案,但 AppSample 與另一個專案的區別是 前者 app 和 library 都配置了測試,而後者只有 library module 配置了測試
我試著完全按照這樣的結構寫了一個demo,檢視重現此問題,很遺憾無法復現。如果你也遇到了這個問題,不妨參考一下我的解決辦法,也許會有用
4. 得到的經驗
- 首先工具也會出錯,但是出了問題還是要首先懷疑自己,證明自己各方面無誤後再去檢視證明是工具出錯了
- 其次一定要注意檢視控制檯輸出的資訊,像 Android Sutido 這麼完善的工具執行結果不管成功過還是失敗都會在控制檯輸出相應的資訊,有時候你 Google 了半天的問題,控制檯早已給出了原因以及解決辦法
- 最後切記勿燥,要有耐心