单元测试

单元测试概述:

在程序中,一个单元可以时一个完整的模块,但它通常是一个单独的方法或者程序

在面向对象的编程中,一个单元通常是整个界面,例如类,但可能是单个方法

JUnit 是一个Java编程语言的单元测试框架

通过先为最小的可测试单元编写测试,然后编写这些单元之间的复合行为,就可以为复杂的应用程序建立全面的测试

单元测试的优点:

自己编写main方法测试存在的问题:

无法得到测试结果报告,需要程序员自己去观察测试是否成功

如果一个测试方法失败了,其他方法测试会受到影响

无法意见完成全部模块的全部方法的测试

单元测试的优点:

可以生成全部方法的测试报告。如果执行结果是绿色的,那么表明测试通过;如果执行结果是红色的,表明测试不通过

单元测试中,某个方法测试失败了,不影响其他测试方法的测试

可以一键执行全部测试方法

单元测试快速入门

编码约定:

类放在test包中

在test包下创建和原包名相同的包

类名用XxxTest结尾

方法用TestMethod命名

1、和src同级建立test目录,并修改该目录为Test Sources Root

2、在test目录下建包com.itheima

3、在com.itheima包下新建类:MyMathTest

4、在类中编写第一个测试方法:testAdd()

方法修饰符:public void testAdd(){}

5、如何让方法称为Junit中的测试方法呢?

导入junit-4.12.jar和hamcrest-1.3.jar包

然后再方法上添加@Test注解

6、运行测试方法

7、使用断言改进测试方法的运行

参考代码:

//src下的包
package com.itheima;
/*
    自定义的数学类,用于对两个数据加减乘除
 */
public class MyMath {
    public int add(int a, int b){
        return a + b;
    }

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

    public int mul(int a, int b){
        return a * b;
    }

    public int div(int a, int b){
        return a / b;
    }
}
//test文件下的包,注意将test目录右键在Mark Directory as中选择Test Sources Root进行目录修改
package com.itheima;

import org.junit.Test;

public class MyMathTest {

    @Test
    public void TestAdd(){
        MyMath myMath = new MyMath();
        int result = myMath.add(10, 20);
        System.out.println(result);
    }

}

断言

断言:其实就是判断

Junit测试框架中Assert类就是实现断言的工具,主要作用如下:

单元测试用于判断某个特定条件下某个方法的行为

执行单元测试为了证明某段代码的执行结果是否与期望的一致

查看两个对象是否相等,类似于字符串比较使用的equals()方法

public static void assertEquals(Object expected, Object actual)
		public static void assertNotEquals(Object unexpected, Object actual)

使用断言改进测试方法:

//与前面参考代码使用同一个src所以没有写出src内容
package com.itheima;

import org.junit.Assert;
import org.junit.Test;

public class MyMathTest {

//    @Test
//    public void TestAdd(){
//        MyMath myMath = new MyMath();
//        int result = myMath.add(10, 20);
//        System.out.println(result);
//    }


    //查看两个对象是否相等,类似于字符串比较使用的equals()方法
    //public static void assertEquals(Object expected, Object actual)
    @Test
    public void TestAdd(){
        MyMath myMath = new MyMath();
        int result = myMath.add(10, 20);

        //public static void assertEquals(Object expected, Object actual)
        Assert.assertEquals(30, result);    //第一个参数表示期望值,后面一个是实际值
//        Assert.assertEquals(20, result);
    }

    @Test
    public void testsub(){
        MyMath myMath = new MyMath();
        int result = myMath.sub(20, 10);

        Assert.assertEquals(10, result);
    }

}

Junit 常用注解

此处在谁之前在谁之后,是针对@Test而言的

方法名

说明

@Test

说明依附在JUnit 的 public void 方法可以作为一个测试案例

@Before

修饰实例方法,方法针对每一个测试用例执行,但是是在执行测试用例之前

@After

修饰实例方法,方法针对每一个测试用例执行,但是是在执行测试用例之后

@BeforeClass

修饰静态方法,方法首先执行,并且只执行一次,用于初始化资源

@AfterClass

修饰静态方法,方法最后执行,并且只执行一次,用于释放资源

参考代码:

package com.itheima;

import org.junit.*;

public class MyMathTest {
    @BeforeClass
    public static void beforeClass() {
        System.out.println("beforeClass");
    }

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

    @Test
    public void testAdd(){
        MyMath myMath = new MyMath();
        int result = myMath.add(10, 20);
        Assert.assertEquals(30, result);
        System.out.println("加法测试完毕");
    }

    @Test
    public void testSub(){
        MyMath myMath = new MyMath();
        int result = myMath.sub(20, 10);
        Assert.assertEquals(10, result);
        System.out.println("减法测试完毕");
    }

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

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

执行结果查看

beforeClass
before
加法测试完毕
after
before
减法测试完毕
after
afterClass

通过测试类和单个方法不难看出:@BeforeClass 和 @AfterClass只执行一次,而@Before 和 @After由执行@Test的个数决定

作用:整体资源的使用和释放、和测试方法前后所需的使用