天天看點

《JUnit實戰(第2版)》—第1章1.1節證明它能運作

本節書摘來自異步社群《junit實戰(第2版)》一書中的第1章1.1節證明它能運作,作者【美】petar tahchiev , felipe leme , vincent massol , gary gregory,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

第1部分 認識junit

junit實戰(第2版)

歡迎閱讀《junit實戰(第2版)》!junit是一個由kent beck和erich gamma于1995年年底着手編寫的架構。自此以後,junit架構日益普及,現在已經成為單元測試java應用程式的事實上的标準。

本書是第2版。《junit實戰》的第1版非常暢銷,由vincent massol和ted husted于2003年編寫,其内容是基于junit 3.x版本的。

我們涵蓋了junit最新的版本4.6,讨論了許多第1版尚未介紹的功能。與此同時,我們關注其他一些有趣的測試代碼的方法:mock objects、junit擴充、測試應用程式的不同層,等等。

這一部分從探索junit本身開始。在本書後面的章節中,我們将專注于另一些工具和方法。

第1章快速介紹了測試的概念。你需要從基礎知識入手逐漸深入。在本章的後半部分,我們會直接跳到代碼内容,檢視如何編寫簡單的測試、運作它并看到運作結果。

第2章介紹了junit最核心的内容。我們建構了一個稍大型的項目,并分析其代碼。我們不僅解釋了junit的概念、widget和内部構成,也為你展示了編寫測試用例的最佳做法,并利用建構的項目對它們進行了說明。

第3章重點介紹了測試。我們描述了各種各樣的測試以及它們所适用的情況。我們還探讨了不同的平台(如開發、生産等),并展示了哪種測試和哪種情況能夠在這些平台上最好地執行。

第1部分的最後一章緻力于提升你的測試技巧。我們告訴你如何衡量測試覆寫面以及如何提高測試覆寫面。我們也解釋了如何在編寫測試之前生成可測試的代碼,如何在動手編寫代碼之前編寫測試。

第1章 unit起步

never in the field of software development was so much owed by so many to so few lines of code.

在軟體開發領域中,從來沒有這樣的事情:少數幾行代碼對大量代碼起着如此重要的作用。

——martin fowler

本章重點

探索junit

安裝junit

編寫第一個測試

運作測試

所有的代碼都需要進行測試。

在開發期間,我們所做的第一件事是運作程式員自己的“驗收測試”。我們編碼、編譯并運作。當我們運作時,我們就在進行測試。測試可能隻是點選一個按鈕,看它是否能彈出預期的菜單。然而,每天我們都要進行編碼、編譯、運作和測試。

當我們測試時,我們經常會發現各種問題——尤其是第一次運作時。于是,我們重新編碼、編譯、運作和測試。我們中的大多數人會迅速形成一種非正式的測試模式:添加一條記錄、檢視一條記錄、編輯一條記錄以及删除一條記錄。手動運作諸如此類的小測試集是非常容易做到的,是以我們會不斷重複這個操作。

有些程式員喜歡這類重複性的測試。在經曆深入的思索和艱難的編碼後,這類重複性的操作可以帶來一段愉快的小憩。當我們小小的點選測試終于成功時,一股成就感便會油然升起:搞定了!我搞定了!

但有一些程式員卻不喜歡重複性的工作。與其手動運作測試,他們甯願建立一個小程式來自動運作測試。編寫測試代碼是一回事,而運作自動測試是另一回事。

如果你是一名編寫測試代碼的開發人員,那麼這本書就是為你而準備的。我們将為你展示建立自動測試是多麼簡單、有效,甚至有趣。

如果你是一名深受測試影響的開發人員(test-infected1),那麼這本書同樣适合你。我們在第1部分介紹了基礎知識,然後在第2、第3和第4部分繼續探讨實際工作中的各種疑難雜症。

1test-infected是由gamma和beck建立的一個術語,參見《test-infected: programmers love writing tests》,java report, 3, 7, 37–50: 1998。

1.1 證明它能運作

