Python中不盡如人意的斷言 Assertion

Python中的斷言用起來(lái)非常簡(jiǎn)單,你可以在assert后面跟上任意判斷條件,如果斷言失敗則會(huì)拋出異常。

>>>assert1+1==2

>>>assertisinstance('Hello',str)

>>>assertisinstance('Hello',int)

Traceback(most recent calllast):

File"",line1,in

AssertionError

其實(shí)assert看上去不錯(cuò),然而用起來(lái)并不爽。就比如有人告訴你程序錯(cuò)了,但是不告訴哪里錯(cuò)了。很多時(shí)候這樣的assert還不如不寫,寫了我就想罵娘。直接拋一個(gè)異常來(lái)得更痛快一些。

改進(jìn)方案 #1

一個(gè)稍微改進(jìn)一丟丟的方案就是把必要的信息也放到assert語(yǔ)句后面,比如這樣。

>>>s="nothin is impossible."

>>>key="nothing"

>>>assertkeyins,"Key: '{}' is not in Target: '{}'".format(key,s)

Traceback(most recent calllast):

File"",line1,in

AssertionError:Key:'nothing'isnotinTarget:'nothin is impossible.'

看上去還行吧,但是其實(shí)寫的很蛋疼。假如你是一名測(cè)試汪,有成千上萬(wàn)的測(cè)試案例需要做斷言做驗(yàn)證,相信你面對(duì)以上做法,心中一定有千萬(wàn)只那種馬奔騰而過(guò)。

改進(jìn)方案 #2

不管你是你是搞測(cè)試還是開(kāi)發(fā)的,想必聽(tīng)過(guò)不少測(cè)試框架。你猜到我要說(shuō)什么了吧?對(duì),不用測(cè)試框架里的斷言機(jī)制,你是不是灑。

py.test

py.test 是一個(gè)輕量級(jí)的測(cè)試框架,所以它壓根就沒(méi)寫自己的斷言系統(tǒng),但是它對(duì)Python自帶的斷言做了強(qiáng)化處理,如果斷言失敗,那么框架本身會(huì)盡可能多地提供斷言失敗的原因。那么也就意味著,用py.test實(shí)現(xiàn)測(cè)試,你一行代碼都不用改。

import pytest

def test_case():

expected="Hello"

actual="hello"

assertexpected==actual

if__name__=='__main__':

pytest.main()

"""

================================== FAILURES ===================================

__________________________________ test_case __________________________________

def test_case():

expected = "Hello"

actual = "hello"

>?????? assert expected == actual

E?????? assert 'Hello' == 'hello'

E???????? - Hello

E???????? ? ^

E???????? + hello

E???????? ? ^

assertion_in_python.py:7: AssertionError

========================== 1 failed in 0.05 seconds ===========================

""""

unittest

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

importunittest

classTestStringMethods(unittest.TestCase):

deftest_upper(self):

self.assertEqual('foo'.upper(),'FoO')

if__name__=='__main__':

unittest.main()

"""

Failure

Expected :'FOO'

Actual?? :'FoO'

Traceback (most recent call last):

File "assertion_in_python.py", line 6, in test_upper

self.assertEqual('foo'.upper(), 'FoO')

AssertionError: 'FOO' != 'FoO'

"""

ptest

我非常喜歡ptest,感謝Karl大神寫了這么一個(gè)測(cè)試框架。ptest中的斷言可讀性很好,而且智能提示也很方便你通過(guò)IDE輕松完成各種斷言語(yǔ)句。

fromptest.decoratorimport*

fromptest.assertionimport*

@TestClass()

classTestCases:

@Test()

deftest1(self):

actual='foo'

expected='bar'

assert_that(expected).is_equal_to(actual)

"""

Start to run following 1 tests:

------------------------------

...

[demo.assertion_in_python.TestCases.test1@Test] Failed with following message:

...

AssertionError: Unexpectedly that the str is not equal to str .

"""

改進(jìn)方案 #3

不僅僅是你和我對(duì)Python中的斷言表示不滿足,所以大家都爭(zhēng)相發(fā)明自己的assert包。在這里我強(qiáng)烈推薦assertpy 這個(gè)包,它異常強(qiáng)大而且好評(píng)如潮。

pip install assertpy

看例子:

fromassertpyimportassert_that

deftest_something():

