Junit Test
Junit test学习笔记
视频链接:
Java教程 - Part-8-JUnit单元测试
文章目录
单元测试
什么是单元测试
- 单元测试是针对最小功能单元编写测试代码
- 由于JAVA最小功能单元是方法,因此单元测试是针对于单个JAVA方法的测试
测试驱动开发(TDD)
写代码前先写测试
单元测试好处
-
确保单个方法运行正常
-
若修改了方法代码,只需确保其对应的单元测试通过
-
测试代码本身可以作为示例代码
-
自动化运行所有测试,获得报告
JUnit介绍
针对JAVA语言的单元测试框架,开源(标准单元测试框架)
使用Main方法测试的缺点
-
只有一个main方法,不能将测试代码分离
-
没有打印出测试结果和期望结果
因此需要一种测试框架来辅助测试
JUnit特点
- 使用断言(Assertion)测试期望结果
- 可以方便地组织,运行测试并查看结果
- 常用IDE(Eclipse, IDEA)都集成了JUnit
- 可以方便地集成到Maven
JUnit的设计
- TestCase:一个TestCase表示一个测试
- TestSuite:一个TestSuite包含一组TestCase,表示一组测试
- TestFixture:一个TestFixture表示一个测试环境
- TestResult:用于收集测试结果
- TestRunner:用于运行测试
- TestListener:用于监听测试过程,收集测试数据
- Assert:用于断言测试结果是否准确
编写JUnit测试程序时,只需要关注 TestCase 和 Assert 即可
JUnit使用
使用 Assert断言
-
需要导入Assert类:
import static org.junit.Assert.*;
-
常用方法:
assertEquals(100,x)//断言相等 assertNotEquals(100,x)//断言不相等 assertArrayEquals({1,2,3},x)//断言数组相等 assertEquals(3.1416,x,0.0001)//浮点数断言相等,其中0.0001为可接受的误差范围 assertNull(x)//断言为null assertNotNull(x)//断言不为null assertTrue(x>0)//断言为true assertFalse(x>0)//断言为false
-
测试要点:
- 一个TestCase包含一组相关的测试方法
- 使用Assert断言测试结果
- 每个测试方法必须互相独立,测试代码必须简单
- 不能为测试代码再编写测试
- 测试须覆盖各类输入条件,特别是边界条件
使用Before和After
使用@Before和@After
-
在同一个单元测试中包含多个测试方法,测试前后可能都需要额外的操作来初始化或释放对象
-
JUnit中使用
@Before
和@After
注解来完成上述工作public class XXXTest{ //xxxxxx @Before public void SetUp(){ //初始化资源 } @After public void TearDown{ //释放资源 } //xxxxxx }
-
Junit对于每个
@Test
测试方法:- 实例化测试类
- 执行
@Before
方法 - 执行
@Test
方法 - 执行
@After
方法
因此,使用
@Before
和@After
可以保证:- 单个
@Test
方法执行前会创建新的XxxTest实例,实例变量状态不会传入进下一个@Test
方法 - 每个
@Test
方法执行前后都会执行@Before
方法和@After
方法
使用@BeforeClass和@AfterClass
Junit提供了@BeforeClass
和@AfterClass
静态方法:
- 在执行所有
@Test
方法前执行@BeforeClass
静态方法 - 执行所有测试
- 在执行所有
@Test
方法后执行@AfterClass
静态方法
注意要点:
@BeforeClass
静态方法初始化的对象只能存放于静态字段中- 使用静态字段的对象测试,其状态会影响到所有的
@Test
方法
JUnit执行逻辑:
invokeBeforeClass(XXTest.class);//@BeforeClass
for (Method testMethod : findTestMethods(XXTest.class)){
XXTest test = new XXTest();//new
test.SetUp();//@Before
testMethod.invoke(test);//@Test
test.TearDown();//@After
}
invokeAfterClass(XXTest.class);//@AfterClass
Junit Fixture
初始化测试资源称作Fixture
- @Before: 初始化测试对象,例如input = new FileInputStream();
- @After: 销毁@Before创建的测试对象,例如input.close();
- @BeforeClass: 初始化非常耗时的资源,例如创建数据库
- @AfterClass: 清理@BeforeClass创建的资源,例如删除数据库
异常测试
对可能抛出的异常进行测试
-
异常本身是方法签名的一部分
public static int parseInt(String s) throws NumberFormatException
-
测试错误的输入是否导致特定的异常
如何测试异常?
-
使用try-catch捕获异常,若没有捕获异常,则使用Junit提供的
fail()
来表示测试失败 -
在注解中,使用
expected
标注来测试异常@Test(expected = NumberFormatException.class) public void testNumberFormatException(){ Integer.parseInt(null); }
参数化测试
如果待测试的输入和输出是一组数据:
- 可以把测试数据组织起来
- 用不同的测试数据调用相同的测试方法
参数化测试要求:
-
参数必须由静态方法
data()
返回 -
返回类型为
Collection<Object[]>
-
静态方法必须标记为
@Parameters
-
测试类必须标记为
@RunWith(Parameterized.class)
-
构造方法参数必须和测试参数相对应
@RunWith(Parameterized.class)
public class AbsTest{
@Parameters
public static Collection<?> data(){
return Arrays.asList(new Object[][]{
{0,0},{1,1},{-1,1}
});
}
int input;
int expected;
//构造方法
public AbsTest(int input,int expected){
this.input = input;
this.expected = expected;
}
@Test
public void testAbs(){
int r = Math.abs(this.input);
assertEquals(this.expected,r);
}
}
超时测试
可以为JUnit的单个测试设置超时
@Test(timeout = 1000)//单位是毫秒
注:超时测试并不能取代性能测试和压力测试