java的单元测试JUnit4
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
java的单元测试JUnit4 java的单元测试
1. 概念
java单元测试是最⼩的功能单元测试代码, 单元测试就是针对单个java⽅法的测试
java程序的最⼩功能单元是⽅法
2. 单元测试的优点
main⽅法进⾏测试的缺点:
只能有⼀个main()⽅法, 不能把测试代码分离出来
⽆法打印出测试结果和期望结果.例如: expected: 3628800, but actual: 123456单元测试的优点:
确保单个⽅法正常运⾏
如果修改了⽅法代码, 只需要保其对应的单元测试通过就可以了
测试代码本省就可以作为⽰例代码
可以⾃动化运⾏所有测试并获得报告
3. Junit单元测试
JUnit是⼀个开源的java语⾔的单元测试框架
专门针对java语⾔设计, 使⽤最⼴泛, JUnit是标准的单元测试架构
3.1 JUnit特点
使⽤断⾔(Assertion)测试期望结果
可以⽅便的组织和运⾏测试
可以⽅便的查看测试结果
常⽤的开发⼯具IDEA, Eclipse都集成了JUnit
可以⽅便的继承到maven中
3.2 maven依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<!-- junit的版本有3.x, 4.x, 5.x 5.x还没有发布, 现在都⽤是4.x -->
</dependency>
3.3 在IDE中使⽤快捷键进⾏单元测试
测试类的使⽤⽬录必须是如下, 测试类规定标准是在test⽬录中进⾏测试
localhost:javatest lingjing$ tree -d -L 3
.
├── src
│├── main
││└── java
│└── test
│└── java
IDE的快捷键是:ctrl+shift+t --> create new test
然后选择对应的⽅法进⾏测试就好了
3.4 断⾔
3.4.1 断⾔的例⼦
断⾔的使⽤, 必须先引⼊必须的包: IDE⾃动创建的会⾃动引⼊
import static org.junit.Assert.*;
例⼦: 在main包中的编写的⼀个正则表达式的类
import java.util.Arrays;
/**
* @ClassName Calculator
* @Description 在main中的主要类
* @Author lingxiangxiang
* @Date 10:07 AM
* @Version 1.0
**/
public class Calculator {
public int calculate(String expression) {
String[] ss = expression.split("\\+");
System.out.println(expression + " => " + Arrays.toString(ss));
int sum = 0;
for (String s: ss) {
sum += Integer.parseInt(s.trim());
}
return sum;
}
}
测试类:
import org.junit.Test;
import static org.junit.Assert.*;
public class CalculatorTest {
@Test
public void calculate() {
assertEquals(3, new Calculator().calculate("1 + 2"));
assertEquals(3, new Calculator().calculate("1 + 2 + 3"));
}
}
测试类执⾏结果如下:
1 +
2 => [1 , 2]
1 +
2 +
3 => [1 , 2 , 3]
ng.AssertionError:
Expected :3
Actual :6
<Click to see difference>
at javatest.CalculatorTest.calculate(CalculatorTest.java:12)
第⼀个⽅法: 1 + 2 => [1 , 2], 最终的结果3是正确的, 所有没有任何报错, 正常显⽰
第⼆个⽅法: 1 + 2 + 3 => [1 , 2 , 3], 最终报错, 并提⽰在代码的位置: CalculatorTest.java:12, 并且罗列出Expected和Actual的值, 清楚的显⽰了结果的对⽐情况, 和代码出现的位置
3.4.2 断⾔的常⽤⽅法
assertEquals(100, x): 断⾔相等
assertArrayEquals({1, 2, 3}, x): 断⾔数组相等
assertEquals(3.1416, x, 0.0001): 浮点数组断⾔相等
assertNull(x): 断⾔为null
assertTrue(x > 0): 断⾔为true
assertFalse(x < 0): 断⾔为false;
assertNotEquals: 断⾔不相等
assertNotNull: 断⾔不为null
3.5 使⽤@Before和@After
在@Before⽅法中初始化测试资源
在@After⽅法中释放测试资源
@BeforeClass: 初始化⾮常耗时的资源, 例如创建数据库
@AfterClass: 清理@BeforeClass创建的资源, 例如创建数据库
3.5.1 对于每⼀个@Test⽅法的执⾏顺序
注意:** 单个@Test⽅法执⾏前会创建新的XxxTest实例, 实例变量的状态不会传递给下⼀个@Test⽅法, 单个@Test⽅法执⾏前后会执⾏@Before和@After⽅法
1. 执⾏类的构造函数
2. 执⾏@Before⽅法
3. 执⾏@Test⽅法
4. 执⾏@After⽅法
3.5.2 代码实例:
写⼀个整体的测试类如下:
package javatest;
/**
* @ClassName SequenceTest
* @Description TODO
* @Author lingxiangxiang
* @Date 1:54 PM
* @Version 1.0
**/
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class SequenceTest {
@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()");
}
public SequenceTest() {
System.out.println(" new SequenceTest()");
}
@Test
public void testA() {
System.out.println(" testA()");
}
@Test
public void testB() {
System.out.println(" testB()");
}
@Test
public void testC() {
System.out.println(" testC()");
}
}
如果运⾏整个类, 运⾏结果如下:
BeforeClass()
new SequenceTest()
Before()
testA()
After()
new SequenceTest()
Before()
testB()
After()
new SequenceTest()
Before()
testC()
After()
AfterClass()
如果运⾏单个@Test类
BeforeClass()
new SequenceTest()
Before()
testA()
After()
AfterClass()
3.6 异常测试
异常测试可以通过@Test(expected=Exception.class), 对可能发⽣的每种类型的异常进⾏测试
如果抛出了指定类型的异常, 测试成功
如果没有抛出指定类型的异常, 或者抛出的异常类型不对, 测试失败
例⼦:
运⾏如下代码: 正常通过
// 运⾏如下代码, 正常运⾏, 确实发⽣了ArithmeticException异常, 代码通过
@Test(expected = ArithmeticException.class)
public void testException() {
int i = 1 / 0;
}
运⾏如下代码: 有报错信息
@Test(expected = ArithmeticException.class)
public void testException() {
int i = 1 / 1;
}
执⾏结果如下:
ng.AssertionError: Expected exception: ng.ArithmeticException
3.7 参数化测试
@RunWith: 当类被@RunWith注释修饰, 或者类继承了⼀个被该注解类修饰的类, JUnit将会使⽤这个注解所指明的运⾏器(runner)来运⾏测试, ⽽不是JUni默认的运⾏器
要进⾏参数化测试,需要在类上⾯指定如下的运⾏器:
@RunWith (Parameterized.class)
然后,在提供数据的⽅法上加上⼀个@Parameters注解,这个⽅法必须是静态static的,并且返回⼀个集合Collection。
JUnit4中参数化测试要点:
1. 测试类必须由Parameterized测试运⾏器修饰
2. 准备数据。
数据的准备需要在⼀个⽅法中进⾏,该⽅法需要满⾜⼀定的要求:
1)该⽅法必须由Parameters注解修饰
2)该⽅法必须为public static的
3)该⽅法必须返回Collection类型
4)该⽅法的名字不做要求
5)该⽅法没有参数
例⼦:
@RunWith(Parameterized.class)
public class Testa {
@Parameterized.Parameters
public static Collection<?> data() {
return Arrays.asList(new Object[][] { { "1+2", 3 }, { "1+2+5", 8 }, { "123+456", 579 }, { " 1 + 5 + 10 ", 16 } }); }
Calculator calc;
@Parameterized.Parameter(0)
public String input;
@Parameterized.Parameter(1)
public int expected;
@Before
public void setUp() {
calc = new Calculator();
}
@Test
public void testCalculate() {
int r = calc.calculate(this.input);
assertEquals(this.expected, r);
}
}
执⾏结果:
1+2 => [1, 2]
1+2+5 => [1, 2, 5]
123+456 => [123, 456]
1 + 5 + 10 => [ 1 , 5 , 10 ]
3.8 超时测试
@Test(timeout=1000)可以设置超时时间
timeout单位是毫秒。