Android自动化测试-从入门到入门(2)Testing APIs

GeneCowles 9年前

来自: http://segmentfault.com/a/1190000004342951


根据该系列文章的第一篇:Hello Testing,大家已经对整个自动化测试运行流程有了一个基本的了解,接下来我们该集中精力关注具体的脚本实现了!在具体实现之前,我们先来了解一下Android提供的对于自动化测试的一些支持。

AndroidJUnitRunner

根据Android官网的说法,

The AndroidJUnitRunner class is a JUnit test runner that lets you run JUnit 3 or JUnit 4-style test classes on Android devices, including those using the Espresso and UI Automator testing frameworks. The test runner handles loading your test package and the app under test to a device, running your tests, and reporting test results. This class replaces the InstrumentationTestRunner class, which only supports JUnit 3 tests.

AndroidJUnitRunner是一个可以用来运行JUnit 3JUnit 4样式的测试类的Test Runner,并且同时支持EspressoUI Automator。这是对于之前的InstrumentationTestRunner的一个升级,如果你去查看Gradle文档中对于Testing配置的说明,会发现推荐的Test Runner为InstrumentationTestRunnerInstrumentationTestRunner只支持JUnit 3样式的测试用例,而我们在写Android测试用例时应该尽可能使用JUnit 4样式来实现。

相对于Junit 3JUnit 4有如下改进:

  • 测试类不需要再继承junit.framework.TestCase类;

  • 测试方法名不再需要以test开头;

  • 可以使用类似@Test, @Before, @After等注解来管理自己的测试方法;

  • 增加了一些Assert方法;

  • 支持对assert方法的static导入。

下面来看一个例子。如下的代码段采用了JUnit 4风格进行编写,并且调用了Espresso的API来进行了一些测试:

@RunWith(AndroidJUnit4.class)  @LargeTest  public class MainActivityInstrumentationTest {        @Rule      public ActivityTestRule mActivityRule = new ActivityTestRule<>(              MainActivity.class);        @Test      public void sayHello(){          onView(withText("Say hello!")).perform(click());          onView(withId(R.id.textView)).check(matches(withText("Hello, World!")));      }  }

从以上代码可以看到,JUnit 4支持使用如下注解来管理整个测试用例:

  • @Before: 标识在运行测试方法之前运行的代码。可以支持同一个Class中有多个@Before,但是这些方法的执行顺序是随机的。该注解替代了JUnit 3中的setUp()方法。

  • @After: 标识在运行测试方法结束之后运行的代码。可以在其中做一些释放资源的操作。该注解替代了JUnit 3中的tearDown()方法。

  • @Test: 标识一个测试方法。一个测试类中可以有多个测试方法,每个测试方法需要用一个@Test注解来标识。

  • @Rule: 简单来说,是为各个测试方法提供一些支持。具体来说,比如我需要测试一个Activity,那么我可以在@Rule注解下面采用一个ActivityTestRule,该类提供了对相应Activity的功能测试的支持。该类可以在@Before@Test标识的方法执行之前确保将Activity运行起来,并且在所有@Test@After方法执行结束之后将Activity杀死。在整个测试期间,每个测试方法都可以直接对相应Activity进行修改和访问。

  • @BeforeClass: 为测试类标识一个static方法,在测试之前只执行一次。

  • @AfterClass: 为测试类标识一个static方法,在所有测试方法结束之后只执行一次。

  • @Test(timeout=<milliseconds>): 为测试方法设定超时时间。

Instrumentation

根据官方的说法,

Android instrumentation is a set of control methods or hooks in the Android system. These hooks control an Android component independently of its normal lifecycle. They also control how Android loads applications.

Android Instrumentation提供了一些方法,可以用来独立地控制某个组件的生命周期。

一般来说,Android中组件的生命周期是由系统来控制的。比如,我们启动了一个Activity,那么Activity的生命周期方法会自动为我们调用,Android APIs并没有提供入口让我们直接去调用这些生命周期方法,但是使用Instrumentation就可以做到。

Instrumentation可以将要测试的APP以及其对应的test Package加载到同一个进程中。由于我们所要测试的组件和其测试用例都运行在同一进程,因此我们就可以在我们的测试用例中直接调用组件的方法,对组件做一系列访问和修改。

Android Testing Support Library APIs

Android为自动化测试提供了如下的API供我们使用:

  • AndroidJUnitRunner: 以上已经提到;

  • Espresso: 提供了UI测试的API;

  • UI Automator: 提供了跨APP UI测试的API。

EspressoUI Automator会在接下来的文章中详细说明。

Assertion

在做测试的过程中,我们应该如何检查实际的结果符合我们的预期呢?

这里就要用到了Assertion ClassesAssertion Classes提供了一系列assert方法用来比对我们检测的数据和期望的数据是否一致,如果检测失败,则会抛出一个AssertionException异常。

比方说在上一篇文章中贴出来的AppStartActivityTest代码中,有这么一行:

assertNotNull("AppStartActivity Content is Null", content);

这一行代码就是检查content的内容不为空。其中第一个参数指定了一个提示文案,第二个参数指定了需要测试的字符串。

为了简化我们的测试代码,在之后的测试中,我们还会使用到一个叫做Hamcrest的类库,用来简化我们的Assertion过程。这些都将会在接下来的文章中一一介绍。