JUnit学习笔记(一)

4 篇文章 0 订阅
1 篇文章 0 订阅

前言

在慕课网上听了一位老师的JUnit的基础讲解,感觉对于新人来说还是很友好,故总结下来做此笔记

什么是单元测试

你的程序主要是由一个个的 Class 组成的,一个类或一个对象当然也是一个单元,而比类更小的单元是类的方法(函式)。如果你的类中的基本单元——如某些方法不能正常工作,在某些输入条件下会得出错误的执行结果,那么如何保证你的类/对象乃至整个应用软件或系统作为一个整体能正常工作呢?所以,简单说,单元测试(优先)的目的就是首先保证一个系统的基本组成单元、模块(如对象以及对象中的方法)能正常工作。

为什么要进行单元测试

看上去像是增加了代码量,毕竟光是业务代码就已经花了我们大部分时间精力,但是实际上却是减少了我们之后可能对代码修改的几率,尽可能的实现我们一次性编写就能成功的这个梦想。

工具

本次笔记采用JUnit4来进行测试。JUnit4比起JUnit3而言使用起来更加容易方便,而且目前为止要比JUnit5稳定,网上的参考文档也更多。编译器采用的eclipse。

什么是JUnit

基于测试驱动开发的测试框架,是xUnit系列的一个子系列。说简单点就是一个用于java测试的工具箱,里面有很多方法和规范可以供我们直接使用。

官网

官网地址
这里写图片描述

  • 第1条是关于如何在项目中配置JUnit,包括具体的jar包,在maven中的配置之类的,但由于本次实验所使用的编译器是Eclipse, Eclipse很好的集成了JUnit框架,所以我们也就不用再单独下载。
  • 第2条是提供一套样例,方便初学者依葫芦画瓢。
  • 第3条是下载的JUnit4的版本。
  • 第4条JUnit的java API文档。里面详细讲述了各种方法。
  • 第5条列举了jUnit使用的语法规范
  • 第6条是指第三方扩展。

基本使用步骤

创建被测试类

  1. 在eclipse里新建一个工程,取名JUnitDemo,并新建一个名叫Number的类,包名写上my.demo。这里写图片描述
  2. 给这个Number类里写上一些测试用方法,为了方便我们写加减乘除即可。
public class Number {

    public int add(int a, int b) {
        return a+b;
    }

    public int subtraction(int a ,int b) {
        return a-b;
    }

    public int division(int a,int b) {
        return a/b;
    }

    public int multiplication(int a,int b) {
        return a*b;
    }
}
  1. 先将jUnit所需的jar包引入项目。右键项目->Build Path->Add Libraries。这里写图片描述
    之后会弹出一个框,选择其中的JUnit
    这里写图片描述
    然后选择JUnit4,最后Finish即可。
  2. 创建测试类。为了方便我们以后对测试类进行管理,建议在在和src平级的地方新建一个文件夹叫做“test”,并在里面创建测试代码,test文件里的目录结构和src的建议保持一致。这里写图片描述
    右键被测试类->new->Other这里写图片描述
    之后在文本框中输入junit,然后选中JUnit Test Case
    这里写图片描述
    弹出一个创建框,点击browse按钮选择路径为test包后,点击next
    这里写图片描述
    随后勾选该类,选择所有方法
    这里写图片描述
    测试类就创建完成了
    这里写图片描述

断言

JUnit测试中使用“断言”来进行测试。断言是编写测试用例的核心实现方式,即对比期望值和测试的结果是否相同,以此来判断测试是否通过。断言的核心方法有以下几种

方法名作用
assertArrayEquals(expecteds, actuals)查看两个数组是否相等
assertEquals(expected, actual)查看两个对象是否相等。类似于字符串比较使用的equals()方法
assertNotEquals(first, second)查看两个对象是否不相等
assertNull(object)查看对象是否为空。
assertNotNull(object)查看对象是否不为空。
assertSame(expected, actual)查看两个对象的引用是否相等。类似于使用“==”比较两个对象
assertNotSame(unexpected, actual)查看运行结果是否为true。
assertFalse(condition)查看运行结果是否为false。
assertThat(actual, matcher)查看实际值是否满足指定的条件
fail()让测试失败

注解

注解与注释不同,注释是由“//”等开头,而注解是“@”开头。两者的区别是注解不会对程序本身有任何影响,其作用仅仅是方便我们更好的理解代码。而注解是对程序本身又影响的,它相当于是一个可执行的代码。
JUnit常用注解及其作用有:

