How to test Python 3.4 asyncio code?

前端 未结 10 1232
遇见更好的自我
遇见更好的自我 2020-12-02 05:38

What\'s the best way to write unit tests for code using the Python 3.4 asyncio library? Assume I want to test a TCP client (SocketConnection):

相关标签:
10条回答
  • 2020-12-02 06:22

    pytest-asyncio looks promising:

    @pytest.mark.asyncio
    async def test_some_asyncio_code():
        res = await library.do_something()
        assert b'expected result' == res
    
    0 讨论(0)
  • 2020-12-02 06:26

    You can also use aiounittest that takes similar approach as @Andrew Svetlov, @Marvin Killing answers and wrap it in easy to use AsyncTestCase class:

    import asyncio
    import aiounittest
    
    
    async def add(x, y):
        await asyncio.sleep(0.1)
        return x + y
    
    class MyTest(aiounittest.AsyncTestCase):
    
        async def test_async_add(self):
            ret = await add(5, 6)
            self.assertEqual(ret, 11)
    
        # or 3.4 way
        @asyncio.coroutine
        def test_sleep(self):
            ret = yield from add(5, 6)
            self.assertEqual(ret, 11)
    
        # some regular test code
        def test_something(self):
            self.assertTrue(true)
    

    As you can see the async case is handled by AsyncTestCase. It supports also synchronous test. There is a possibility to provide custom event loop, just override AsyncTestCase.get_event_loop.

    If you prefer (for some reason) the other TestCase class (eg unittest.TestCase), you might use async_test decorator:

    import asyncio
    import unittest
    from aiounittest import async_test
    
    
    async def add(x, y):
        await asyncio.sleep(0.1)
        return x + y
    
    class MyTest(unittest.TestCase):
    
        @async_test
        async def test_async_add(self):
            ret = await add(5, 6)
            self.assertEqual(ret, 11)
    
    0 讨论(0)
  • 2020-12-02 06:28

    Since Python 3.8 unittest comes with the IsolatedAsyncioTestCase function, designed for this purpose.

    from unittest import IsolatedAsyncioTestCase
    
    class Test(IsolatedAsyncioTestCase):
    
        async def test_functionality(self):
            result = await functionality()
            self.assertEqual(expected, result)
    
    0 讨论(0)
  • 2020-12-02 06:29

    I usually define my async tests as coroutines and use a decorator for "syncing" them:

    import asyncio
    import unittest
    
    def sync(coro):
        def wrapper(*args, **kwargs):
            loop = asyncio.get_event_loop()
            loop.run_until_complete(coro(*args, **kwargs))
        return wrapper
    
    class TestSocketConnection(unittest.TestCase):
        def setUp(self):
            self.mock_server = MockServer("localhost", 1337)
            self.socket_connection = SocketConnection("localhost", 1337)
    
        @sync
        async def test_sends_handshake_after_connect(self):
            await self.socket_connection.connect()
            self.assertTrue(self.mock_server.received_handshake())
    
    0 讨论(0)
提交回复
热议问题