创建单元测试

编写:huanglizhuo - 原文:http://developer.android.com/training/activity-testing/activity-unit-testing.html

Activity单元测试可以快速且独立地(和系统其它部分分离)验证一个Activity的状态以及其与其它组件交互的正确性。一个单元测试通常用来测试代码中最小单位的代码块(可以是一个方法,类,或者组件),而且也不依赖于系统或网络资源。比如说,你可以写一个单元测试去检查Activity是否正确地布局或者是否可以正确地触发一个Intent对象。

单元测试一般不适合测试与系统有复杂交互的UI。我们应该使用如同测试UI组件所描述的ActivityInstrumentationTestCase2来对这类UI交互进行测试。

这节内容将会讲解如何编写一个单元测试来验证一个Intent是否正确地触发了另一个Activity。由于测试是与环境独立的,所以Intent实际上并没有发送给Android系统,但我们可以检查Intent对象的载荷数据是否正确。读者可以参考一下示例代码中的LaunchActivityTest.java,将它作为一个例子,了解完备的测试用例是怎么样的。

注意: 如果要针对系统或者外部依赖进行测试,我们可以使用Mocking Framework的Mock类,并把它集成到我们的你的单元测试中。要了解更多关于Android提供的Mocking Framework内容请参考Mock Object Classes

编写一个Android单元测试例子

ActiviUnitTestCase类提供对于单个Activity进行分离测试的支持。要创建单元测试,我们的测试类应该继承自ActiviUnitTestCase。继承ActiviUnitTestCase的Activity不会被Android自动启动。要单独启动Activity,我们需要显式的调用startActivity()方法,并传递一个Intent来启动我们的目标Activity

例如:

  1. public class LaunchActivityTest
  2. extends ActivityUnitTestCase<LaunchActivity> {
  3. ...
  4. @Override
  5. protected void setUp() throws Exception {
  6. super.setUp();
  7. mLaunchIntent = new Intent(getInstrumentation()
  8. .getTargetContext(), LaunchActivity.class);
  9. startActivity(mLaunchIntent, null, null);
  10. final Button launchNextButton =
  11. (Button) getActivity()
  12. .findViewById(R.id.launch_next_activity_button);
  13. }
  14. }

验证另一个Activity的启动

我们的单元测试目标可能包括:

  • 验证当Button被按下时,启动的LaunchActivity是否正确。
  • 验证启动的Intent是否包含有效的数据。

为了验证一个触发Intent的Button的事件,我们可以使用getStartedActivityIntent()方法。通过使用断言方法,我们可以验证返回的Intent是否为空,以及是否包含了预期的数据来启动下一个Activity。如果两个断言值都是真,那么我们就成功地验证了Activity发送的Intent是正确的了。

我们可以这样实现测试方法:

  1. @MediumTest
  2. public void testNextActivityWasLaunchedWithIntent() {
  3. startActivity(mLaunchIntent, null, null);
  4. final Button launchNextButton =
  5. (Button) getActivity()
  6. .findViewById(R.id.launch_next_activity_button);
  7. launchNextButton.performClick();
  8. final Intent launchIntent = getStartedActivityIntent();
  9. assertNotNull("Intent was null", launchIntent);
  10. assertTrue(isFinishCalled());
  11. final String payload =
  12. launchIntent.getStringExtra(NextActivity.EXTRAS_PAYLOAD_KEY);
  13. assertEquals("Payload is empty", LaunchActivity.STRING_PAYLOAD, payload);
  14. }

因为LaunchActivity是独立运行的,所以不可以使用TouchUtils库来操作UI。如果要直接进行Button点击,我们可以调用perfoemClick()方法。

本节示例代码AndroidTestingFun.zip