单元测试简介和使用

1. 单元测试的作用:

许多开发者都有个习惯,常常不乐意去写个简单的单元测试程序来验证自己的代码。对自己的程序一直非常有自信,或存在侥幸心理每次运行通过后就直接扔给测试组测试了。然而每次测试组的BUG提交过来后就会发现自己的程序还存在许多没有想到的漏洞。但是每次修改好BUG以后还是怀着侥幸心理,认为这次不会有bug了。然后又一次自信地提交,结果又败了。其实在项目开发的过程中,实际编程的时间并不是特别多,而真正耗时的往往是调试和修改阶段。因此单元测试的覆盖是很有必要的。

一般认为,单元测试有四种作用:
(1)使代码可以放心修改和重构;
(2)迫使程序员从调用者而不是实现者的角度设计软件模块;
(3)迫使程序员将软件模块写得易于测试和调用,从而有利于解耦;
(4)测试本身可作为被测代码的用法说明,从而替代了一部分文档功能。

2. JUnit单元测试框架:

2.1. 简介:

JUnit 是一个开源测试框架,用于编写和运行可重复的自动化测试,让我们可以确保我们的代码按预期工作。 JUnit 广泛应用于行业,可以用作单独的Java程序(在命令行)或在一个IDE如Eclipse内。 JUnit提供:

  • 断言测试预期结果.
  • 测试功能共享通用的测试数据.
  • 测试套件轻松地组织和运行测试.
  • 图形和文本测试运行.

2.2. 简单使用:

2.2.1 下载安装

目前为止最新的版本是JUnit4,很多IDE都会集成进去。如果没有可以下载这两个包导入

2.2.2.  JUnit的注释

2.2.3. JUnit的断言

2.2.4. 简单示例

Caculate.java:

public class Caculate {
    int add(int numberA, int numberB){
        return numberA + numberB;
    }
}

CaculateTest.java:

import static org.junit.Assert.assertEquals;

import org.junit.Before;
import org.junit.Test;

public class CaculateTest {

    private Caculate caculate;

    @Before
    public void init(){
        if(caculate == null){
            caculate = new Caculate();
        }
    }

    @Test
    public void testAdd(){
        int result = caculate.add(5, 3);
        assertEquals(8, result);
    }  
}

右键点击CaculateTest.java的Run as --> JUnit Test:

3. Android中的单元测试

3.1. Android单元测试框架

Android基于JUnit专门写了一套测试框架(Instrumented Test), 用于支持其单元测试和验收测试.  类继承关系:

3.2. 简单示例

用这套框架可以不使用JUnit的注解,直接在要测试的方法前面带上test前缀就可以。我们按需要继承这些基类就可以编写自己所需要的单元测试。Android studio的项目会自动生成一个src/androidTest/java文件夹,单元测试类就放在这个文件夹下面,目录结构如下:

在src/main/java/com/junittest包下新建一个MainActivity.java, 里面有一个按钮和一个文本,点击按钮后可以改变文本内容。

public class MainActivity extends Activity {

    private TextView mTextView;

    private Button mSubmitButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        mTextView = (TextView) findViewById(R.id.hello_text);
        mSubmitButton = (Button) findViewById(R.id.submit_button);
        mSubmitButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mTextView.setText("Change from Click!");
            }
        });
    }

    public String getTextString(){
        if(mTextView != null){
            return mTextView.getText().toString();
        }
        return "";
    }
}

在src/androidTest/javacom/junittest包下新建一个MainActivityTest.java, MainActivityTest继承InstrumentationTestCase:

package com.junittest;

import android.content.Intent;
import android.test.InstrumentationTestCase;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;

/**
 * Created by caihanyuan on 15-10-28.
 */
public class MainActivityTest extends InstrumentationTestCase {

    final static String TAG = MainActivityTest.class.getName();

    private MainActivity mActivity;

    private TextView mTextView;

    private Button mButton;

