JAVA中单元测试的常用方式

栏目: Java · 发布时间: 5年前

内容简介:单元测试(英语:Unit Testing)又称为模块测试, 是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法。优质的单元测试可以保障开发质量和程序的鲁棒性。在大多数互联网企业中开发工程师在研发过程中都会频繁地执行测试用例,运行失败的单测能帮助我们快速排查和定位问题 使问题在被带到线上之前完成修复。正如软件工程界的一条金科玉

什么是单元测试

单元测试(英语:Unit Testing)又称为模块测试, 是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法。

单元测试的优点

优质的单元测试可以保障开发质量和程序的鲁棒性。在大多数互联网企业中开发工程师在研发过程中都会频繁地执行测试用例,运行失败的单测能帮助我们快速排查和定位问题 使问题在被带到线上之前完成修复。正如软件工程界的一条金科玉律----越早发现的缺陷,其修复成本越低。一流的测试能发现未发生的故障;二流的测试能快速定位故障的发生点;三流的测试则疲于奔命,一直跟在故障后面进行功能回归。

JAVA中常用的单元测试工具

JUnit/JUnit5

https://junit.org/junit5/

junit是老牌测试框架了,也是目前引用最广泛的一个框架。当前已经更新到Junit5,功能更强大。

class StandardTests {

    @BeforeAll
    static void initAll() {
    }

    @BeforeEach
    void init() {
    }

    @Test
    void succeedingTest() {
    }

    @Test
    void failingTest() {
        fail("a failing test");
    }

    @Test
    @Disabled("for demonstration purposes")
    void skippedTest() {
        // not executed
    }

    @Test
    void abortedTest() {
        assumeTrue("abc".contains("Z"));
        fail("test should have been aborted");
    }

    @AfterEach
    void tearDown() {
    }

    @AfterAll
    static void tearDownAll() {
    }

}

assertj

https://assertj.github.io/doc/

一个功能强悍的断言工具,支持各种断言方式

// entry point for all assertThat methods and utility methods (e.g. entry)
import static org.assertj.core.api.Assertions.*;

// basic assertions
assertThat(frodo.getName()).isEqualTo("Frodo");
assertThat(frodo).isNotEqualTo(sauron);

// chaining string specific assertions
assertThat(frodo.getName()).startsWith("Fro")
                           .endsWith("do")
                           .isEqualToIgnoringCase("frodo");

// collection specific assertions (there are plenty more)
// in the examples below fellowshipOfTheRing is a List<TolkienCharacter>
assertThat(fellowshipOfTheRing).hasSize(9)
                               .contains(frodo, sam)
                               .doesNotContain(sauron);

// as() is used to describe the test and will be shown before the error message
assertThat(frodo.getAge()).as("check %s's age", frodo.getName()).isEqualTo(33);

// Java 8 exception assertion, standard style ...
assertThatThrownBy(() -> { throw new Exception("boom!"); }).hasMessage("boom!");
// ... or BDD style
Throwable thrown = catchThrowable(() -> { throw new Exception("boom!"); });
assertThat(thrown).hasMessageContaining("boom");

// using the 'extracting' feature to check fellowshipOfTheRing character's names (Java 7)
assertThat(fellowshipOfTheRing).extracting("name")
                               .contains("Boromir", "Gandalf", "Frodo", "Legolas")
// same thing using a Java 8 method reference
assertThat(fellowshipOfTheRing).extracting(TolkienCharacter::getName)
                               .doesNotContain("Sauron", "Elrond");

// extracting multiple values at once grouped in tuples (Java 7)
assertThat(fellowshipOfTheRing).extracting("name", "age", "race.name")
                               .contains(tuple("Boromir", 37, "Man"),
                                         tuple("Sam", 38, "Hobbit"),
                                         tuple("Legolas", 1000, "Elf"));

// filtering a collection before asserting in Java 7 ... 
assertThat(fellowshipOfTheRing).filteredOn("race", HOBBIT)
                               .containsOnly(sam, frodo, pippin, merry);
// ... or in Java 8
assertThat(fellowshipOfTheRing).filteredOn(character -> character.getName().contains("o"))
                               .containsOnly(aragorn, frodo, legolas, boromir);

// combining filtering and extraction (yes we can)
assertThat(fellowshipOfTheRing).filteredOn(character -> character.getName().contains("o"))
                               .containsOnly(aragorn, frodo, legolas, boromir)
                               .extracting(character -> character.getRace().getName())
                               .contains("Hobbit", "Elf", "Man");

// and many more assertions: iterable, stream, array, map, dates (java 7 and 8), path, file, numbers, predicate, optional ...

Mockito

https://site.mockito.org/

一个单元测试中的Mock工具,可以很灵活的创建对象,配合单元测试。

// You can mock concrete classes and interfaces
TrainSeats seats = mock(TrainSeats.class);

// stubbing appears before the actual execution
when(seats.book(Seat.near(WINDOW).in(FIRST_CLASS))).thenReturn(BOOKED);

// the following prints "BOOKED"
System.out.println(seats.book(Seat.near(WINDOW).in(FIRST_CLASS)));

// the following prints "null" because 
// .book(Seat.near(AISLE).in(FIRST_CLASS))) was not stubbed
System.out.println(seats.book(Seat.near(AISLE).in(FIRST_CLASS)));

// the following verification passes because 
// .book(Seat.near(WINDOW).in(FIRST_CLASS)) has been invoked
verify(seats).book(Seat.near(WINDOW).in(FIRST_CLASS));

// the following verification fails because 
// .book(Seat.in(SECOND_CLASS)) has not been invoked
verify(seats).book(Seat.in(SECOND_CLASS));

其他

对于业务代码,有时单元测试并不方便,因为每次启动成本过高。可以使用适当的单元测试方式,比如可以提供一个测试接口,利用IDE的热部署功能实现不重启及时修改代码。

但是对于非业务性代码,进行单元测试时非常有必要的,可以更早的发现代码中的问题,同时也可以检验程序的解耦性。

良好的代码设计在单元测试时会更方便,反之紧耦合的设计会给单元测试带来很大的困扰。


以上所述就是小编给大家介绍的《JAVA中单元测试的常用方式》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

写给大忙人看的Java SE 8

写给大忙人看的Java SE 8

【美】Cay S. Horstmann(凯.S.霍斯曼) 编 / 张若飞 / 电子工业出版社 / 2014-11 / 59.00元

《写给大忙人看的Java SE 8》向Java开发人员言简意赅地介绍了Java 8 的许多新特性(以及Java 7 中许多未被关注的特性),《写给大忙人看的Java SE 8》延续了《快学Scala》“不废话”的风格。 《写给大忙人看的Java SE 8》共分为9章。第1章讲述了lambda表达式的全部语法;第2章给出了流的完整概述;第3章给出了使用lambda表达式设计库的有效技巧;第4章......一起来看看 《写给大忙人看的Java SE 8》 这本书的介绍吧!

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具