1. 错误信息

打算在项目中添加单元测试。先找到自动生成的ExampleUnitTest文件里面去运行下,发现死活都是报如下错误

No tests were found
Class not found: "**.logger.ExampleUnitTest"

点击左边的锤子图标进行编译,编译完死活还是报上面的错误。

对照官方文档,找到build.gradle中的单元测试相关依赖,左改右改,点击锤子进行编译,结果还是死活报上面的错误。
新建demo项目,等待项目可以run之后,进入到自动生成的那个单元测试文件,尝试运行,测试通过没问题。从demo中把配置完全迁移到自己的项目,依赖同步,然后点击锤子,依然是报上述错误。

升级编译插件版本、升级gradle…各种尝试,依然未能解决。
多方查阅资料,各种尝试修改build.gradle中的配置信息,尝试修改单元测试的配置信息,最终还是依然报上面的错误…

2. 解决方式及原因

某无意操作后,似乎可以正常跑单元测试了
通过git对比自己的配置文件代码的修改,一个个尝试,删除了所有的修改,还是没找到原因。
在build窗口,选择某个module的build命令,执行后,再去该module右键运行单元测试,成功。
到其他没有build过的module中,右键执行单元测试,还是报那个错误。
继续按照上述方式build该module,单元测试又可以了
检查其他没有build的module里面示例单元测试,依然是报上诉错误。这里猜测该错误就是由于没有build引起的。
android studio的终端执行命令

./gradlew build

build的时间还挺长,等待build完成,检查之前没有build过的module里面的ExampleUnitTest文件能否右键执行单元测试,结果都执行成功。
clean之后点击锤子,继续验证,上面的错误又重现了

抽丝剥茧,我们对比下点击锤子进行编译和执行build命令后,自动生的build目录下的文件

可以看到,在build/tmp/kotlin-classes/目录下,当执行build命令时,目录如下

pytest pytest_runtest_teardown item 结果_android


当点击锤子按钮时,目录结构如下:

pytest pytest_runtest_teardown item 结果_Test_02


可以看出,点击锤子,只有debug这个目录,该目录是编译后的main下的代码

执行build后,多了debugUnitTest, release 以及releaseUnitTest这几个目录,点击进入debugUnitTest目录下,可以找到编译后的ExampleUnitTest文件。

build后,单元测试可以执行,将tmp下的debugUnitTest目录删除,再执行单元测试,发现失败。说明能不能执行单元测试,关键就是看build/tmp/目录下有没有编译好的单元测试文件。
进一步试验,删除了debugUnitTest目录后,releaseUnitTest目录还在,在build variants为debug情况下右键执行单元测试失败。将build variants切换成release,执行单元测试成功。进一步佐证上述结论。

根据上面的试验,我们可以得到如下结论:

  • 单元测试必须build之后才可以执行,build才会编译单元测试的文件,该文件存储在build/tmp目录下
  • 点击那个编锤子图标按钮只会编译main下的代码,不会编译单元测试的代码

这正好和所报的错误信息“No tests were found“符合,确实没有找到该文件,因为确实没有编译测试代码。

浪费了许多时间,笨如我,郁闷!

3. 思考++:较好的编写单元测试代码流程

对于多module的android项目,添加单元测试较好的工作流程如下:
编写单元测试后,点击右边边框上的gradle,打开gradle窗口,选中要编写单元测试的module,到Tasks/build下点击执行build脚本进行构建。这样,单元测试的代码就被编译了。每次修改单元测试的代码之后,都得build下才能完成更改。