    /**
     * 单元测试开始之前处理一些初始化工作
     * @throws Exception
     */
    @Override
    protected void setUp() throws Exception {
        Intent intent = new Intent();
        intent.setClassName("com.junittest", MainActivity.class.getName());
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        mActivity = (MainActivity) getInstrumentation().startActivitySync(intent);
        mTextView = (TextView) mActivity.findViewById(R.id.hello_text);
        mButton = (Button) mActivity.findViewById(R.id.submit_button);
    }

    /**
     * 单元测试结束后处理一些资源释放工作
     * @throws Exception
     */
    @Override
    protected void tearDown() throws Exception {
        mActivity.finish();
        super.tearDown();
    }

    public void testInit() {
        assertNotNull(mActivity);
        assertNotNull(mTextView);
        assertNotNull(mButton);
    }

    public void testGetText() {
        String textString = mActivity.getTextString();
        assertEquals("Hello World!", textString);
    }

    public void testChangeText() {
        assertNotNull(mTextView);
        getInstrumentation().runOnMainSync(new Runnable() {
            @Override
            public void run() {
                mTextView.setText("ATest");
                assertEquals("ATest", mActivity.getTextString());
            }
        });
    }

    public void testClickButton(){
        assertNotNull(mButton);
        getInstrumentation().runOnMainSync(new Runnable(){
            @Override
            public void run() {
                mButton.performClick();
                assertEquals("Change from Click!", mActivity.getTextString());
            }
        });
    }

    public void testGetActivity() {
        Log.d(TAG, mActivity.getPackageName());
    }
}

测试结果:

由于篇幅有限,这里只是做简单的介绍,Android测试框架的各个基类的用途可以参考官网。

3.3. 单元测试框架Robolectric

Robolectric is a framework that allows you to write unit tests and run them on a desktop JVM while still using Android API. Robolectric mocks part of the Android framework contained in the android.jar file. This is similar to the unit test support via the Android Gradle plug-in but Robolectric provides also implementations for the methods while the Android unit testing support throws exceptions in all in android.jar methods which are used for unit testing.

因此Robolectric的设计目的是让我们能在本地JVM上直接进行Android的单元测试,这样就不用等待Android真机或模拟器中打包,安装,运行的过程。大大提高了单元测试的效率。

Robolectric的介绍和使用篇幅比较长,这里就不写出来了。参考文献中附有相关的资料,感兴趣的同学可以看看哦。

参考文献:

单元测试的好处:http://www.blogjava.net/square/articles/158103.html

Junit官网:http://junit.org/

Android单元测试: http://developer.android.com/intl/zh-cn/training/activity-testing/index.html

Robolectric官网:http://robolectric.org/

时间: 2024-10-17 14:02:05

单元测试简介和使用的相关文章

TDD学习笔记【二】---单元测试简介

大纲 Testing 的第一个切入点:单元测试. 本篇文章将针对单元测试进行简介,主要内容包含了5W: Why What Where Who When 而How 的部分,属于实现部分,将于下一篇文章介绍工具与简单的范例. 最后会提到测试用例所代表的意义与其重要性. 前言 单元测试,是开发人员最该写的测试程序,却也是最容易被忽略的测试. 大家常碰到的测试相关问题是: 往往一堆人写测试程序时,自以为是在写单元测试,却压根就不是单元测试,而是集成测试. 生产代码是我写的,如果测试程序也是我写,那有什么

使用catch做单元测试简介

