
…并描述了一種非常通用的測試技術: 不編寫測試 , 而是手動進行所有操作。
今天的博客涵蓋了另一種實踐,我也認為這是次優的。 在這種情況下,開發人員使用JUnit編寫測試,但是在完成編寫代碼之后并且沒有任何類隔離的情況下編寫測試。 這實際上是冒充單元測試的“端到端”(又稱集成)測試。
盡管昨天我說過我只測試AddressService類,但是使用此技術的測試首先從數據庫中加載一些測試數據,然后抓住AddressController來調用被測方法。 AddressController調用AddressService ,然后再調用AddressDao以獲取并返回所請求的數據。
@RunWith(UnitilsJUnit4TestClassRunner.class)
@SpringApplicationContext("servlet-context.xml")
@Transactional(TransactionMode.DISABLED)
public class EndToEndAddressServiceTest {@SpringBeanByTypeprivate AddressController instance;/*** Test method for* {@link com.captaindebug.address.AddressService#findAddress(int)}.*/@Testpublic void testFindAddressWithNoAddress() {final int id = 10;BindingAwareModelMap model = new BindingAwareModelMap();String result = instance.findAddress(id, model);assertEquals("address-display", result);Address resultAddress = (Address) model.get("address");assertEquals(Address.INVALID_ADDRESS, resultAddress);}/*** Test method for* {@link com.captaindebug.address.AddressService#findAddress(int)}.*/@Test@DataSet("FindAddress.xml")public void testFindAddress() {final int id = 1;Address expected = new Address(id, "15 My Street", "My Town","POSTCODE", "My Country");BindingAwareModelMap model = new BindingAwareModelMap();String result = instance.findAddress(id, model);assertEquals("address-display", result);Address resultAddress = (Address) model.get("address");assertEquals(expected.getId(), resultAddress.getId());assertEquals(expected.getStreet(), resultAddress.getStreet());assertEquals(expected.getTown(), resultAddress.getTown());assertEquals(expected.getPostCode(), resultAddress.getPostCode());assertEquals(expected.getCountry(), resultAddress.getCountry());}
}
上面的代碼使用Unitils將測試數據加載到數據庫中并在Spring上下文中加載類。 我發現Nevers是一個有用的工具,它消除了編寫此類測試的繁瑣工作,而必須設置如此大規模的測試是一項艱巨的工作。
這種測試必須在代碼完成后編寫; 它不是測試驅動的開發(從以前的博客中可以看到,我是一個忠實的擁護者),它也不是單元測試。 在代碼后編寫測試的問題之一是必須執行測試的開發人員將其視為瑣事而不是開發的一部分,這意味著它通常很匆忙,而不是在編碼風格的整潔中完成的。
您還需要一定數量的基礎結構才能使用此技術進行編碼,因為需要建立數據庫,而數據庫可能會或可能不在您的本地計算機上,因此您可能必須連接到網絡才能運行測試。 測試數據要么保存在測試文件中(如本例所示),然后在運行測試時加載到數據庫中,要么永久保存在數據庫中。 如果需求變更迫使測試發生變更,則通常需要將數據庫文件與測試代碼一起進行更新,這迫使您至少在兩個位置更新測試。
除了缺乏測試對象隔離之外,這種測試的另一個大問題是它們可能非常慢,有時要花幾秒鐘來執行。 Shane Warden在他的《敏捷開發的藝術》一書中指出,單元測試的運行速度應為“每秒數百”。 沃登還繼續引用邁克爾·費瑟(Michael Feather)的書《有效地使用舊版代碼》 ,以明確定義什么單元測試或不可以:
在以下情況下,測試不是單元測試:
- 它與數據庫對話。
- 它通過網絡進行通信。
- 它涉及文件系統。
- 您必須對環境做一些特殊的事情(例如編輯配置文件)才能運行它。
…現在我喜歡。
…盡管我不一定同意第三點。 良好的單元測試代碼的主要租戶之一是可讀性。 傳遞給被測對象的方法參數有時會很大,尤其是在使用XML時。 在這種情況下,我認為支持測試的可讀性并將這種大小的數據存儲在數據文件中而不是將其作為私有的靜態最終String更為實用,因此在可行的情況下,我只堅持第3點。
可以使用第一個首字母縮寫來總結單元測試:快速,獨立,可重復,自我驗證和及時,而Roy Osherove在他的《單元測試的藝術》一書中總結了一個很好的單元測試:“自動代碼調用方法或類,然后檢查有關該方法或類的邏輯行為的一些假設。 單元測試幾乎總是使用單元測試框架編寫的。 它可以輕松編寫并快速運行。 它是完全自動化的,可信賴的,可讀的和可維護的”。
端到端測試的好處是,他們確實會與其他對象和周圍環境一起測試您的測試主題,而這在交付代碼之前確實是必須要做的。 這意味著完成后,您的代碼應包含數百個單元測試,但僅包含數十個“端到端”測試。
鑒于此,當我說技術是“次優”時,我的介紹性前提并不嚴格。 “端到端”測試沒有任何問題,每個項目都應該有一些測試以及一些普通的集成測試,但是這類測試不能替代或稱為單元測試,通常是這種情況。
確定了單元測試的內容后,我的下一個博客將調查您應測試的內容以及原因……
參考: Captain Debug博客上的 JCG合作伙伴
的“ 端到端測試的濫用-測試技術2”相關文章 :
- 測試技巧–不編寫測試
- 您應該對什么進行單元測試? –測試技術3
- 常規單元測試和存根–測??試技術4
- 使用模擬的單元測試–測試技術5
- 為舊版代碼創建存根–測試技術6
- 有關為舊版代碼創建存根的更多信息–測試技術7
- 為什么要編寫單元測試–測試技巧8
- 一些定義–測試技術9
- 使用FindBugs產生更少的錯誤代碼
- 在云中開發和測試
翻譯自: https://www.javacodegeeks.com/2011/11/misuse-of-end-to-end-tests-testing.html