单元测试JUnit 4

简述:

在实际项目开发中,都是需要写成千上万个方法或函数,这些函数的功能可能很强大,也可能是很小一个功能,但在程序中使用时都是需要经过测试的,保证这一部分功能是正确的。所以,每编写完一个函数之后,都应该对这个函数的方方面面进行测试,这样的测试称之为单元测试。JUnit 4 是其中一种的单元测试框架


JUnit 4 注解
@Before 标注setup方法,每个单元测试用例方法调用之前都会调用
@After 标注teardown方法,每个单元测试用例方法调用之后都会调用
@Test 标注的每个方法都是一个测试用例
@BeforeClass 标注的静态方法,在当前测试类所有用例方法执行之前执行
@AfterClass 标注的静态方法,在当前测试类所有用例方法执行之后执行
@Test(timeout=) 为测试用例指定超时时间

JUnit断言
assertTrue(condition) condition为真pass,否则fail
assertFalse(condition) condition为假pass,否则fail
fail() 直接fail
assertEquals(expected, actual) expected equal actual pass,否则fail
assertSame(expected, actual) expected == actual pass,否则fail


测试筛选
@RequiresDevice 指定测试仅在物理设备而不在模拟器上运行
@SdkSupress 禁止在低于给定级别的 Android API 级别上运行测试
例如,@SdkSupress(minSdkVersion=18)
@SmallTest、@MediumTest和@LargeTest 指定测试的运行时长以及运行频率


系统:Windows 7 64bit

Android 系统:Android Studio 3.0.0.18

本文将简单介绍本地单元测试以及设备单元测试,且都是没有与界面交互的。

1、本地单元测试Local Unit Tests


测试运行在本地开发环境的Java虚拟机上,无需连接Android设备或模拟器。

因此,无法获得Android相关的API,只能测试只使用Java API的一些功能。

1 > 首先,在AS 3.0中新建一个项目“LocalUnitTest”,创建方法参考Android Studio安装与配置第3项

2 > 项目创建完成后,project面板中默认为Android,将其切换为Project


展开app,查看目录结构。从目录结构中可以看到,除了main文件夹外,还有两个文件夹androidTest和test。这两个都是Android Studio自动生成的,也是用来编写测试代码的。为了学习,先将相关的全部删掉,只保留main文件夹需要的。

3 > 首先在app目录的 build.gradle文件中添加下面的引入,根据提示点击Sync Now

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    //implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    //JUnit 4 framework
    testImplementation 'junit:junit:4.12'
    //androidTestImplementation 'com.android.support.test:runner:1.0.1'
    //androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}

4 > 在项目中新建一个Calculation 类,并添加一些需要的测试的函数,如add,multiply




5 > 添加测试方法,选中add → 鼠标右键 → Go To → Test → Create New Test



6 >Testing library 选择JUnit4 ,同时选中待测试的方法,点击OK




选择目录为...\app\src\test\java...,点击OK。



可以看到,Android Studio已经生成了测试类,完善测试类


package com.hebbe.localunittest;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import static org.junit.Assert.*;

/**
 * Created by Hebbe on 2018/1/13.
 */
public class CalculationTest {
    Calculation calculation;
    @BeforeClass
    public  static void start() throws  Exception {
        System.out.println("类运行时调用一次");
    }

    @AfterClass
    public  static  void  end() throws Exception {
        System.out.println("类结束时调用一次");
    }

    @Before
    public  void before() throws Exception{
        calculation = new Calculation();
        System.out.println("每个test方法前都会调用");
    }

    @After
    public void  after() throws Exception {
        System.out.println("每个test方法后都会调用");
    }

    @Test
    public void add() throws Exception {
        System.out.println("test add");
        int r = calculation.add(2,3);
        Assert.assertEquals(5,r);
    }

    @Test
    public void multiply() throws Exception {
        System.out.println("test multiply");
        int r = calculation.multiply(2,3);
        Assert.assertEquals(6,r);
    }

}

7 > 测试运行效果

直接在测试类上单击鼠标右键 → 选择 Run 'CalculationTest'




运行结果:



