Junit简介
JUnit是一个Java语言的单元测试框架。Junit测试是程序员测试,即所谓白盒测试,因为程序员知道被测试的软件如何(How)完成功能和完成什么样(What)的功能。Junit是一套框架,继承TestCase类,就可以用Junit进行自动测试了。多数Java的开发环境都已经集成了JUnit作为单元测试的工具。 -- 来源:百度百科。
JUnit是一个开放源代码的Java测试框架,用于编写和运行可重复的测试。是起源于 JUnit 的一个统称为 xUnit 的单元测试框架之一(用于java语言)。它包括以下特性:
1、用于测试期望结果的断言(Assertion)
2、用于共享共同测试数据的测试工具
3、用于方便的组织和运行测试的测试套件
4、图形和文本的测试运行器
下面就带大家来初步接触Junit,本教程所有源码地址:
https://github.com/jiahaoit/tool
初步认识Junit
1、用原始的main方法进行测试
大家刚开始写代码的时候,可能都像我一样,会用 main 函数来进行运行。顺便测试一下所写的代码,是否按照期望运行。
比如如下代码,用来测试sum方法是否按照预期进行执行:
public class GeneralMain {
public static void main(String[] args) {
int result = sum1(1, 2);
System.out.println(result);
}
public static int sum1(int i, int j) {
return i+j;
}
}
通过main方法来进行测试的问题是显而易见的。 比如新开发了一个方法,是对3个数求和,那么问题至少有两个:
1. 要在原来测试的基础上修改,可能破坏原来的测试逻辑。
2. 测试成功了,还是i测试失败了,都不知道呀。。。只能通过肉眼进行观察,如果测试的量很大,是很难看的过来滴。
2、使用Junit的@Test
这个时候我们的主角登场了,使用 junit 测试框架来进行测试工作。首先下载 jar 包: junit-4.9.jar, 导入到项目中(在我的Github上可以下载),其实大部分IDE已经集成了Junit,例如Eclipse可以导入Junit库:
右键项目 --> Build Path --> Add Library --> Junit:
然后创建 TestCase1类,并创建一个方法:
import org.junit.Test;
import junit.framework.Assert;
public class TestCase1 {
@Test
public void testSum1() {
int result = GeneralMain.sum1(1, 2);
Assert.assertEquals(result, 3);
}
}
它是由 @Test 进行了注解,表示这个方法是一个测试方法。
Assert.assertEquals(result, 3); 表示对 result 数值的期待是 3,如果是其他数值,就无法通过测试。
与main方法运行不一样,运行测试用例的时候,需要选择 Run As -> JUnit Test 方式:
运行成功之后,会显示如图所示的样子,运行成功是绿色的:
接着,我们新增加一个 testSum2 方法, 用于测试sum2 方法。这一次,我们故意写成 错误的result期待值:
@Test
public void testSum2() {
int result = GeneralMain.sum2(1, 2, 3);
Assert.assertEquals(result, 5);
}
运行之后,因为 result 的值是 6, 并不等于5, 所以失败之后,看到如图所示的效果,表示没有通过测试,是红色的:
而且还给出了失败的行数: TesetCase1.java:28
现在回过头来看 junit 解决的main 的问题 中的2个问题:
1. 新增加的测试,对原来的测试没有影响。
2. 如果测试失败了,会立即得到通知。
3、使用JUnit的@before 和@after
@Before @After 也是常见的测试框架注解,分别用来在测试开始之前做的事情,和结束之后做的事情。
@Before
public void before() {
System.out.println("测试前的准备工作,比如链接数据库等等");
}
@After
public void after() {
System.out.println("测试结束后的工作,比如关闭链接等等");
}
运行截图:
4、JUnit常用注解:
(1)@Test:@Test有个expected属性和timeout属性:(@Test(expected=NullPointerException.class),@Test(timeout=1000))
expected属性可以捕获测试方法和被测试方法中预期抛出的异常,timeout限定方法执行的时间。
注意:测试方法必须是public void,即公共、无返回数据。可以抛出异常。
(2)@Ignore:@Ignore修饰的方法不会被执行,可以@Ignore("此方法被忽略")做一个注释:此方法被忽略。
(3)@BeforeClass:意思是在测试类里所有用例运行之前,运行一次这个方法。例如创建数据库连接、读取文件等。
注意:方法名可以任意,但必须是public static void,即公开、静态、无返回。这个方法只会运行一次。
(4)@AfterClass:跟@BeforeClass对应,在测试类里所有用例运行之后,运行一次。用于处理一些测试后续工作,例如清理数据,恢复现场。
注意:同样必须是public static void,即公开、静态、无返回。这个方法只会运行一次。
(5)@Before:与@BeforeClass的区别在于,@Before不止运行一次,它会在每个用例运行之前都运行一次。主要用于一些独立于用例之间的准备工作。比如两个用例都需要读取数据库里的用户A信息,但第一个用例会删除这个用户A,而第二个用例需要修改用户A。那么可以用@BeforeClass创建数据库连接。用@Before来插入一条用户A信息。
注意:必须是public void,不能为static。不止运行一次,根据用例数而定。
(6)@After:与@Before对应。
一个测试类单元测试的执行顺序为:
@BeforeClass –> @Before –> @Test –> @After –> @AfterClass
每一个测试方法的调用顺序为:
@Before –> @Test –> @After
实例:
import static org.junit.Assert.*;
import org.junit.*;
/**
* 了解一个测试类单元测试的执行顺序为:
* @BeforeClass –> @Before –> @Test –> @After –> @AfterClass
* @author hao
*
*/
public class TestJunit1 {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
System.out.println("in BeforeClass================");
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
System.out.println("in AfterClass=================");
}
@Before
public void before() {
System.out.println("in Before");
}
@After
public void after() {
System.out.println("in After");
}
@Test(timeout = 10000)
public void testadd() {
TestJunit2 a = new TestJunit2();
assertEquals(6, a.add(3, 3));
System.out.println("in Test ----Add");
}
@Test
public void testdivision() {
TestJunit2 a = new TestJunit2();
assertEquals(3, a.division(6, 2));
System.out.println("in Test ----Division");
}
@Ignore
@Test
public void test_ignore() {
TestJunit2 a = new TestJunit2();
assertEquals(6, a.add(1, 5));
System.out.println("in test_ignore");
}
@Test
public void teest_fail() {
fail();
}
}
class TestJunit2 extends Thread {
int result;
public int add(int a, int b) {
try {
sleep(1000);
result = a + b;
} catch (InterruptedException e) {
}
return result;
}
public int division(int a, int b) {
return result = a / b;
}
}
执行结果:
--------- in BeforeClass ----------
in Before
in Test ---- Division
in After
in Before
in After
in Before
in Test ---- Add
in After
---------- in AfterClass ----------
5、Assert的用法:
Assert就是断言,断言是编写测试用例的核心实现方式,即期望值是多少,测试的结果是多少,以此来判断测试是否通过。
Assert的核心方法:
注:图片来源--https://blog.csdn.net/wangpeng047/article/details/9628449
实例:
import org.junit.Test;
/**
* Assert 断言的使用方法
* @author hao
*
*/
public class AssertTests {
@Test
public void testAssertArrayEquals() {
byte[] expected = "trial".getBytes();
byte[] actual = "trial".getBytes();
// 查看两个数组是否相等。
org.junit.Assert.assertArrayEquals("failure - byte arrays not same", expected, actual);
}
@Test
public void testAssertEquals() {
// 查看两个对象是否相等。类似于字符串比较使用的equals()方法
org.junit.Assert.assertEquals("failure - strings not same", 5l, 5l);
}
@Test
public void testAssertFalse() {
// 查看两个对象是否不相等。
org.junit.Assert.assertFalse("failure - should be false", false);
}
@Test
public void testAssertNotNull() {
// 查看对象是否不为空
org.junit.Assert.assertNotNull("should not be null", new Object());
}
@Test
public void testAssertNull() {
// 查看对象是否为空
org.junit.Assert.assertNull("should be null", null);
}
@Test
public void testAssertNotSame() {
// 查看两个对象的引用是否不相等。类似于使用“!=”比较两个对象
org.junit.Assert.assertNotSame("should not be same Object", new Object(), new Object());
}
@Test
public void testAssertSame() {
Integer aNumber = Integer.valueOf(768);
// 查看两个对象的引用是否相等。类似于使用“==”比较两个对象
org.junit.Assert.assertSame("should be same", aNumber, aNumber);
}
}
6、使用TestSuite
上面我们讲解的是对一个工具类 SumUtil 的测试类 TestCase1. 如果有很多工具类需要被测试,那么就会有 TestCase2, TestCase3, TestCase4。如果不得不挨个去执行这些单独的测试类,也是比较麻烦的,所以就有了 TestSuite的概念:
TestCase:字面意思,测试用例。为一个或多个方法提供测试方法。一般是一个test
TestSuite:测试集合,即一组测试。一个test suite是把多个相关测试归入一组的快捷方式。如果自己没有定义,Junit会自动提供一个test suite ,包括TestCase中的所有测试。
TestRunner:测试运行器。执行test suite的程序。
TestSuite 。。。 其实就是一下执行多个测试类。
我们新建一个测试类TestCase2,内容和TestCase1一样,然后新建TestSuite类:
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({TestCase1.class,TestCase2.class})
public class TestSuite {
}
运行效果:
本教程所有源码地址:
https://github.com/jiahaoit/tool
参考文章:
本文是学习how2j网站所写的一篇教程,代码所有权归how2j网站所有!
http://how2j.cn/k/junit/junit-tutorial/1937.html
junit百度百科:
https://baike.baidu.com/item/junit/1211849?fr=aladdin
https://www.cnblogs.com/tobey/p/4837495.html
https://blog.csdn.net/wangpeng047/article/details/9628449