一.Junit 是什么?
JUnit是一个Java语言的单元测试框架。它由Kent Beck和Erich Gamma建立,逐渐成为源于Kent Beck的sUnit的xUnit家族中最为成功的一个JUnit有它自己的JUnit扩展生态圈。多数Java的开发环境都已经集成了JUnit作为单元测试的工具。
注意:Junit 测试也是程序员测试,即所谓的白盒测试,它需要程序员知道被测试的代码如何完成功能,以及完成什么样的功能
二.Junit 能做什么?
我们知道 Junit 是一个单元测试框架,那么使用 Junit 能让我们快速的完成单元测试
通常我们写完代码想要测试这段代码的正确性,那么必须新建一个类,然后创建一个 main() 方法,然后编写测试代码。如果需要测试的代码很多呢?那么要么就会建很多main() 方法来测试,要么将其全部写在一个 main() 方法里面这也会大大的增加测试的复杂度,降低程序员的测试积极性。而 Junit 能很好的解决这个问题,简化单元测试,写一点测一点,在编写以后的代码中如果发现问题
可以较快的追踪到问题的原因,减小回归错误的纠错难度
三.单元测试的工具有JUnit、TestNG、Mockito、Unitils等,其中JUnit、TestNG比较主流
JUnit4相关注解:
@BeforeClass:在所有测试方法前执行一次,一般在其中写上整体初始化的代码
@AfterClass:在所有测试方法后执行一次,一般在其中写上销毁和释放资源的代码。
@Before:在每个测试方法前执行,一般用来初始化方法(比如我们在测试别的方法时,类中与其他测试方法共享的值已经被改变,为了保证测试结果的有效性,我们会在@Before注解的方法中重置数据
@After:在每个测试方法后执行,在方法执行完成后要做的事情
@Test(timeout = 1000):指明要被测试的方法(测试方法执行超过1000毫秒后算超时,测试将失败)
@Test(expected = Exception.class):测试方法期望得到的异常类,如果方法执行没有抛出指定的异常,则测试失败
@Ignore:执行测试时将忽略掉此方法,如果用于修饰类,则忽略整个类。
@Test:指明要被测试的方法。
@RunWith:指定用什么方式策略去运行这些测试集、类、方法。
@ActiveProfiles(“xxx”):在测试的时候启用某些Profile的Bean。
注:JUnit5不仅新增了@ParameterizedTest注解等,还对JUnit4的部分注解进行了调整,如:注解名称发生了变化(功能几乎没变)等。
四.断言Assert:
程序员在测试时,使用断言来判断某些逻辑条件必须满足。断言判断为真,下面的一些业务逻辑才可以进行下去,如果断言判断为假,程序就会"报错"甚至是"崩溃"
断言与异常、错误的区别:
"断言"通常是给程序开发人员自己使用,并且在开发测试期间使用。而异常等在程序运行期间触发。通常"断言"触发后程序"崩溃"退出,不需要从错误中恢复。而"异常"通常会使用try/catch等结构从错误中恢复并继续运行程序
断言简单使用示例: Assert.assertEquals(result, 3); 断言还有很多方法
注:与断言(assert)相似的叫假设(assume)。当断言不成立时,当次测试的结果状态将会是测试失败;
而当假设不成立时,当次测试的结果状态不是失败,而是假设。断言用得想多一些,本人也不介绍假设
注:未使用断言的单元测试,不是一个合格的单元测试;使用System.out…的单元测试不是一个合格的单元测试;
需要人员盯着观察的单元测试,不是一个合格的单元测试。
五.单元测试时的事务回滚:
在单元测试时,有时我们会进行事务回滚来恢复现场,设置方式为:在类上或方法上加@Transactional注解
测试代码:
public class Calculator{
public int add(int a,int b){
return a+b;
}
public int sub(int a,int b){
return a-b;
}
}
public class CalculatorTest {
// @Test
// public void testAdd(){
// Calculator c = new Calculator();
// int result = c.add(1, 2);
// Assert.assertEquals(result, 3);
// }
// @Test
// public void testSub(){
// Calculator c = new Calculator();
// int result = c.sub(2,1);
// Assert.assertEquals(result,1);
// }
Calculator c = null;
@Before
public void testBeforeClass(){
c = new Calculator();
}
@Test
public void testAdd(){
int result = c.add(1, 2);
if(result==3){
System.out.println("add()方法正确");
}
}
@Test
public void testSub(){
int result = c.sub(2, 1);
if(result==1){
System.out.println("sub()方法正确");
}
}
}
public class JunitTest {
public JunitTest(){
System.out.println("构造函数");
}
@BeforeClass
public static void beforeClass(){
System.out.println("@BeforeClass");
}
@Before
public void befor(){
System.out.println("@Before");
}
@Test
public void test(){
System.out.println("@Test");
}
@Ignore
public void ingore(){
System.out.println("@Ignore");
}
@After
public void after(){
System.out.println("@After");
}
@AfterClass
public static void afterClass(){
System.out.println("@AfterClass");
}
}