簡體   English   中英

如何使用Twisted Trial對Autobahn應用程序進行單元測試?

[英]How to do unit test on Autobahn applications using Twisted Trial?

假設您只使用Autobahn連接(不是原始WebSocket)。

我們如何在沒有網絡,RPC方法和事件的情況下進行測試?
由於它是Twisted,我認為最合適的工具是Twisted Trial。

但我無法弄清楚如何編寫這些測試,而不需要編寫大量的樣板代碼並重新使用Autobahn的內部實現(甚至我不確定我是否能夠這樣做)。

你會怎么做?

這是試圖回答我自己的問題。

問題

然后,為了對RPC方法和事件進行單元測試,我們需要假設Autobahn經過了充分測試,我們不必測試它,解決方案變得簡單:

解決方案

嘲笑所有。

上下文

在我的應用程序中,我有兩種類型的組件(讀取ApplicationSession):StandardComponent和DatabaseComponent(繼承自StandardComponent)。

單元測試中最大的問題是我們有很多依賴項,比如數據庫連接,Redis連接等等......

例子

我在測試中做的是通過unittest.TestCase來修補所有這些對象:

class APITestCase(unittest.TestCase):

    def _patchObject(self, module_name, **kwargs):
        patcher = patch(module_name, **kwargs)
        mock = patcher.start()

        self.patches.append(patcher)
        return mock

    def setUp(self):
        logging.disable(logging.CRITICAL)
        self.patches = []
        self.session = self._patchObject('components.ApplicationAPI')
        self.database = self._patchObject('txpostgres.txpostgres.Connection')

    def tearDown(self):
        for patcher in self.patches:
            patcher.stop()

我在我的測試用例中注入了一個模擬會話和一個模擬數據庫。

然后,測試變得非常簡單。

每當我調用一個需要調用數據庫或從數據庫中獲取結果的RPC方法時,我都會修補它: self.mocked_auth_user.return_value = (1, "abc", "something", "admin")

在我的測試方法中:

def test_authenticate_success(self):
    self.mocked_auth_user.return_value = (1, "abc", "paris", "admin")

    def _doTest(auth_result):
        attempted_auth_result = {
            "secret": "abc",
            "role": "admin",
            "authid": "1",
            "salt": "paris",
            "iterations": 1000,
            "keylen": 32
        }

        self.assertEqual(auth_result, attempted_auth_result)
        self.mocked_auth_user.assert_called_with(self.api.database, "raito")

    return self.api.authenticate("test", "raito", {}).addCallback(_doTest)

您可以執行一些更高級和有趣的測試,以查看您的方法是否是防錯的:

def test_authenticate_authid_not_found(self):
    def _raiseException(db, user):
        return defer.fail(Exception("User {} not found!".format(user)))

    self.mocked_auth_user.side_effect = _raiseException
    return self.failUnlessFailure(self.api.authenticate("test", "raito", {}), AuthenticationError)

對於事件也是如此,你只需要調用它們並測試它們是否發布了一個事件( self.session.publish.assert_called_with(...)

它變得神奇!

無論如何,它解決了單元測試問題,但整合還沒有。 我正在努力,但問題可能會使用一些虛擬化技術(Docker)或類似的東西來解決。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM