Android测试详解_1-Best Practices for Testing-介绍

时间:2021-07-07 03:24:55

写在前面

英文官方链接
Android测试都是基于JUnit,不管是运行在jvm上的本地单元测试还是运行在android设备上的仪器测试都需要用到它。本篇主要介绍创建android测试的概念和工具。


测试类型

当你使用AS写测试的时候,你的测试必须写到两个不同代码目录(源集)中的一个里面。对于你的项目中每个module,AS都包括了两个源集,对应一下的测试类型:

1.Local unit tests
在目录 module-name/src/test/java/.下
此目录下的测试运行在本地JVM中,不会访问功能性的Android框架API.
具体请看 创建 local unit tests。

2.Instrumented tests
在目录 module-name/src/androidTest/java/.下
此目录下的测试必须运行在Android设备或模拟器上。
Instrumented test 是创建一个apk运行在设备上,在你的apk中测试。这个系统运行你的测试apk,和你的app测试在一同意进程中,所以,你的测试可以调用方法以及修改字段在App中,并且模拟用户自动与app交互.
若想了解如何创建instrumented test ,请看下面几篇本章:

  • 创建 Instrumented unit test:创建复合Android依赖的 unit test,仅仅mock对象是不够的。
  • 自动化用户界面测试(Automating User Interface Tests): 创建测试区验证单一app里的用户交互或是跨多个app的交互的用户界面行为是否正确。
  • 测试app控件集成:验证用户交互没有直接参与的控件行为,如service、content provider。

不管怎样,local unit test 和 instrumented test 描述的都是只是帮助区分运行JVM中的本地测试,以及运行在Android设备中的测试。当你创建一个完整的测试时你需要明白真正的测试类型满足下表的描述。
Android测试详解_1-Best Practices for Testing-介绍

  • 1.单元测试。
    1.1 本地单元测试 这类单元测试运行在jvm中,用这些测试来最小化执行时间,当你的测试没有Android框架依赖或者能mock(模拟)Android框架依赖。
    1.2 仪器单元测试 这类单元测试运行在Android设备中。这类测试需要使用Instrumentation信息,如app的context。当你的测试有Android依赖,并且仅仅依靠mock对象是不能实现的。

  • 2.集成测试。
    2.1 应用内组件 这类测试验证,当用户在activity中执行一个特定的动作或者一个特定的输入时,目标app的行为是否如预期。例如,它允许你检查目标app在响应用户交互时,返回的ui输出是否正确。ui测试框架,像Espresso 可以让你去编程来模仿用户行为,以及复合的应用内的用户交互。
    2.2 跨应用组件 这类测试验证不同app或者不同系统的app的交互是否是正确的行为。例如,你要验证当用户执行Android设置菜单时,你的app行为的正确性。支持cross-app(跨应用)交互的UI测试框架,如UI Automator,可以让你在这样的场景中创建测试。


测试API

JUnit
你应该写单元或集成test class 作为JUnit4的test class。 这个框架提供便捷的方式来执行普通的设置,拆卸,以及判断操作在你的测试中。

一个基本的JUnit4 测试类是一个包含一个或多个测试方法的java类。一个测试方法一@test注解开始,并且包含练习和验证一个单一功能的代码在你想要测试的组件中。

下面的代码片段展示的是一个JUnit4集成测试的例子,用Espresso Api来执行一个点击动作在一个UI元素中,检查是否是预期的字符串显示出来。

@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!")));
}
}

在你的JUnit4测试类中,你能在你的测试代码中的调出特别处理的测试代码块,通过使用下面这些注解:

  • @Before:使用此注解来指定包含测试设置操作的代码块。测试类在任何测试之前调用这个代码块。你可以有多个@Before方法,但是测试类调用它们的顺序是不被保障的。
  • @After:这个注解指定包含卸载操作的代码块。测试类在每个测试方法之后调用这个代码块。你可以定义多个@After操作在你的测试代码中。使用这个注解来释放内存。
  • @Test:使用这个注解来标注一个测试方法。一个单独的测试类可以包含多个带有这个前缀的测试方法。
  • @Rule:Rules 允许你灵活的给添加或重定义每个测试方法的行为,以一个可重复使用的方式。在Android测试中,这个注解与一个由Android测试支持库提供的测试规则类一起使用,例如ActivityTestRule 或 ServiceTestRule。
  • @BeforeClass:使用这个注解来指定每个测试类静态方法,只能调用一次。这一测试步骤作用于昂贵的开销,例如连接一个数据库。
  • @AfterClass:使用这个注解指定测试类的静态方法,只有在这个类的所有测试运行结束后调用。这一测试步骤作用于释放任何在@BeforeClass块中开辟的资源。
  • @Test(timeout=):一些注解支持进入那些你能设置值的元素的能力。例如,你能给测试指定一个超时时间。如果测试开始但是在超时时间内没有完成,它自动的失败。你必须指定毫秒格式的超时时间。eg:@Test(timeout=5000)。

更多注解,请看文档:JUnit AnnotationsAndroid Annotations

使用JUnit的Assert类来验证一个对象状态的正确性。assert方法比较测试中你预期的值与实际结果,如果比较出不同则会抛出异常。更多assert方法详情请看Assertion classes

Android测试支持库
Android Testing Support Library 提供了一系列API,让你能够快速的给你的app创建并运行测试代码,包括JUnit4和功能UI测试。这个库还包括下面的仪器基础API,当你想要自动化测试时这些会很有用:

  • AndroidJUnitRunner JUnit中一个兼用android的测试器。
  • Espresso UI测试框架,适配app的功能UI测试。
  • UI Aotomator UI测试框架,适配系统以及已安装应用之间跨应用的功能UI测试。

    Assertion类
    Android Testing Support Library API 继承自 JUnit,你能使用assertion方法去显示测试结果。一个assertion方法比较测试的实际返回结果与期望值,如果比较出不同则抛出异常。使用assertion比log日志更方便,并且有更好的测试表现。
    简化测试开发,你可以使用 Hamcrest library,使用它的API可以让你更灵活的测试。

Monkey 和 monkeyrunner
Android SDK 为功能级别app测试提供两个工具:
Monkey: 这是一个命令行工具,发送伪随机的敲击、触摸、手势数据流到一个设备。你可以通过adb工具运行它,用它对你的应用进行压力测试,上报遇到的任何错误,或通过运行多次相同随机数,报告一组事件的数据流。

monkeyrunner:这是用Python编写的一个API和运行环境的测试程序。API包括的功能有连接设备、安装或卸载包,截屏,对比两个图片,以及运行与app冲突的测试包。使用这个API,你能写出一个范围广,力量强,复杂的测试。你通过monkeyrunner 命令行工具使用api来 运行程序。

创建Android测试向导

下面的文章更详细的描述如何进行每一种测试类型的创建和运行。

  • Building Local Unit Tests :构建那些没有依赖或是能mock够模拟的简单依赖的单元测试,运行在本地jvm。
  • Building Instrumented Unit Tests :构建那些通过不能mock的Android依赖的复杂的单元测试,运行在设备上。
  • Automating User Interface Tests:创建测试用来验证在一个应用中的用户交互或是跨应用交互时界面行为的正确性。
  • Testing App Compontent Integrations:验证用户没有直接交互的eg.service或是content provider的组件的行为。
  • Testing Display Performance:这个测试用来度量app的UI性能是否流畅。