近似线性依靠matlab_不要仅仅依靠单元测试
近似線性依靠matlab
 當您構建一個復雜的系統時,僅僅測試組件是不夠的。 這很關鍵,但還不夠。 想象一下一家汽車廠生產和進口最高質量的零件,但組裝好汽車后再也沒有啟動發動機。 如果您的測試用例套件幾乎不包含單元測試,那么您將永遠無法確保系統整體正常運行。 讓我們舉一個人為的例子: 
我希望您已經在catch塊中發現了一個反模式(而且我并不是想忽略異常,這似乎是可以預期的)。 作為好公民,我們決定通過以下方式解決問題: 返回一個空集合,而不是null :
public class UserDao {public List<User> findRecentUsers() {try {return //run some query} catch(EmptyResultDataAccessException ignored) {return Collections.emptyList();}}//... }修復非常簡單,我們幾乎忘記了運行單元測試,但是以防萬一我們執行它們并發現第一個失敗的測試用例:
public class UserDaoTest {private UserDao userDao;@Beforepublic void setUp() throws Exception {userDao = new UserDao();}@Testpublic void shouldReturnNullWhenNoRecentUsers() throws Exception {//given//whenfinal List<User> result = userDao.findRecentUsers();//thenassertThat(result).isNull();}@Testpublic void shouldReturnOneRecentUser() throws Exception {//givenfinal User lastUser = new User();userDao.storeLoginEvent(lastUser);//whenfinal List<User> result = userDao.findRecentUsers();//thenassertThat(result).containsExactly(lastUser);}@Testpublic void shouldReturnTwoRecentUsers() throws Exception {//givenfinal User lastUser = new User();final User oneButLastUser = new User();userDao.storeLoginEvent(oneButLastUser);userDao.storeLoginEvent(lastUser);//whenfinal List<User> result = userDao.findRecentUsers();//thenassertThat(result).containsExactly(lastUser, oneButLastUser);}}顯然,不僅代碼被破壞了(通過返回null而不是像null的空集合),而且還有一個測試來驗證這種虛假行為。 我很確定測試是在實現之后編寫的,并且必須以某種方式處理現實。 如果沒有對實現特性的事先了解,就不會有人編寫這樣的測試。 因此,我們修復了測試,并樂意等待綠色CI的建立–最終來了。 幾天后,我們的應用程序在生產中因NullPointerException中斷。 它打破了經過徹底的單元測試的地方:
public class StatService {private final UserDao userDao;public StatService(UserDao userDao) {this.userDao = userDao;}public void welcomeMostRecentUser() {final List<User> recentUsers = userDao.findRecentUsers();if (recentUsers != null) {welcome(recentUsers.get(0));}}private void welcome(User user) {//...} }我們很驚訝,因為此類已被單元測試完全覆蓋(為清楚起見,省略了驗證步驟):
@RunWith(MockitoJUnitRunner.class) public class WelcomeServiceTest {@Mockprivate UserDao userDaoMock;private WelcomeService welcomeService;@Beforepublic void setup() {welcomeService = new WelcomeService(userDaoMock);}@Testpublic void shouldNotSendWelcomeMessageIfNoRecentUsers() throws Exception {//givengiven(userDaoMock.findRecentUsers()).willReturn(null);//whenwelcomeService.welcomeMostRecentUser();//then//verify no message sent}@Testpublic void shouldSendWelcomeMessageToMostRecentUser() throws Exception {//givengiven(userDaoMock.findRecentUsers()).willReturn(asList(new User()));//whenwelcomeService.welcomeMostRecentUser();//then//verify user welcomed}//...}您知道問題出在哪里嗎? 我們更改了UserDao類的合同,同時使它在表面上“看起來”相同。 通過修復損壞的測試,我們認為它仍然可以工作。 但是, WelcomeService仍然依賴UserDao的舊行為,該行為要么返回null ,要么返回具有至少一個元素的列表。 使用模擬框架記錄了此行為,因此我們能夠對單元中的WelcomeService進行單獨測試。 換句話說,我們無法確保這兩個組件仍然可以正常工作,我們僅對它們進行了單獨測試。 回到我們的汽車隱喻–所有部件仍然可以放在一起(相同的合同),但是其中一個部件的內部行為與以前不同。 那么,到底出了什么問題? 這里至少有四個問題,如果解決了其中任何一個,這些都不會發生。
首先, UserDao的作者未能認識到返回null而空列表似乎更直觀。 這就引出了一個問題: null和empty集合之間有顯著區別嗎? 如果是,也許您正在嘗試在單個返回值中“編碼”太多信息? 如果沒有,為什么還要增加API使用者的生活呢? 遍歷空集合不需要任何額外的工作; 對可能為null collection進行迭代需要一個額外的條件。 WelcomeService作者也因為假定null表示一個空集合而失敗。 他應該處理丑陋的API,而不是依賴它。 在這種情況下,他本可以使用CollectionUtils.isNotEmpty()并采取一些防御措施:
if (CollectionUtils.isNotEmpty(recentUsers)) {對于更全面的解決方案,他還可以考慮裝飾 UserDao并將null替換為空collection。 甚至使用AOP在整個應用程序中全局修復此類API。 順便說一句,這也適用于String 。 在99%的情況下, null ,空字符串和很少有空格的字符串之間沒有“業務”差異。 除非您真的想區分它們,否則默認情況下使用StringUtils.isBlank()或類似名稱。
 最終,“修復” UserDao的人看不到大圖。 僅僅修復單元測試是不夠的。 當您在不更改API的情況下更改類的行為時(這對于動態語言尤為重要),您很可能會錯過使用該API的地方,從而失去上下文。 但是最大的失敗是缺少組件/系統測試 。 如果我們只是簡單地測試了一個同時運行WelcomeService 和 UserDao ,那么就會發現此錯誤。 僅有100%的代碼覆蓋率是不夠的。 您測試了拼圖游戲的每一個片段,但從未看過完成的圖片。 至少進行一些較大的煙霧測試。 否則,您將不再具有如此強大的信心,即當測試呈綠色時,代碼就可以使用了。 
參考: 不要僅僅依靠我們的JCG合作伙伴 Tomasz Nurkiewicz的NoBlogDefFound博客中的單元測試 。
翻譯自: https://www.javacodegeeks.com/2013/02/dont-rely-on-unit-tests-alone.html
近似線性依靠matlab
總結
以上是生活随笔為你收集整理的近似线性依靠matlab_不要仅仅依靠单元测试的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: mvp安卓下载(mvp安卓)
- 下一篇: DDOS攻击平台(ddos平台攻击网站)
