Junit使用教程详解

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

junit常用注解详细说明:

https://www.cnblogs.com/tobey/p/4837495.html

Junit使用教程(二):

https://blog.csdn.net/wangpeng047/article/details/9628449

原文发布于微信公众号 - 浩Coding(gh_c4a2e63d2ca7)

原文发表时间:2019-04-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券