在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Python/ 測(cè)試詩(shī)歌
小插曲 Deferred
異步編程模式與Reactor初探
使用Deferred新功能實(shí)現(xiàn)新客戶端
由twisted支持的客戶端
增強(qiáng)defer功能的客戶端
改進(jìn)詩(shī)歌下載服務(wù)器
測(cè)試詩(shī)歌
更加"抽象"的運(yùn)用Twisted
Deferred用于同步環(huán)境
輪子內(nèi)的輪子: Twisted和Erlang
Twisted 進(jìn)程守護(hù)
構(gòu)造"回調(diào)"的另一種方法
Twisted 理論基礎(chǔ)
惰性不是遲緩: Twisted和Haskell
第二個(gè)小插曲,deferred
使用Deferred的詩(shī)歌下載客戶端
Deferreds 全貌
結(jié)束
取消之前的意圖
由Twisted扶持的客戶端
改進(jìn)詩(shī)歌下載服務(wù)器
初識(shí)Twisted

測(cè)試詩(shī)歌

簡(jiǎn)介

在我們探索Twisted的過(guò)程中寫了很多代碼, 但目前我們卻忽略了一些重要的東西 —— 測(cè)試. 你也許會(huì)疑問(wèn)怎樣用像 unittest 這樣Python自帶的同步框架測(cè)試異步代碼. 答案是你不能. 正如我們已經(jīng)發(fā)現(xiàn)的,同步代碼和異步代碼是不能混合的, 至少不容易.

幸運(yùn)地是, Twisted包含自己的測(cè)試框架, 叫 trial, 它支持測(cè)試異步代碼(當(dāng)然你也可以用它測(cè)試同步代碼).

我們假設(shè)你已經(jīng)熟悉了 unittest和相似的測(cè)試框架的原理, 它允許你通過(guò)定義類創(chuàng)建測(cè)試. 這個(gè)類通常是繼承一個(gè)一個(gè)特殊的父類(通常叫"TestCase"), 類中的方法以"test"開(kāi)頭并被視作一個(gè)測(cè)試. 框架負(fù)責(zé)發(fā)現(xiàn)所有的測(cè)試, 一個(gè)接一個(gè)地運(yùn)行它們, 并伴有可選項(xiàng) setUptearDown 步驟, 然后報(bào)告測(cè)試結(jié)果.

例子

你可以在 tests/test_poetry.py 中找到一些關(guān)于測(cè)試的例子.為了確保我們所有的例子是自包含的(以便你不用擔(dān)心PYTHONPAYH設(shè)置),我們將所有需要的代碼拷貝到測(cè)試模塊中.當(dāng)然正常情況,你只需導(dǎo)入需要測(cè)試的模塊.

通過(guò)使用客戶端從測(cè)試服務(wù)器抓取一首詩(shī), 這個(gè)例子既測(cè)試了詩(shī)歌客戶端又測(cè)試了服務(wù)器. 為了提供一個(gè)可供測(cè)試的詩(shī)歌服務(wù)器, 我們?cè)跍y(cè)試案例中實(shí)現(xiàn) setUp方法:

class PoetryTestCase(TestCase):

    def setUp(self):
        factory = PoetryServerFactory(TEST_POEM)
        from twisted.internet import reactor
        self.port = reactor.listenTCP(0, factory, interface="127.0.0.1")
        self.portnum = self.port.getHost().port

這個(gè) setUp 方法用一首測(cè)試詩(shī)建立詩(shī)歌服務(wù)器,然后監(jiān)聽(tīng)一個(gè)隨機(jī)開(kāi)放端口.我們保存了端口號(hào),以便實(shí)際測(cè)試需要時(shí)可以利用.當(dāng)然測(cè)試結(jié)束時(shí)我們會(huì)用 tearDown 清除測(cè)試服務(wù)器:

def tearDown(self):
    port, self.port = self.port, None
    return port.stopListening()

test_client把我們帶到了第一個(gè)測(cè)試, 用 get_poetry 從測(cè)試服務(wù)器獲取詩(shī)歌并且驗(yàn)證這就是我們所期望的詩(shī)歌:

def test_client(self):
    """The correct poem is returned by get_poetry."""
    d = get_poetry('127.0.0.1', self.portnum)
    def got_poem(poem):
        self.assertEquals(poem, TEST_POEM)
    d.addCallback(got_poem)
    return d

注意我們的測(cè)試函數(shù)返回一個(gè) deferred.在 trial 中,每個(gè)測(cè)試方法都以回調(diào)的方式運(yùn)行.這意味著 reactor 正在運(yùn)行并且我們可以以測(cè)試的一部分執(zhí)行異步操作.我們僅僅需要讓框架知道測(cè)試是異步的,這可以通過(guò)采用常規(guī)的Twisted方式 —— 返回 deferred 來(lái)實(shí)現(xiàn).