开始使用catch呢! catch的好处是,它只有一个头文件, 坏处是,它需要C++11,不过不是很坏. catch有两种测试用例的书写方式: Normal unsigned int Factorial( unsigned int number ) { return number < 1 ? 1 : Factorial(number-1)*number; } TEST_CASE( "Factorials are computed", "[factorial]"

Visual Studio 2005 自带单元测试

一 单元测试简介 单元测试是代码正确性验证的最重要的工具,也是系统测试当中最重要的环节.也是唯一需要编写代码才能进行测试的一种测试方法.在标准的开发过程中,单元测试的代码与实际程序的代码具有同等的重要性.每一个单元测试,都是用来定向测试其所对应的一个单元的数据是否正确. 单元测试是由程序员自己来完成,最终受益的也是程序员自己.可以这么说,程序员有责任编写功能代码,同时也就有责任为自己的代码编写单元测试.执行单元测试,就是为了证明这段代码的行为和我们期望的一致. 单元测试还具有一下几个好处:  能

如何编写单元测试

如何编写单元测试 燕双龙 一 单元测试简介 单元测试是代码正确性验证的最重要的工具,也是系统测试当中最重要的环节.也是唯一需要编写代码才能进行测试的一种测试方法.在标准的开发过程中,单元测试的代码与实际程序的代码具有同等的重要性.每一个单元测试,都是用来定向测试其所对应的一个单元的数据是否正确. 单元测试是由程序员自己来完成,最终受益的也是程序员自己.可以这么说,程序员有责任编写功能代码,同时也就有责任为自己的代码编写单元测试.执行单元测试,就是为了证明这段代码的行为和我们期望的一致. 单元测试

PHP单元测试使用手册

1 单元测试简介 1.1 单元测试 单元测试:是指对软件中的最小可测试单元进行检查和验证.(单一模块.一个过程.一个函数等) 1.2 单元测试范围和目标 单元测试包含计划阶段.设计阶段.实现阶段和执行阶段.起始于详细设计,主要是各模块的源代码进行测试,直到单元阶段结束后终止.此时主要是PHP单元测试. 单元测试的目标是隔离程序部件并证明这些单个部件是正确的.一个单元测试提供了代码片断需要满足的严密的书面规约. 2 安装与使用 2.1 安装PHPUnit 1.在Linux中下载PHPUnit  w

单元测试 + UI测试

一. 单元测试 简介: 单元测试, 又称模块测试, 是针对程序模块的最小单位来进行测试. 对于过程化变成来说, 一个单元就是单个函数 \ 过程等; 对于面向对象变成来说, 一个单元就是一个方法. 有了单元测试, 我们不需要每次都com+R 启动我们的程序,对于大的项目来说, 启动一次项目都会花费很长时间, 这时使用单元测试, 就方便了很多; 使用: 1.  添加测试文件 a.在创建项目的时候, 可以直接勾选include Unit Test b.项目已存在, 可添加: File -> New -

JUnit单元测试教程(翻译自Java Code Geeks)

JUnit单元测试教程--终极指南 JUnit单元测试教程终极指南 说明 单元测试简介 1 什么是单元测试 2 测试覆盖 3 Java中的单元测试 JUnit简介 1 使用Eclipse实现简单JUnit测试例子 使用Eclipse实现完整的JUnit例子 1 创建工程 2 创建要被测试的Java类 3 创建并运行JUnit测试用例 4 使用Ignore注解 5 创建测试套件suite tests 6 创建参数化测试parameterized tests 7 规则Rules 8 策略Catego

iOS 单元测试- Xcode 7测试工具XCTest学习

1. 单元测试简介 1.1.Unit Testing: 单元测试 测试这个词很容易理解,那么什么是单元(Unit)呢? 一个单元指的就是应用程序中可以测试的最小单元. 一组源代码可以测试,一般要求有明确的输入与输出.因此一般来说源代码中明确的包含输入输出的每一个方法被认为一个测试的单元(一个case). 注意,这里的输出并不局限于方法的返回值对输入参数的改变,也包括方法在执行过程中改变的任何数据. 单元测试在程序里面可以理解一个模块一个方法,在每个可能存在的模块都进行测试,确保每个模块都没有问题

好代码是管出来的——.Net Core中的单元测试与代码覆盖率

测试对于软件来说,是保证其质量的一个重要过程,而测试又分为很多种,单元测试.集成测试.系统测试.压力测试等等,不同的测试的测试粒度和测试目标也不同,如单元测试关注每一行代码,集成测试关注的是多个模块是否能正常的协同工作. 当我们在衡量代码好坏时,其中一点就是这些代码是否进行了单元测试,测试的质量.代码覆盖率怎么样?本文将从以下几个方面介绍.Net Core中的单元测试: 单元测试简介 .Net Core中的单元测试框架 使用xUnit.Net对.Net Core应用进行单元测试 创建xUnit.