JAVA中單元測(cè)試的常用方式(小結(jié))
什么是單元測(cè)試
單元測(cè)試(英語(yǔ):Unit Testing)又稱(chēng)為模塊測(cè)試, 是針對(duì)程序模塊(軟件設(shè)計(jì)的最小單位)來(lái)進(jìn)行正確性檢驗(yàn)的測(cè)試工作。程序單元是應(yīng)用的最小可測(cè)試部件。在過(guò)程化編程中,一個(gè)單元就是單個(gè)程序、函數(shù)、過(guò)程等;對(duì)于面向?qū)ο缶幊?,最小單元就是方法,包括基?lèi)(超類(lèi))、抽象類(lèi)、或者派生類(lèi)(子類(lèi))中的方法。
通常來(lái)說(shuō),程序員每修改一次程序就會(huì)進(jìn)行最少一次單元測(cè)試,在編寫(xiě)程序的過(guò)程中前后很可能要進(jìn)行多次單元測(cè)試,以證實(shí)程序達(dá)到軟件規(guī)格書(shū)要求的工作目標(biāo),沒(méi)有程序錯(cuò)誤;雖然單元測(cè)試不是什么必須的,但也不壞,這牽涉到項(xiàng)目管理的政策決定。
單元測(cè)試的優(yōu)點(diǎn)
優(yōu)質(zhì)的單元測(cè)試可以保障開(kāi)發(fā)質(zhì)量和程序的魯棒性。在大多數(shù)互聯(lián)網(wǎng)企業(yè)中開(kāi)發(fā)工程師在研發(fā)過(guò)程中都會(huì)頻繁地執(zhí)行測(cè)試用例,運(yùn)行失敗的單測(cè)能幫助我們快速排查和定位問(wèn)題 使問(wèn)題在被帶到線上之前完成修復(fù)。正如軟件工程界的一條金科玉律----越早發(fā)現(xiàn)的缺陷,其修復(fù)成本越低。一流的測(cè)試能發(fā)現(xiàn)未發(fā)生的故障;二流的測(cè)試能快速定位故障的發(fā)生點(diǎn);三流的測(cè)試則疲于奔命,一直跟在故障后面進(jìn)行功能回歸。
JAVA中常用的單元測(cè)試工具
JUnit/JUnit5
junit是老牌測(cè)試框架了,也是目前引用最廣泛的一個(gè)框架。當(dāng)前已經(jīng)更新到Junit5,功能更強(qiáng)大。
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/
一個(gè)功能強(qiáng)悍的斷言工具,支持各種斷言方式
// 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
一個(gè)單元測(cè)試中的Mock工具,可以很靈活的創(chuàng)建對(duì)象,配合單元測(cè)試。
// 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));
其他
對(duì)于業(yè)務(wù)代碼,有時(shí)單元測(cè)試并不方便,因?yàn)槊看螁?dòng)成本過(guò)高??梢允褂眠m當(dāng)?shù)膯卧獪y(cè)試方式,比如可以提供一個(gè)測(cè)試接口,利用IDE的熱部署功能實(shí)現(xiàn)不重啟及時(shí)修改代碼。
但是對(duì)于非業(yè)務(wù)性代碼,進(jìn)行單元測(cè)試時(shí)非常有必要的,可以更早的發(fā)現(xiàn)代碼中的問(wèn)題,同時(shí)也可以檢驗(yàn)程序的解耦性。
良好的代碼設(shè)計(jì)在單元測(cè)試時(shí)會(huì)更方便,反之緊耦合的設(shè)計(jì)會(huì)給單元測(cè)試帶來(lái)很大的困擾。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 解決java junit單元測(cè)試@Test報(bào)錯(cuò)的問(wèn)題
- java實(shí)現(xiàn)連接mysql數(shù)據(jù)庫(kù)單元測(cè)試查詢數(shù)據(jù)的實(shí)例代碼
- java單元測(cè)試JUnit框架原理與用法實(shí)例教程
- 詳解Java單元測(cè)試之JUnit篇
- Java Junit單元測(cè)試實(shí)例詳解
- 詳解Java單元測(cè)試Junit框架實(shí)例
- 詳解Java單元測(cè)試之Junit框架使用教程
- 淺談Java 中的單元測(cè)試
- Java通過(guò)PowerMockito和Mokito進(jìn)行單元測(cè)試的實(shí)現(xiàn)
相關(guān)文章
Java中枚舉的實(shí)現(xiàn)與應(yīng)用詳解
這篇文章主要介紹了Java中枚舉的實(shí)現(xiàn)與應(yīng)用詳解,EnumTest中還有一個(gè)VALUES數(shù)組,里面存儲(chǔ)著所有的枚舉實(shí)例,調(diào)用values方法時(shí)返回VALUES數(shù)組的clone,需要的朋友可以參考下2023-12-12
Installij IDEA install或clean項(xiàng)目的使用
這篇文章主要介紹了Installij IDEA install或clean項(xiàng)目的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
Eclipse中實(shí)現(xiàn)JS代碼提示功能(圖文教程)
本文通過(guò)圖文并茂的形式給大家介紹了Eclipse中實(shí)現(xiàn)JS代碼提示功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2017-11-11
CMD運(yùn)行Intellij Idea編譯后的class文件操作
這篇文章主要介紹了CMD運(yùn)行Intellij Idea編譯后的class文件操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02
javaweb學(xué)習(xí)總結(jié)——使用JDBC處理MySQL大數(shù)據(jù)
本篇文章主要介紹了JDBC處理MySQL大數(shù)據(jù),有時(shí)是需要用程序把大文本或二進(jìn)制數(shù)據(jù)直接保存到數(shù)據(jù)庫(kù)中進(jìn)行儲(chǔ)存的,非常具有實(shí)用價(jià)值,需要的朋友可以參考下。2016-11-11
深入詳解java高并發(fā)熱點(diǎn)數(shù)據(jù)更新
這篇文章主要為大家深入介紹了java高并發(fā)熱點(diǎn)數(shù)據(jù)更新詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
SpringBoot yaml語(yǔ)法與數(shù)據(jù)讀取操作詳解
YAML 是 “YAML Ain’t Markup Language”(YAML 不是一種標(biāo)記語(yǔ)言)的遞歸縮寫(xiě)。在開(kāi)發(fā)的這種語(yǔ)言時(shí),YAML 的意思其實(shí)是:“Yet Another Markup Language”(仍是一種標(biāo)記語(yǔ)言),本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07