一些開發人員認為自動測試是開發過程中非常重要的一部分。你無法證明一個元件能夠運作,除非它通過了一系列全面的測試。有兩名開發人員覺得這類單元測試如此重要,以至于值得為它編寫一個架構。1997年,erich gamma和kent beck針對java建立了一個簡單但有效的單元測試架構,叫做junit。他們的工作遵循了sunit的設計,而sunit是kent beck早期為smalltalk建立的一個架構。

nition 架構*

個應用程式的半成品{![ralph e. johnson and brian foote, “designing reusable classes,” journal of object-oriented programming __1.5 (june/july 1988): 22–35;架構提供了一個可複用的公共結構,可以在多個應用程式之間進行共享。開發人員将架構融入到他們自己的應用程式中,并且加以擴充以滿足他們特定的需求。架構與工具包的不同之處在于,架構提供了一緻的結構,而不隻是一組簡單的工具類。

如果你對這些名字似曾相識,那很正常。erich gamma就是為我們帶來經典之作《模式設計》1的四大作者之一。同樣,kent beck由于他在軟體開發方面的開創性成就“極限程式設計”而廣為人知。

junit是sourceforge網站上的一款開源軟體,根據ibm通用公共許可證(common public license)1.0版本進行釋出。通用公共許可證 對商業使用者是友好的:人們可以随同商業産品分發junit,而沒有很多繁瑣的手續和限制。

junit迅速成為java中開發單元測試的事實上的标準架構。被稱為xunit的相關測試架構,正在逐漸成為任何語言的标準架構。asp、c++、c#、eiffel、delphi、perl、php、python、rebol、smalltalk和visual basic都有了對應的xunit架構,這裡隻是列舉了一些而已。

junit團隊并沒有發明軟體測試,甚至也沒有發明單元測試。起初,單元測試這個術語隻是用來描述一項檢查單個工作單元的行為的測試。

随着時間的推移,單元測試這一術語的運用領域擴充了。例如,ieee已經将單元測試定義為“單個硬體、軟體單元或一組相關單元的測試”2。

在本書中,單元測試隻是指窄義上的一種測試:檢查與其他單元隔離的單個單元。我們重點關注的是程式員應用在他們自己代碼中的小型漸增測試。有時我們把這種測試稱為programmer test,以差別于品質保證測試(qa)和客戶測試。

以我們的角度來看,一個典型的單元測試通常可以描述為:“確定方法接受預期範圍内的輸入,并且為每一次測試輸入傳回預期的值”。

以上描述要求我們通過方法的接口來測試方法的行為。如果我們将x值傳給方法,那麼它會傳回y值嗎?如果我們改為将z值傳給方法,那麼它會正确地抛出異常嗎?

definition

單元測試檢查一個獨立工作單元的行為。在java應用程式中,獨立工作單元經常是(但不總是)一個獨立方法。相比之下,內建測試和驗收測試檢查的是各種元件如何互動。一個工作單元就是一項任務,不直接依賴于其他任何任務的完成。

單元測試通常關注的是一個方法是否遵循了它的api契約中的條款。就像人們在特定條件下同意交換某種商品或服務時所簽署的書面合同,api契約是一份由方法簽名而生成的正式協定,方法需要它的調用者提供特定的對象引用(object reference)或原始類型數值(primitive value),然後傳回一個對象引用或原始類型數值。如果方法不能遵守契約,測試将抛出異常,于是我們就說方法已經破壞了它的契約。

在這一章裡,我們從零開始介紹如何為一個簡單的類建立單元測試。我們首先編寫一個測試以及運作該測試的最小架構,以便你能夠了解我們是如何處理的。然後我們再通過junit向你展示,正确的工具可以如何使生活變得更加簡單。

api契約是一種觀點:把一個應用程式程式設計接口(api)當作是在調用者與被調用者之間的正式協定。通常,單元測試通過證明預期的行為來幫助定義api契約。api契約的概念源于因eiffel程式設計語言而流行的“design by contract”的實踐。

1erich gamma et al., design patterns(reading, ma: addison-wesley, 1995).

2eee standard computer dictionary: a compilation of ieee standard computer glossaries (new york, ieee, 1990).

本文僅用于學習和交流目的,不代表異步社群觀點。非商業轉載請注明作譯者、出處,并保留本文的原始連結。