assert_that(1+2).is_equal_to(3)

assert_that('foobar')\

.is_length(6)\

.starts_with('foo')\

.ends_with('bar')

assert_that(['a','b','c'])\

.contains('a')\

.does_not_contain('x')

從它的github 主頁(yè) 文檔上你會(huì)發(fā)現(xiàn)它支持了幾乎你能想到的所有測(cè)試場(chǎng)景,包括但不限于以下列表。

Strings

Numbers

Lists

Tuples

Dicts

Sets

Booleans

Dates

Files

Objects

而且它的斷言信息簡(jiǎn)潔明了,不多不少。

Expectedto be oflength<4>,butwas<3>.

Expectedto be empty string,but wasnot.

Expected,but wasnot.

Expectedto contain onlydigits,but didnot.

Expected<123>to contain only alphabeticchars,but didnot.

Expectedto contain only uppercasechars,but didnot.

Expectedto contain only lowercasechars,but didnot.

Expectedto be equalto,but wasnot.

Expectedto benotequalto,butwas.

Expectedto becase-insensitive equalto,but wasnot.

在發(fā)現(xiàn)assertpy之前我也想寫一個(gè)類似的包,盡可能通用一些。但是現(xiàn)在,我為毛要重新去造輪子?完全沒(méi)必要!

總結(jié)

斷言在軟件系統(tǒng)中有非常重要的作用,寫的好可以讓你的系統(tǒng)更穩(wěn)定,也可以讓你有更多真正面對(duì)對(duì)象的時(shí)間,而不是在調(diào)試代碼。

Python中默認(rèn)的斷言語(yǔ)句其實(shí)還有一個(gè)作用,如果你寫了一個(gè)類型相關(guān)的斷言,IDE會(huì)把這個(gè)對(duì)象當(dāng)成這種類型,這時(shí)候智能提示就有如神助。

要不要把內(nèi)置的斷言語(yǔ)句換成可讀性更好功能更強(qiáng)大的第三方斷言,完全取決于實(shí)際情況。比如你真的需要驗(yàn)證某個(gè)東西并且很關(guān)心驗(yàn)證結(jié)果,那么必須不能用簡(jiǎn)單的assert;如果你只是擔(dān)心某個(gè)點(diǎn)可能有坑或者讓IDE認(rèn)識(shí)某個(gè)對(duì)象,用內(nèi)置的assert既簡(jiǎn)單又方便。

所以說(shuō),項(xiàng)目經(jīng)驗(yàn)還是蠻重要的。怎么樣才能學(xué)好python學(xué)好python你需要一個(gè)良好的環(huán)境,一個(gè)優(yōu)質(zhì)的開(kāi)發(fā)交流群,群里都是那種相互幫助的人才是可以的,我有建立一個(gè)python學(xué)習(xí)交流群,在群里我們相互幫助,相互關(guān)心,相互分享內(nèi)容,這樣出問(wèn)題幫助你的人就比較多,群號(hào)是301,還有056,最后是051,這樣就可以找到大神聚合的群,如果你只愿意別人幫助你,不愿意分享或者幫助別人,那就請(qǐng)不要加了,你把你會(huì)的告訴別人這是一種分享。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,569評(píng)論 19 139
  • Startup 單元測(cè)試的核心價(jià)值在于兩點(diǎn): 更加精確地定義某段代碼的作用,從而使代碼的耦合性更低 避免程序員寫出...
    wuwenxiang閱讀 10,234評(píng)論 1 27
  • Python 四五事 介紹 Python 相關(guān)工具,工作流程和測(cè)試框架。 發(fā)布于 2014.1.19最后更新 20...
    hzyido閱讀 65,118評(píng)論 0 4
  • 第一章 邊城暗流 (6) 木影悠悠醒來(lái),強(qiáng)烈的白光讓他雙目出現(xiàn)暫時(shí)的恍惚,頭腦微微刺痛,像是做了一場(chǎng)大夢(mèng)。 “你這...
    非愛(ài)閱讀 450評(píng)論 0 0
  • 七月過(guò)去了,做一下總結(jié)。 1:做了22天精美早餐 2:記錄晚餐15天 3:每天寫博客,寫新浪博客31篇,發(fā)微信31...
    心境如花閱讀 275評(píng)論 0 0

友情鏈接更多精彩內(nèi)容