twisted系列教程十五–测试twisted代码
Introduction
在這個系列中我們也已經寫了很多twisted 代碼了,但目前為止我們忽略了一個很重要的事情—測試.你可能也一直在想我們怎樣用一個同步的測試框架unitest來測試我們的異步的程序.簡短的回答是不能,我們已經發現,同步的程序和異步的程序不能混合在一起.最起碼不會很好的結合在一起.
幸運的是,twisted 已經包含了他自己的異步測試測試框架–trial.我們也可以用它來測試同步的框架.
我們假設你已經對unittest 的測試原理和測試框架比較熟悉了,在unittest 中,我們通過定義一個繼承TestCase的類創建測試,并且每個測試方法前面以test為前綴.框架會幫你發現測試,運行測試,然后報告出測試結果.
The Example
你會在tests/test_poetry.py發現一些例子代碼.為了保證我們的例子可以自包含,我們已經把全部的有必要的代碼拷進test 模塊.正常的來說,你只需要導入你想測試的模塊就可以了.
這個例子測試了client 和server,通過使用這個client 去從test server 上獲取到每一首詩.為了提供一個可供測試的server,我們在我們的測試用例中實現了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
這個setUp 方法創建了一個poetry server,并隨機監聽一個端口.我們保存了這個端口號,讓我們的測試用例使用.當我們的測試用例運行完的時候我們用tearDown清理我們的test server:
def tearDown(self):
????port, self.port = self.port, None
????return port.stopListening()
下面我們看一下我們真實的測試代碼,test_client,我們使用get_poetry 從test server 上獲取詩的內容并驗證是不是我們想要的詩:
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
注意一下我們的測試函數返回了一個deferred.在trial中,每一個測試方法被當作一個callback.它意味著reactor 在運行著我們可以執行異步的操作.我們需要讓這個測試框架知道我們的測試是異步的,我們通過返回一個deferred來告訴測試框架我們的函數是異步的.
trial 框架會等待所有的deferred 被觸發之后才會調用tearDown 方法,如果deferred 失敗了測試也會失敗.假如我們的deferred 花了太多的時間去觸發,我們的測試也會失敗,默認的是兩分鐘.如果我們的測試運行結束了,我們知道我們的deferred 也觸發了,我們的callback 也觸發了,我們就可以運行assertEquals 了.
我們的第二個測試是,test_failure,可以驗證get_poetry 失敗的方式,假如我們不能連接上server 的話:
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)
在這里我們試圖去連接一個不正確的端口,并用trial 提供的assertFailure方法.這個方法有點像assertRaises ,但是是用來測試異步的代碼的.它會返回一個成功的deferred 假如測試用的deferred 出現我們要的錯誤.
你可以運行這個測試腳本:
trial tests/test_poetry.py
你會看到每個測試用例的輸出,如果測試通過的話會輸出OK.
Discussion
因為trial 和unittest 提供的一些api非常相像.用它寫單元測試是很簡單的.如果你想測試異步的代碼你只需要返回一個deferred,trial 會負責其他的事情.你也可以從setUp 和 tearDonw 中返回一個deferred,如果他們也需要異步的話.
任何的日志信息都會被保存到一個叫做_trial_temp的目錄下,如果沒有的話 trial 會自動幫我們建立.除了被打印到屏幕上的一些錯誤信息除外,這些日志信息對我們分析出錯的原因非常重要.
圖片三十三展示了一個假想的測試過程:
圖片三十三
如果你曾經用過類似的測試框架,這個會是一個非常熟悉的模型,除了這個測試相關的方法都返回deferred.
trial 框架也是一個怎樣在一個程序中用交錯任務讓這個程序變成異步的程序的很好的說明,為了讓一個測試變成異步的,你需要:
????不能是阻塞的
????返回一個deferred
Summary
這個就是我們要講 單元測試.如果你想要看更多的怎樣測試twisted 代碼的例子,你可以看一下twisted 的源代碼.twisted 代碼中包含了大量的單元測試.因為這些測試都是twisted 的專家經過仔細地檢查之后才被加入代碼庫的,他們的代碼就是一個非常好的單元測試的例子.
在第十六部分我們會使用twisted 的一個實用的功能讓我們的poetry server 變成一個守護進程.
總結
以上是生活随笔為你收集整理的twisted系列教程十五–测试twisted代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows获取本机主机IP信息
- 下一篇: Python字符串之'\x00'与空串'