Android中如何简单的做单元测试
2016-11-24 22:51
288 查看
单元测试
单元测试(模块测试)是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的功能是否正确。通常而言,一个单元测试是用于判断某个特定条件(或者场景)下某个特定函数的行为。例如,你可能把一个很大的值放入一个有序list 中去,然后确认该值出现在list 的尾部。或者,你可能会从字符串中删除匹配某种模式的字符,然后确认字符串确实不再包含这些字符了。基于
JUnit来进行测试,包括运行在JVM上的本地单元测试,和运行在Android设备上的Instrumented测试。
JUnit
把单元测试或集成测试类写成JUnit 4测试类。此框架提供了便捷的方法来执行测试中常见的建立(setup),拆除(teardown)和断言(assertion)操作。一个基本的JUnit 4测试类是一个包含一个或多个测试方法的Java类。测试方法应以@Test注解开始,并包含代码执行和验证单一的功能,这通常是待测组件中的一个业务逻辑单元。
一:基本流程
写测试类写测试方法
运行JUnit Test进行测试
二:注解方式
在你的JUnit测试类中,你可以使用下面的注解,来对你测试代码的片段做特殊处理:@Before:使用此注解来指定一段代码为建立(setup)操作。测试类会在每一个测试方法之前调用此代码块。你可以有多个@Before注解的方法,但测试类调用这些方法的顺序无法保证。
@After:使用此注解来指定一段代码为拆除(teardown)操作。测试类会在每一个测试方法之后调用此代码块。同样,你可以在测试代码中定义多个@After操作。使用此注解释放内存资源。
@Test:使用此注解来标注测试方法。一个测试类可以包含多个测试方法,都以此注解开头,返回值为void
@Rule:Rule能以一种可重用的方式,灵活地添加或重定义每一个测试方法的行为。在Android测试中,此注解是和Android Testing Support Library提供的测试规则类结合起来使用,例如ActivityTestRule或者ServiceTestRule。
@BeforeClass:使用此注解标明测试类只会调用一次的静态方法。此步骤对于昂贵的操作(例如连接到数据库)是很有用的。
@AfterClass:使用此注解标明,在所有测试方法执行完毕后,会执行一次的静态方法。这一步骤中,应释放在@BeforeClass代码块中分配的资源。
@Test(timeout=):一些注解支持设置参数。例如,你可以为测试方法指定一个超时时间。如果测试没有在指定时间内介绍,它会自动失败。超时时间以毫秒为单位,例如@Test(timeout=5000)。
执行顺序为:@BeforeClass --> @Before --> @Test --> @After --> @AfterClass
使用JUnit的断言(Assert)类来验证对象状态的正确性。断言方法会比较你预期的值和测试得到的实际值,如果不符则会抛出异常。Assertion classes描述了这些方法的细节。
三:断言方法
常用的断言方法:assertEquals(args):根据传入的参数判断预期结果和实际结果是否相等。
assertTrue/False(args): 判断一个条件为true/false。
assertNotNull/Null(args): 判断一个对象是否为空。
assertSame/NotSame(args): 判断两个对象是否指向同一个对象。
fail(args): 中断测试方法,可以为其设置信息。
四:测试示例
Android studio 默认支持JUnit,创建一个新的项目,项目中自动添加了JUnit的依赖testCompile 'junit:junit:4.12',所以可以直接在Android studio中使用JUnit来进行单元测试。
本地单元测试
运行在本地JVM上的单元测试,主要的测试类在路径src/test下(Project面板视图)。
第一步:项目中的被测试类: 确定一个被测试的类,测试里面的方法运行返回是否符合功能要求,比如在网络请求的时候,测试接口构建是否正确。
// 要被测试的接口或类 public interface RetrofitApi { @GET("https://api.github.com/users/gqq") Call<ResponseBody> getRequest(); @POST("/Handler/UserHandler.ashx?action=register") Call<UserResult> getUserRequest(@Body User user); }
第二步:创建测试类: 确定要被测试的类之后,在test路径下创建相应的测试类和测试方法来进行测试,而更快捷的方式在该类上点击右键菜单--> Go To --> Test(ctrl+shift+T快捷键),自动创建相应的测试类和方法,创建到test路径下
第三步:完善测试类和方法:
测试类和测试方法创建完成之后,在相应的方法中完善测试方法:
public class RetrofitApiTest { private RetrofitApi retrofitApi; // @Before 在测试方法执行之前被调用 @Before public void setUp() throws Exception { retrofitApi = RetrofitClient.getInstance().getRetrofitApi(); } // 测试方法 @Test public void getRequest() throws Exception { ResponseBody body = retrofitApi.getRequest().execute().body(); assertNotNull(body); } // 测试方法 @Test public void getUserRequest() throws Exception { UserResult userResult = retrofitApi.getUserRequest(new User("123", "123")).execute().body(); assertEquals(1,userResult.getCode()); } // 测试完成后执行 @After public void tearDown() throws Exception { } }
第四步:执行测试类及结果: 右键Run "RetrofitApiTest"执行测试类,查看测试的结果。
通过则显示为
OK,未通过展示信息:
java.lang.AssertionError: Expected :1 Actual :2
根据测试未通过信息进行修改。以上就是一次本地单元测试过程。
Instrumented单元测试
虽然在Android框架内支持运行instrumentation测试,但是目前开发重心主要集中在刚刚发布的作为AndroidTesting Support Library一部分的新的AndroidJUnitRunner,测试库包含Espresso,用于运行功能UI测试的框架。
第一步:添加依赖: 在gradle2.2默认添加了对单元测试的支持
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) android { defaultConfig { testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } }
所以不再进行依赖的添加。 没有默认添加依赖的话,需要手动添加以下依赖:
dependencies { androidTestCompile 'com.android.support.test:runner:0.4' // Set this dependency to use JUnit 4 rules androidTestCompile 'com.android.support.test:rules:0.4' // Set this dependency to build and run Espresso tests androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1' // Set this dependency to build and run UI Automator tests androidTestCompile 'com.android.support:support-annotations:24.2.0' } android { defaultConfig { testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } }
具体参见:Testing Support Library Setup
第二步:确定要被测试的具有交互效果的页面:
例如注册页面,实现输入用户名和密码,点击注册按钮执行业务。
@Bind(R.id.et_Username) EditText etUsername; @Bind(R.id.et_Passrword) EditText etPassrword; @OnClick(R.id.btn_Register) public void onClick() { // 执行业务 }
第三步:创建测试类和测试方法: 在要被测试的类中点击右键菜单--> Go To --> Test(ctrl+shift+T快捷键),自动创建相应的测试类和方法,创建到androidTest路径下。
第四步:完善测试类和测试方法:
import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.action.ViewActions.typeText; import static android.support.test.espresso.matcher.ViewMatchers.withId; public class RetrofitPostActivityInstrumentedTest { @Rule public ActivityTestRule<RetrofitPostActivity> activityTestRule = new ActivityTestRule<RetrofitPostActivity>(RetrofitPostActivity.class); @Test public void onClick() throws Exception { onView(withId(R.id.et_Username)).perform(typeText("123456"));// 为id为et_Username的控件输入字符串“123456” onView(withId(R.id.et_Passrword)).perform(typeText("123456"));// 为id为et_Passrword的控件输入字符串“123456” onView(withId(R.id.btn_Register)).perform(click());// 为id为btn_Register的控件设置点击事件 Thread.sleep(3000);// 因为注册为网络请求(耗时操作),所以线程休眠以等待结果。 } }
关于视图的操作方法由Espresso进行,更多API参考Espresso
第五步:执行测试
右键Run "RetrofitPostActivityInstrumentedTest"执行测试类,查看测试。 至此,测试过程结束。
相关文章推荐
- Android、JUnit深入浅出(六)——如何运行单元测试?
- 如何进行Android单元测试
- 如何运行android sdk sample中的单元测试
- 如何使用androidpn实现android手机消息推送(简单的源码分析)
- 如何进行Android单元测试
- 简单介绍如何应用DDMS协助开发Android Apps
- 【Android游戏开发二十一】Android os设备谎言分辨率的解决方案!以及简单阐述游戏引擎如何使用
- 如何进行Android单元测试
- 【Android游戏开发二十一】Android os设备谎言分辨率的解决方案!以及简单阐述游戏引擎如何使用!
- Android、JUnit深入浅出(六)——如何运行单元测试?
- android 简单的单元测试
- 如何进行Android单元测试
- 【Android游戏开发二十一】Android os设备谎言分辨率的解决方案!以及简单阐述游戏引擎如何使用!
- 主题:四,android四大组件基础介绍及打电话,发短信简单应用 &单元测试
- 【Android游戏开发二十一】Android os设备谎言分辨率的解决方案!以及简单阐述游戏引擎如何使用!
- Android中默认不输出stdout stderr,如何输出?最简单的方法
- 【Android游戏开发二十一】Android os设备谎言分辨率的解决方案!以及简单阐述游戏引擎如何使用!
- 在Android项目里如何构建单元测试
- 如何进行Android单元测试
- Android应用开发中如何进行单元测试