Python中不盡如人意的斷言Assertion

發表於2016-10-27

Python中的斷言用起來非常簡單,你可以在assert後面跟上任意判斷條件,如果斷言失敗則會丟擲異常。


其實assert看上去不錯,然而用起來並不爽。就比如有人告訴你程式錯了,但是不告訴哪裡錯了。很多時候這樣的assert還不如不寫,寫了我就想罵娘。直接拋一個異常來得更痛快一些。

改進方案 #1

一個稍微改進一丟丟的方案就是把必要的資訊也放到assert語句後面,比如這樣。

看上去還行吧,但是其實寫的很蛋疼。假如你是一名測試汪,有成千上萬的測試案例需要做斷言做驗證,相信你面對以上做法,心中一定有千萬只那種馬奔騰而過。

改進方案 #2

不管你是你是搞測試還是開發的,想必聽過不少測試框架。你猜到我要說什麼了吧?對,不用測試框架裡的斷言機制,你是不是灑。

py.test

py.test 是一個輕量級的測試框架,所以它壓根就沒寫自己的斷言系統,但是它對Python自帶的斷言做了強化處理,如果斷言失敗,那麼框架本身會盡可能多地提供斷言失敗的原因。那麼也就意味著,用py.test實現測試,你一行程式碼都不用改。

unittest

Python自帶的unittest單元測試框架就有了自己的斷言方法self.assertXXX(),而且不推薦使用assert XXX語句。

ptest

我非常喜歡ptest,感謝Karl大神寫了這麼一個測試框架。ptest中的斷言可讀性很好,而且智慧提示也很方便你通過IDE輕鬆完成各種斷言語句。

改進方案 #3

不僅僅是你和我對Python中的斷言表示不滿足,所以大家都爭相發明自己的assert包。在這裡我強烈推薦assertpy 這個包,它異常強大而且好評如潮。

看例子:

從它的github 主頁 文件上你會發現它支援了幾乎你能想到的所有測試場景,包括但不限於以下列表。

  • Strings
  • Numbers
  • Lists
  • Tuples
  • Dicts
  • Sets
  • Booleans
  • Dates
  • Files
  • Objects

而且它的斷言資訊簡潔明瞭,不多不少。

在發現assertpy之前我也想寫一個類似的包,儘可能通用一些。但是現在,我為毛要重新去造輪子?完全沒必要!

總結

斷言在軟體系統中有非常重要的作用,寫的好可以讓你的系統更穩定,也可以讓你有更多真正面對物件的時間,而不是在除錯程式碼。

Python中預設的斷言語句其實還有一個作用,如果你寫了一個型別相關的斷言,IDE會把這個物件當成這種型別,這時候智慧提示就有如神助。

要不要把內建的斷言語句換成可讀性更好功能更強大的第三方斷言,完全取決於實際情況。比如你真的需要驗證某個東西並且很關心驗證結果,那麼必須不能用簡單的assert;如果你只是擔心某個點可能有坑或者讓IDE認識某個物件,用內建的assert既簡單又方便。

所以說,專案經驗還是蠻重要的。

相關文章