实际上,TestCase这个类用于在Android担当所有独特的TestCase的基类的作用,它是一个Abstract Class。Android单元测试类继承关系图如下所示:
之所以有那么多XXXTestCase主要是为了简化工作。例如当你想对一个访问数据库的功能进行测试时,首先需要自己启动并初始化数据库。在这里是类似的,如果你想测试一个Activity,首先要启动它。而ActivityTestCase就会自动帮你做完这些事情。而ActivityUnitTestCase会更注重测试的独立性,它会让测试与Android底层的联系降到最低。其余的类可以查看相关的Javadoc来按需挑选。要编写测试,就是找到合适的XXXTestCase作为基类来继承,并且编写自己的测试方法。
很明显的,最简单的编写测试的方法就是继承AndroidTestCase写一个自己的TestCase。然后为自己的一组TestCase写一个Activity界面,由界面控制TestCase的启动,运行和结果报告。但是,你很快会发现,为何要给测试写一个界面呢?这太诡异了。这时就需要一种技术,它可以利用命令行(Shell)来启动一组测试,并且通过命令行的形式给出结果。这就是所谓的Instrumentation。
什么是Instrumentation?
一般在开发Android程序的时候,需要写一个manifest文件,其结构是:
<application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".TestApp" android:label="@string/app_name"> …… </activity> </application> |
这样,在启动程序的时候就会先启动一个Application,然后在此Application运行过程中根据情况加载相应的Activity,而Activity是需要一个界面的。但是Instrumentation并不是这样的。你可以将Instrumentation理解为一种没有图形界面的,具有启动能力的,用于监控其他类(用Target Package声明)的工具类。任何想成为Instrumentation的类必须继承android.app.Instrumentation。下面是这个类的解释:
Base class for implementing application instrumentation code. When running with instrumentation turned on, this class will be instantiated for you before any of the application code, allowing you to monitor all of the interaction the system has with the application. An Instrumentation implementation is described to the system through an AndroidManifest.xml's <instrumentation> tag.
对于单元测试,我们需要认真了解的就是android.test.InstrumentationTestRunner类。这是Android单元测试的主入口。它相当于JUnit当中TestRunner的作用。
那么如何加载它呢,首先要在manifest文件中加入一行关于Instrumentation的声明。比如Android Api Demos中的测试里的manifest是这么写的(我滤掉了所有的注释):
<manifest xmlns:android=" http://schemas.android.com/apk/res/android" package="com.example.android.apis.tests"> <application> <uses-library android:name="android.test.runner" /> </application> <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.example.android.apis" android:label="Tests for Api Demos."/> </manifest> |