如果把add测试方法中expected值改为6,再运行,便可看到错误信息




2、设备单元测试 Instrumented Unit Tests

此测试需要连接Android设备或模拟器。可使用Android API,比如测试需要访问设备信息(如目标应用程序的上下文中)或若需要一个Android 相关的API(如Parcelable或SharedPreferences对象)。该测试类必须以 @RunWith(AndroidJUnit4.class)注解作为前缀。

1 > 首先,在AS 3.0中新建一个项目“InstrumentedUnitTest”,创建方法参考Android Studio安装与配置第3项。

同时删除自动生成的一些文件,最终目录结构如下:




2 > 在app目录的build.gradle文件中添加下面的引入,根据提示点击Sync Now

android {
    defaultConfig {
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
}

dependencies {
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}

3 > 在main文件夹中新建一个Config类,编写待测试的方法。



增加几个方法模拟通过SharedPreferences保存数据


package com.hebbe.instrumentedunittest;

import android.content.Context;
import android.content.SharedPreferences;

/**
 * Created by Hebbe on 2018/1/15.
 */

public class Config {
    private static SharedPreferences sharedPreferences;
    private static SharedPreferences.Editor editor;
    private static Config instance;

    private Config(Context context) {
        sharedPreferences = context.getSharedPreferences("test",Context.MODE_PRIVATE);
        editor =sharedPreferences.edit();
    }

    public static Config getInstance(Context context){
        if (instance == null) {
            synchronized (Config.class){
                if (instance == null){
                    instance = new Config(context.getApplicationContext());
                }
            }
        }
        return instance;
    }

    /**
     * 模拟待测试方法,通过SharedPreferences保存userId
     *
     * @param userId
     */
    public static void setUserId(String userId){
        editor.putString("userId",userId);
        editor.commit();
    }

    /**
     * 模拟待测试方法,通过SharedPreferences读取userId
     *
     * @return
     */
    public static String getUserId(){
        return sharedPreferences.getString("userId","");
    }
}

SharedPreferences是Android平台上一个轻量级的存储类,用来保存应用的一些常用配置。

获取SharedPreferences的两种方式:

调用Context对象的getSharedPreferences()方法:

此方法获得的SharedPreferences对象可以被同一应用程序下的其他组件共享。

调用Activity对象的getPreferences()方法:

此方法获得的SharedPreferences对象只能在该Activity中使用。

SharedPreferences的四种操作模式:
Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容。
Context.MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。
Context.MODE_WORLD_READABLE:表示当前文件可以被其他应用读取。
Context.MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。


4 > 生成测试类,在Config类中单击鼠标右键 →Go To →Test →Create New Test




Testing library选择JUnit4,同时在Generate test methods for中同时选中setUserIdgetUserId方法:




选择.../app/src/androidTest/java/...




点击OK,然后可以看到在刚刚选择的目录中生成了测试类ConfigTest





5 > 编写测试类

首先需要在类开始添加注解@RunWith(AndroidJUnit4.class)。与Local Unit Tests相比,多了访问设备信息和测试筛选。

编写测试类:


package com.hebbe.instrumentedunittest;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;

import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.*;

/**
 * Created by Hebbe on 2018/1/15.
 */
@RunWith(AndroidJUnit4.class)
public class ConfigTest {
    private  static String userId;
    @BeforeClass
    public static void setUp(){
        userId = "1002123";
    }

    @Test
    public void setUserId() throws Exception {
        //模拟通过SharedPreferences保存userId
        Context context = InstrumentationRegistry.getTargetContext();
        Config.getInstance(context).setUserId(userId);
    }

    @Test
    public void getUserId() throws Exception {
        //读取保存的数据,对比是否成功
        Context context = InstrumentationRegistry.getTargetContext();
        String id = Config.getInstance(context).getUserId();
        assertEquals(userId,id);
    }

}


6 > 测试运行效果

直接在测试类上单击鼠标右键 → 选择 Run 'ConfigTest',选择模拟器






从结果上看,测试是通过了的:





猜你喜欢

转载自blog.csdn.net/hebbely/article/details/79051601