Junit单元测试框架
引言
我们为什么需要单元测试?
随着我们的项目逐渐变大,比如我们之前编写的图书管理系统,我们都是边在写边在测试,而我们当时使用的测试方法,就是直接在主方法中运行测试,但是,在很多情况下,我们的项目可能会很庞大,不可能每次都去完整地启动一个项目来测试某一个功能,这样显然会降低我们的开发效率,因此,我们需要使用单元测试来帮助我们针对于某个功能或是某个模块单独运行代码进行测试,而不是启动整个项目。
同时,在我们项目的维护过程中,难免会涉及到一些原有代码的修改,很有可能出现改了代码导致之前的功能出现问题(牵一发而动全身),而我们又不一定能立即察觉到,因此,我们可以提前保存一些测试用例,每次完成代码后都可以跑一遍测试用例,来确保之前的功能没有因为后续的修改而出现问题。
我们还可以利用单元测试来评估某个模块或是功能的耗时和性能,快速排查导致程序运行缓慢的问题,这些都可以通过单元测试来完成,可见单元测试对于开发的重要性。
正文
1.尝试JUnit
首先需要导入JUnit依赖
<!--单元测试的依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
现在我们创建一个新的类,来编写我们的单元测试用例:
public class TestMain {
@Test
public void method(){
System.out.println("我是测试用例1");
}
@Test
public void method2(){
System.out.println("我是测试用例2");
}
}
运行测试后,我们发现控制台得到了一个测试结果,显示为绿色表示测试通过。
只需要通过打上@Test
注解,即可将一个方法标记为测试案例,我们可以直接运行此测试案例,但是我们编写的测试方法有以下要求:
- 方法必须是
public
的 - 不能是静态方法
- 返回值必须是
void
- 必须是没有任何参数的方法
2.测试结果与预期
对于一个测试案例来说,我们肯定希望测试的结果是我们所期望的一个值,因此,如果测试的结果并不是我们所期望的结果,那么这个测试就应该没有成功通过!
我们可以通过断言工具类来进行判定:
@Test
public void test1() {
System.out.println("单元测试案例测试1-开始");
Assert.assertEquals("断言语句", 1, 2);//这里的1,是期望值,而2是实际的值
System.out.println("单元测试案例测试1-完成");
}
由于期望和实际不符,会报错:
java.lang.AssertionError: 断言语句
Expected :1
Actual :2
<Click to see difference>
同样的,断言工具是一个重载方法,可以对不同的结果进行断言:
@Test
public void test2() {
System.out.println("单元测试案例2-开始");
// 测试冒泡排序
int query[] = {1, 5, 6, 2, 0, 14, 52, 32, 98};
for (int i = 0; i < query.length - 1; i++) {
boolean lock = true;//优化锁
for (int j = 0; j < query.length - 1; j++) {
if (query[j] > query[j + 1]) {
lock = false;
int temp = query[j];
query[j] = query[j + 1];
query[j + 1] = temp;
}
}
if (lock) break;
}
Assert.assertArrayEquals(new int[]{0, 1, 2, 5, 6, 14, 32, 52, 98}, query);
System.out.println("单元测试案例2-完成");
}
3.前置操作&收尾动作
那么如果我们在进行所有的测试之前需要做一些前置操作和收尾动作,我们的基本思路:
-
在所有的测试用例前面都加上前置操作和守卫动作。
-
@Before
注解和@After
注解来代替前置操作和守卫动作。
@Before
public void before() {
System.out.println("测试前置正在初始化...");
}
@Test
public void test1() {
System.out.println("单元测试案例测试1-开始");
Assert.assertEquals("断言语句", 1, 2);//这里的1,是期望值,而2是实际的值
System.out.println("单元测试案例测试1-完成");
}
@Test
public void test2() {
System.out.println("单元测试案例2-开始");
// 测试冒泡排序
int query[] = {1, 5, 6, 2, 0, 14, 52, 32, 98};
for (int i = 0; i < query.length - 1; i++) {
boolean lock = true;//优化锁
for (int j = 0; j < query.length - 1; j++) {
if (query[j] > query[j + 1]) {
lock = false;
int temp = query[j];
query[j] = query[j + 1];
query[j + 1] = temp;
}
}
if (lock) break;
}
Assert.assertArrayEquals(new int[]{0, 1, 2, 5, 6, 14, 32, 52, 98}, query);
System.out.println("单元测试案例2-完成");
}
@After
public void after() {
System.out.println("测试结束,收尾工作正在进行...");
}
注:@Before
和@After
注解对每个测试用例都有效
运行结果: