Python中不盡如人意的斷言 Assertion

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

>>>assert1+1==2

>>>assertisinstance('Hello',str)

>>>assertisinstance('Hello',int)

Traceback(most recent calllast):

File"",line1,in

AssertionError

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

改進(jìn)方案 #1

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

>>>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è)試汪蒿辙,有成千上萬的測(cè)試案例需要做斷言做驗(yàn)證,相信你面對(duì)以上做法,心中一定有千萬只那種馬奔騰而過须板。

改進(jìn)方案 #2

不管你是你是搞測(cè)試還是開發(fā)的碰镜,想必聽過不少測(cè)試框架。你猜到我要說什么了吧习瑰?對(duì),不用測(cè)試框架里的斷言機(jī)制秽荤,你是不是灑甜奄。

py.test

py.test 是一個(gè)輕量級(jí)的測(cè)試框架,所以它壓根就沒寫自己的斷言系統(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語句。

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中的斷言可讀性很好,而且智能提示也很方便你通過IDE輕松完成各種斷言語句腹缩。

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 主頁 文檔上你會(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)在,我為毛要重新去造輪子菇曲?完全沒必要冠绢!

總結(jié)

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

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

要不要把內(nèi)置的斷言語句換成可讀性更好功能更強(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)單又方便。

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末伴箩,一起剝皮案震驚了整個(gè)濱河市入愧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嗤谚,老刑警劉巖棺蛛,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異巩步,居然都是意外死亡旁赊,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門椅野,熙熙樓的掌柜王于貴愁眉苦臉地迎上來终畅,“玉大人籍胯,你說我怎么就攤上這事±敫#” “怎么了杖狼?”我有些...
    開封第一講書人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)妖爷。 經(jīng)常有香客問我蝶涩,道長(zhǎng),這世上最難降的妖魔是什么絮识? 我笑而不...
    開封第一講書人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任子寓,我火速辦了婚禮,結(jié)果婚禮上笋除,老公的妹妹穿的比我還像新娘。我一直安慰自己炸裆,他們只是感情好垃它,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著烹看,像睡著了一般国拇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惯殊,一...
    開封第一講書人閱讀 51,624評(píng)論 1 305
  • 那天酱吝,我揣著相機(jī)與錄音,去河邊找鬼土思。 笑死务热,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的己儒。 我是一名探鬼主播崎岂,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼闪湾!你這毒婦竟也來了冲甘?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤途样,失蹤者是張志新(化名)和其女友劉穎江醇,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體何暇,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡陶夜,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了赖晶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片律适。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡辐烂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出捂贿,到底是詐尸還是另有隱情纠修,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布厂僧,位于F島的核電站扣草,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏颜屠。R本人自食惡果不足惜辰妙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望甫窟。 院中可真熱鬧密浑,春花似錦、人聲如沸粗井。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽浇衬。三九已至懒构,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間耘擂,已是汗流浹背胆剧。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留醉冤,地道東北人秩霍。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像冤灾,于是被迫代替她去往敵國和親前域。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

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