trial 框架在調(diào)用 tearDown 方法之前將等待直到 deferred 激發(fā),并且當(dāng) deferred 失敗時(shí)將使測(cè)試失敗(如,最后一個(gè)callback/errback對(duì)失敗).如果我們的 deferred 太長(zhǎng)時(shí)間才被激活調(diào)用(默認(rèn)2分鐘), 它同樣會(huì)使測(cè)試失敗.這意味著如果測(cè)試完成,我們知道 deferred 激發(fā)了, 那我們的回調(diào)就會(huì)激發(fā)并且運(yùn)行 assertEquals 測(cè)試方法.

我們的第二個(gè)測(cè)試, test_failure, 證實(shí) get_poetry 如果不能連接到服務(wù)器會(huì)以適當(dāng)?shù)姆绞绞?

def test_failure(self):
    """The correct failure is returned by get_poetry when
    connecting to a port with no server."""
    d = get_poetry('127.0.0.1', -1)
    return self.assertFailure(d, ConnectionRefusedError)

這里我們打算連接到一個(gè)無(wú)效端口,之后使用trial提供的 assertFailure 方法.這個(gè)方法類似于熟悉的 assertRaises 方法,但是assertFailure是針對(duì)異步代碼的.它返回一個(gè) deferred,如果這個(gè) deferred 失敗則返回成功,否則返回失敗.

你可以用trial腳本自己運(yùn)行這些測(cè)試,如下:

trial tests/test_poetry.py

你將看到每個(gè)測(cè)試案例的輸出, OK表示測(cè)試通過(guò)了.

討論

由于當(dāng)談到基本API時(shí),trial與unittest十分相似,所以開(kāi)始寫測(cè)試十分容易.如果你的測(cè)試使用異步代碼,僅僅返回 deferred 就可以了,trial將負(fù)責(zé)其余的事情.你也可以從 setUptearDown 方法返回一個(gè) deferred,如果它們也需要異步.

任何來(lái)自測(cè)試的日志消息將被收集到當(dāng)前文件夾下的一個(gè)文件中,即"_trial_temp", trial會(huì)自動(dòng)創(chuàng)建它. 除了打印到屏幕的錯(cuò)誤,日志是調(diào)試失敗測(cè)試的實(shí)用入口.

圖33顯示了一個(gè)正在進(jìn)行中的假想測(cè)試:

http://wiki.jikexueyuan.com/project/twisted-intro/images/p15_test-1.png" alt="" />

如果你之前使用過(guò)類似的框架,這是一個(gè)熟悉的模型,除了所有測(cè)試相關(guān)的方法可能返回 deferreds.

trial框架是一個(gè)關(guān)于如何"異步運(yùn)作"的很好例子,包括級(jí)聯(lián)在整個(gè)程序中的變化.為了使一個(gè)測(cè)試(或任何函數(shù),方法)是異步的,它必須:

  1. 非阻塞,并且通常
  2. 返回一個(gè) deferred.

但這意味著無(wú)論什么調(diào)用,那個(gè)函數(shù)必須愿意接收一個(gè) deferred,并且非阻塞(如此又好像返回了一個(gè) deferred).如此這般一層又一層.這樣就呼喚出現(xiàn)trial一樣的框架,可以處理返回 deferreds 的異步測(cè)試.

總結(jié)

這就是關(guān)于單元測(cè)試的內(nèi)容.如果你想了解更多關(guān)于如何為Twisted代碼寫單元測(cè)試的例子,你只需要看看Twisted代碼本身.Twisted框架自帶了一套非常龐大的單元測(cè)試,而且每個(gè)新的發(fā)布又會(huì)加入很多.由于這些測(cè)試在被接受入代碼庫(kù)之前,經(jīng)過(guò)嚴(yán)格的代碼評(píng)論以及Twisted專家們的仔細(xì)審查,故而它們是告訴你如何以正確方式測(cè)試Twisted代碼的極好例子.

在第十六節(jié)中,我們將使用Twisted工具將詩(shī)歌服務(wù)器轉(zhuǎn)化為一個(gè)真正的守護(hù)進(jìn)程.

參考練習(xí)

  1. 改變測(cè)試之一使其失敗,然后再次運(yùn)行 trial 看看輸出結(jié)果.
  2. 閱讀 trial 在線文檔
  3. 為我們這個(gè)系列中所創(chuàng)建的其他詩(shī)歌服務(wù)寫測(cè)試.
  4. 探索Twisted中的 一些測(cè)試

參考

本部分原作參見(jiàn): dave @ http://krondo.com/blog/?p=2273

本部分翻譯內(nèi)容參見(jiàn)luocheng @ https://github.com/luocheng/twisted-intro-cn/blob/master/p15.rst