注解名作用
@Before初始化方法
@After释放资源
@Test测试方法,在这里可以测试期望异常和超时时间
@Ignore忽略的测试方法
@BeforeClass针对所有测试,只执行一次,且必须为static void
@AfterClass针对所有测试,只执行一次,且必须为static void
@RunWith指定测试类使用某个运行器
@Parameters指定测试类的测试数据集合
@Rule允许灵活添加或重新定义测试类中的每个测试方法的行为
@FixMethodOrder指定测试方法的执行顺序

测试代码的编写

初级使用我们采用assertEquals(excepted, actual)来进行举例。

public class NumberTest {

    @Test
    public void testAdd() {
        assertEquals(5, new Number().add(2, 3));    //判断2+3是不是等于5
    }

    @Test
    public void testSubtraction() {
        assertEquals(4, new Number().subtraction(8, 4));    //判断8-4是不是等于4
    }

    @Test
    public void testDivision() {
        assertEquals(2, new Number().division(10, 5));  //判断10/5是不是等于2
    }

    @Test
    public void testMultiplication() {
        assertEquals(12, new Number().multiplication(3, 4));    //判断3*4是不是等于12
    }

}

如果我们想要测试单独的某个方法,需要右键该方法->Run as->JUnit Test,
如果是想要测试一个类中的全部方法,则右键类名->Run as ->JUnit Test这里写图片描述
之后会出现一个测试窗体,如果全部是绿条,则表明所测试的对象是无误的。测试成功。
这里写图片描述

错误案例

当绿条变成红色的时候,代表测试对象有误,其中包括两种错误,一个是Failure,另一个是Error。Failure的出现代表程序运行的实际值和预期值不符,而Error的出现代表代码本身有误或者有隐藏的bug。
这里我们编写了两个错误代码,一个是测试2+3等不等于4,另一个是测试6/0等不等于3。右边的测试框中显示了测试结果,一个Failure,一个是Error。
Failure方法的错误描述是java.lang.AssertionError: expected:<4> but was:<5>,表示预期是4,但实际值是5.
Error的错误描述是java.lang.ArithmeticException: / by zero。意思是除数不能是0。
这里写图片描述

    @Test
    public void testAdd() {
        assertEquals(4, new Number().add(2, 3));    //判断2+3是不是等于4
    }

    @Test
    public void testDivision() {
        assertEquals(3, new Number().division(6, 0));   //判断6/0是不是等于3
    }

JUnit运行流程

再次新建一个测试类,这次取名为NumberTest2,并勾选框中的四个选项
这里写图片描述
之后会自动生成代码,需要我们手动补充,补充后的代码如下:

public class NumberTest2 {

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        System.out.println("beforeClass()");
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
        System.out.println("afterClass()");
    }

    @Before
    public void setUp() throws Exception {
        System.out.println("before()");
    }

    @After
    public void tearDown() throws Exception {
        System.out.println("after()");
    }

    @Test
    public void test() {
        System.out.println("test()");
    }

    @Test
    public void test2() {
        System.out.println("test2()");
    }

}

执行程序后查看程序执行顺序
这里写图片描述
从以上结果我们得出结论
1. 被@BeforeClass注解修饰的方法第一个执行
2. 被@Before注解修饰的方法会在每个@Test方法执行前执行一次
3. 被@After注解修饰的方法会在每个@Test方法执行后执行一次
4. 被@AfterClass注解修饰的方法最后一个执行
利用以上特性我们可以有效的实现初始化以及结尾清除功能

进阶使用

@Test的两个参数

@Test有两个可控的参数,分别为timeout和expected
新建一个测试类取名为NumberTest3,并在里面添加如下代码

public class NumberTest3 {

    //第一个test()用来阐述timeout参数
    @Test(timeout=1)
    public void test() {
        while(true) {
            System.out.println("running.....");
        }
    }

    //test2()用来阐述excepted参数
    @Test(expected=ArithmeticException.class)
    public void test2() {
        assertEquals(3, new Number().division(6, 0));
    }

}

