摘要:中常用的單元測(cè)試工具是老牌測(cè)試框架了,也是目前引用最廣泛的一個(gè)框架??梢允褂眠m當(dāng)?shù)膯卧獪y(cè)試方式,比如可以提供一個(gè)測(cè)試接口,利用的熱部署功能實(shí)現(xiàn)不重啟及時(shí)修改代碼。
什么是單元測(cè)試
單元測(cè)試(英語(yǔ):Unit Testing)又稱為模塊測(cè)試, 是針對(duì)程序模塊(軟件設(shè)計(jì)的最小單位)來(lái)進(jìn)行正確性檢驗(yàn)的測(cè)試工作。程序單元是應(yīng)用的最小可測(cè)試部件。在過(guò)程化編程中,一個(gè)單元就是單個(gè)程序、函數(shù)、過(guò)程等;對(duì)于面向?qū)ο缶幊?,最小單元就是方法,包括基類(超類)、抽象類、或者派生類(子類)中的方法?br>通常來(lái)說(shuō),程序員每修改一次程序就會(huì)進(jìn)行最少一次單元測(cè)試,在編寫程序的過(guò)程中前后很可能要進(jìn)行多次單元測(cè)試,以證實(shí)程序達(dá)到軟件規(guī)格書要求的工作目標(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
https://junit.org/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 ListMockitoassertThat(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 ...
https://site.mockito.org/
一個(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)很大的困擾。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/77861.html
摘要:三使用介紹通過(guò)代碼創(chuàng)建通過(guò)注解四常用方法驗(yàn)證方法沒(méi)有被調(diào)用驗(yàn)證方法被調(diào)用了次方法至少被調(diào)用次方法最多被調(diào)用次備注假如你無(wú)法給你程序?qū)憜卧獪y(cè)試,那么意味著你的程序結(jié)構(gòu)有問(wèn)題,需要調(diào)整或重構(gòu)。 Java單元測(cè)試入門 什么是單元測(cè)試 定義:?jiǎn)卧獪y(cè)試是對(duì)軟件或程序的基本(最?。┙M成單元的測(cè)試對(duì)象:方法、類特點(diǎn):showImg(https://segmentfault.com/img/bVbcR...
摘要:?jiǎn)卧獪y(cè)試框架作為的標(biāo)準(zhǔn)庫(kù),是其他單元測(cè)試框架的基礎(chǔ)??梢院秃团浜鲜褂镁帉憜卧獪y(cè)試。官網(wǎng)地址單元測(cè)試覆蓋率工具單元測(cè)試中還需要用到代碼覆蓋率工具。代碼覆蓋率統(tǒng)計(jì)工具用來(lái)發(fā)現(xiàn)沒(méi)有被測(cè)試覆蓋的代碼,完善單元測(cè)試的覆蓋率。 在應(yīng)用程序中,單元是具有一個(gè)或多個(gè)輸入和單個(gè)輸出的軟件中最小可測(cè)試部分。單元...
摘要:請(qǐng)注意,我們?cè)诹牧膯卧獪y(cè)試遇到問(wèn)題多思考多查閱多驗(yàn)證,方能有所得,再勤快點(diǎn)樂(lè)于分享,才能寫出好文章。單元測(cè)試是指對(duì)軟件中的最小可測(cè)試單元進(jìn)行檢查和驗(yàn)證。 JAVA容器-自問(wèn)自答學(xué)HashMap 這次我和大家一起學(xué)習(xí)HashMap,HashMap我們?cè)诠ぷ髦薪?jīng)常會(huì)使用,而且面試中也很頻繁會(huì)問(wèn)到,因?yàn)樗锩嫣N(yùn)含著很多知識(shí)點(diǎn),可以很好的考察個(gè)人基礎(chǔ)。但一個(gè)這么重要的東西,我為什么沒(méi)有在一開(kāi)始...
摘要:在年年初,公司通過(guò)調(diào)查名開(kāi)發(fā)者來(lái)了解開(kāi)發(fā)者的生態(tài)狀態(tài),最近,調(diào)查結(jié)果終于整理完畢,以下是得出的結(jié)果。注報(bào)告會(huì)分多成多個(gè)部分,此為第一部分。 在2018年年初,jetbrains公司通過(guò)調(diào)查6000名開(kāi)發(fā)者來(lái)了解開(kāi)發(fā)者的生態(tài)狀態(tài),最近,調(diào)查結(jié)果終于整理完畢,以下是得出的結(jié)果。一、 日常工作1.1)流行語(yǔ)言:今年,使用最受歡迎、最常用與最有前途的語(yǔ)言相較去年沒(méi)有變化,最受歡迎的語(yǔ)言是...
摘要:在年年初,公司通過(guò)調(diào)查名開(kāi)發(fā)者來(lái)了解開(kāi)發(fā)者的生態(tài)狀態(tài),最近,調(diào)查結(jié)果終于整理完畢,以下是得出的結(jié)果。注報(bào)告會(huì)分多成多個(gè)部分,此為第一部分。 在2018年年初,jetbrains公司通過(guò)調(diào)查6000名開(kāi)發(fā)者來(lái)了解開(kāi)發(fā)者的生態(tài)狀態(tài),最近,調(diào)查結(jié)果終于整理完畢,以下是得出的結(jié)果。一、 日常工作1.1)流行語(yǔ)言:今年,使用最受歡迎、最常用與最有前途的語(yǔ)言相較去年沒(méi)有變化,最受歡迎的語(yǔ)言是...
閱讀 3041·2023-04-25 17:46
閱讀 3698·2021-11-25 09:43
閱讀 1178·2021-11-18 10:02
閱讀 3129·2021-10-14 09:43
閱讀 2878·2021-10-13 09:40
閱讀 1587·2021-09-28 09:35
閱讀 2267·2019-08-30 15:52
閱讀 3218·2019-08-30 14:06