51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 1788|回复: 1
打印 上一主题 下一主题

[讨论] Android中如何简单的做单元测试

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2018-2-27 16:01:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
单元测试(模块测试)是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的功能
是否正确。通常而言,一个单元测试是用于判断某个特定条件(或者场景)下某个特定函数的行为。
例如,你可能把一个很大的值放入一个有序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提供的测试规则类结合起来使用,例如ActivityTestR
ule或者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面板视图)。

第一步:项目中的被测试类: 确定一个被测试的类,测试里面的方法运行返回是否符合功能要
求,比如在网络请求的时候,测试接口构建是否正确。
  1. // 要被测试的接口或类
  2. public interface RetrofitApi {

  3. @GET("https://api.github.com/users/gqq")
  4. Call<ResponseBody> getRequest();

  5. @POST("/Handler/UserHandler.ashx?action=register")
  6. Call<UserResult> getUserRequest(@Body User user);
  7. }
复制代码
第二步:创建测试类: 确定要被测试的类之后,在test路径下创建相应的测试类和测试方法来进
行测试,而更快捷的方式在该类上点击右键菜单--> Go To --> Test(ctrl+shift+T快捷键),自动创
建相应的测试类和方法,创建到test路径下


第三步:完善测试类和方法:

测试类和测试方法创建完成之后,在相应的方法中完善测试方法:
  1. public class RetrofitApiTest {

  2.     private RetrofitApi retrofitApi;

  3.     // @Before 在测试方法执行之前被调用
  4.     @Before
  5.     public void setUp() throws Exception {
  6.         retrofitApi = RetrofitClient.getInstance().getRetrofitApi();
  7.     }

  8.     // 测试方法
  9.     @Test
  10.     public void getRequest() throws Exception {
  11.         ResponseBody body = retrofitApi.getRequest().execute().body();
  12.         assertNotNull(body);
  13.     }

  14.     // 测试方法
  15.     @Test
  16.     public void getUserRequest() throws Exception {
  17.         UserResult userResult = retrofitApi.getUserRequest(new User("123", "123")).execute().body();
  18.         assertEquals(1,userResult.getCode());
  19.     }

  20.     // 测试完成后执行
  21.     @After
  22.     public void tearDown() throws Exception {

  23.     }
  24. }
复制代码
虽然在Android框架内支持运行instrumentation测试,但是目前开发重心主要集中在刚刚发布的作为
Android Testing Support Library一部分的新的AndroidJUnitRunner,测试库包含Espresso,用于运行
功能UI测试的框架。

第一步:添加依赖: 在gradle2.2默认添加了对单元测试的支持
  1. androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
  2.     exclude group: 'com.android.support', module: 'support-annotations'
  3. })

  4. android {
  5.     defaultConfig {
  6.         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
  7.     }   
  8. }   
复制代码
所以不再进行依赖的添加。 没有默认添加依赖的话,需要手动添加以下依赖:
  1. dependencies {
  2.     androidTestCompile 'com.android.support.test:runner:0.4'
  3.     // Set this dependency to use JUnit 4 rules
  4.     androidTestCompile 'com.android.support.test:rules:0.4'
  5.     // Set this dependency to build and run Espresso tests
  6.     androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
  7.     // Set this dependency to build and run UI Automator tests
  8.     androidTestCompile 'com.android.support:support-annotations:24.2.0'
  9. }


  10. android {
  11.     defaultConfig {
  12.         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
  13.     }   
  14. }   
复制代码
第二步:确定要被测试的具有交互效果的页面:

例如注册页面,实现输入用户名和密码,点击注册按钮执行业务。
  1. @Bind(R.id.et_Username)
  2. EditText etUsername;
  3. @Bind(R.id.et_Passrword)
  4. EditText etPassrword;

  5. @OnClick(R.id.btn_Register)
  6. public void onClick() {
  7.     // 执行业务
  8. }
复制代码
第三步:创建测试类和测试方法: 在要被测试的类中点击右键菜单--> Go To --> Test(ctrl+shift+T快
捷键),自动创建相应的测试类和方法,创建到androidTest路径下。
第四步:完善测试类和测试方法:
  1. import static android.support.test.espresso.Espresso.onView;
  2. import static android.support.test.espresso.action.ViewActions.click;
  3. import static android.support.test.espresso.action.ViewActions.typeText;
  4. import static android.support.test.espresso.matcher.ViewMatchers.withId;

  5. public class RetrofitPostActivityInstrumentedTest {

  6.     @Rule
  7.     public ActivityTestRule<RetrofitPostActivity> activityTestRule = new ActivityTestRule<RetrofitPostActivity>(RetrofitPostActivity.class);

  8.     @Test
  9.     public void onClick() throws Exception {

  10.         onView(withId(R.id.et_Username)).perform(typeText("123456"));// 为id为et_Username的控件输入字符串“123456”

  11.         onView(withId(R.id.et_Passrword)).perform(typeText("123456"));// 为id为et_Passrword的控件输入字符串“123456”

  12.         onView(withId(R.id.btn_Register)).perform(click());// 为id为btn_Register的控件设置点击事件

  13.         Thread.sleep(3000);// 因为注册为网络请求(耗时操作),所以线程休眠以等待结果。
  14.     }
  15. }
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-4-24 15:40 , Processed in 0.062425 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表