test()方法中写入的是一个死循环,按照常理来说应该是死循环直到内存溢出,现在我们对test()进行测试,控制台的结果是
这里写图片描述
可以看到,程序自动停止了。这就是timeout参数的作用,规定程序在n毫秒之内结束,如果测试代码没有在n毫秒内结束,在第n毫秒时会强制停止。test()上的timeout规定在了1毫秒,所以死循环也就只执行了1毫秒。

test2()函数中写入的是一个断言,判断6/0是否等于3,按照之前的测试来看,测试应该是报Error,因为除数不能为0,但我们加上expected之后,程序测试结果如下
这里写图片描述
绿条表示测试成功。
expected参数的含义是指期望抛出什么异常(也就是说加上这个参数后,测试的目的就变成了看它是否会抛出指定异常,如果抛出了就是绿条,没抛出指定异常就变红条)

测试套件

测试套件出现的目的是为了方便我们一次运行多个类的测试。加入我们有Test1,Test2,Test3……n个测试类,我们想要全部测试他们的功能,总不可能一个类一个类的去右键点击Run as junit Test吧,因此测试套件的作用就是我们可以只执行一次run as,就可以测试所有的我们想测试的类的测试方法。可以类比工具箱,我们在搬运的时候,肯定不是一件工具一件工具的来回拿放,而是把工具放在工具箱里,一齐进行搬运。
先在test里创建三个测试类,也就是“工具”,里面分别有一个test方法,该方法的内容是打印函数名称
这里写图片描述
最后创建一个“工具箱”
这里写图片描述
注意,这个“工具箱”类里有如下几个特点
1. 这整个类是个空类,什么都不要写,它存在的意义就仅仅只是为了我们一次性进行多类测试
2. 两个注解放在类名上面,且第一个注解里的内容固定为“Suite.class”
3. 第二个注解里的内容是说明具体有哪些“工具”需要被一次性测试。里面放了几个类,就会测试几个。

参数化设置

参数化设置的目的是方便我们进行多组数据测试。
在test里新建一个测试类,取名MultipTest,其代码如下


//该类必须加上注释 @RunWith(Parameterized.class),表示这个类是参数化的测试类
@RunWith(Parameterized.class)
public class MultipTest {

//参数的类型和数量取决于test()方法,这里因为测试的是add()方法
//因此有一个预期值,两个加数,总共三个参数。
    int expected = 0;
    int input1 = 0;
    int input2 = 0;


    public MultipTest(int expected,int input1, int input2) {
        this.expected = expected;
        this.input1 = input1;
        this.input2 = input2;
    }

//JUnit规定了测试数据组必须是一个静态的collection,且里面得是一个数组。
    @Parameters
    public static Collection<Object[]> t(){
        return Arrays.asList(new Object[][] {
            {3,1,2},
            {4,2,2}
            });
    }

    @Test
    public void testAdd() {
        assertEquals(expected, new Number().add(input1, input2));
    }

}

运行结果如图
这里写图片描述
发现有两条数据,这两条数据分别对应我们往collection里放的数据。

资料参考

慕课网 JUnit单元测试
使用junit测试预期异常

  • 13
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
JUnit学习笔记精要》是一本介绍JUnit测试框架的学习资料,可以从CSDN下载。JUnit是一个开源的Java单元测试框架,用于简化和自动化开发者编写和执行单元测试的过程。JUnit学习对于提高代码质量、减少bug的产生以及提高开发效率具有重要意义。 这本《JUnit学习笔记精要》将帮助读者从零开始掌握JUnit的基本概念和用法。书中首先介绍了JUnit的起源和发展历程,让读者了解JUnit的背景和重要性。然后详细讲解了JUnit的安装和配置,帮助读者快速上手使用该测试框架。 接下来,书中深入介绍了JUnit的各种注解和断言方法。JUnit的注解用于标记测试方法,通过使用不同的注解,可以控制测试方法的执行顺序、重复执行次数等。而JUnit的断言方法则用于验证测试结果是否符合预期。书中通过大量的示例代码和实际案例,详细讲解了如何使用这些注解和断言方法。 此外,书中还介绍了如何构建复杂的测试套件、如何使用参数化测试和如何处理异常测试。这些高级主题能够帮助读者进一步提升自己的单元测试技能,实现更全面的测试覆盖和更准确的测试结果。 总之,《JUnit学习笔记精要》是一本系统、实用的学习资料,适合想要学习JUnit的开发者。通过下载这本书,读者可以更好地理解和掌握JUnit的各种概念和用法,提高软件开发的质量和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值