所谓单元测试,就是针对最小的功能单元,编写测试代码对其进行正确性测试。
我们之前一直使用的测试便是通过main方法来实现,但在main方法中写测试代码有如下的几个问题存在:
为了测试更加方便,有一些第三方的公司或者组织提供了很好用的测试框架,其中一种便是JUnit测试框架。
JUnit是第三方公司开源出来的框架,用于对代码进行单元测试的工具(IDEA已经继承了JUnit框架)。
相比于在main方法中测试,JUnit有如下的优点:
因为Junit是第三方提供的,所以在使用之前,我们需要导入到项目之中才能使用,具体步骤如下所示:
使用演示
先准备一个类:Utils工具类(实现两数最大值)
public class Utils {
public static int max(int num1,int num2) {
return num1 > num2? num1 : num2;
}
}
再准备一个测试类,测试Utils工具类中的方法能否正常使用。
public class showTest {
@Test
public void show(){
int num = 10;
int num2 = 30;
System.out.println("两数最大值为:" + Utils.max(num,num2));
}
}
在写完代码后,测试方法左边会出现一个绿色的三角形按钮,点击按钮就可以测试方法。
运行效果
断言机制(assertions):是测试方法中的核心部分,用来对测试需要满足的条件进行验证。这些断言方法都是org.junit.jupiter.api.Assertions的静态方法。
而所谓断言,意思是程序员可以预测程序的运行结果,检查程序的运行结果是否与预期一致。
介绍一种简单的断言方法。
现在在showTest中新增一个方法:assertEquals(判断两个对象或两个原始类型是否相等)。
public class showTest {
@Test
public void show(){
int num = 10;
int num2 = 30;
assertEquals("不等于",10,Utils.max(num,num2));
System.out.println("两数最大值为:" + Utils.max(num,num2));
}
}
运行效果
若断言失败,后面的代码都不会执行,所以断言后的输出语句并没有执行。
通过 assertArrayEquals 方法来判断两个对象或原始类型的数组是否相等
public class showTest {
@Test
public void show(){
assertArrayEquals("内容不相等",new int[]{3,2},new int[]{2,2});
}
}
运行效果
JUnit的启动必须要有@Test注解,它的作用是用来标记一个方法为测试方法,测试才能启动执行。
在JUnit中,除了@Test注解,还有一些其他的注解:
@Before:每个测试方法执行之前执行
@Before
public void before(){
System.out.println("before执行了");
}
@Test
public void test1(){
System.out.println("test1执行");
}
@Test
public void test2(){
System.out.println("test2执行");
}
运行效果
@After:每个测试方法之后执行。
@Test
public void test1(){
System.out.println("test1执行");
}
@Test
public void test2(){
System.out.println("test2执行");
}
@After
public void after(){
System.out.println("after执行了");
}
运行效果
@BeforeClass :修饰静态方法,只会在所有测试方法之前执行一次。
@BeforeClass
public static void before(){
System.out.println("before执行了");
}
@Test
public void test1(){
System.out.println("test1执行");
}
@Test
public void test2(){
System.out.println("test2执行");
}
运行效果
@AfterClass : 修饰静态方法,只会在所有测试方法之后执行一次。
@Test
public void test1(){
System.out.println("test1执行");
}
@Test
public void test2(){
System.out.println("test2执行");
}
@After
public void after(){
System.out.println("after执行了");
}
运行效果
● 注解的应用场景
假如我想在每个测试方法中使用Socket对象,并且用完之后,要把Socket关闭,这个时候就可以使用注解来完成。
public class jUnitTest{
private static Socket socket;
@Before
public void test1(){
System.out.println("--> test1 Before 执行了");
}
@BeforeClass
public static void test11(){
System.out.println("--> test11 BeforeClass 执行了");
//初始化Socket对象
socket = new Socket();
}
@After
public void test2(){
System.out.println("--> test2 After 执行了");
}
@AfterCalss
public static void test22(){
System.out.println("--> test22 AfterCalss 执行了");
//关闭Socket
socket.close();
}
}
● 注解小结
1.被@BeforeClass标记的方法,执行在所有方法之前
2.被@AfterCalss标记的方法,执行在所有方法之后
3.被@Before标记的方法,执行在每一个@Test方法之前
4.被@After标记的方法,执行在每一个@Test方法之后
在JUnit5中对注释做了更新,但作用是相同的,只是改了方法名。