Search code examples
pythonpython-unittestpython-asyncioaiohttpsanic

python unitests for sanic app


I'm building CRUD REST APIs using peewee ORM and sanic(sanic-crud) as app server. Things are working fine. And I wrote couple of unittest cases for the same.

But, I'm facing problem running unittests. The problem is that unittests starts sanic app server and stalled there. Its not running unittest cases at all. But when I press Ctrl+C manually then the sanic server gets terminated and unittests execution starts. So, it means there should be a way to start sanic server and continue unittests run and terminate server at the end.

Can someone please me the correct way writting unittest cases for sanic app?

I followed official docs too but no luck. http://sanic.readthedocs.io/en/latest/sanic/testing.html

I tried following

from restapi import app # the execution stalled here i guess
import unittest
import asyncio
import aiohttp

class AutoRestTests(unittest.TestCase):
    ''' Unit testcases for REST APIs '''

    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

    def test_get_metrics_all(self):
        @asyncio.coroutine
        def get_all():
            res = app.test_client.get('/metrics')
            assert res.status == 201
        self.loop.run_until_complete(get_all())

from restapi.py

app = Sanic(__name__)
generate_crud(app, [Metrics, ...])
app.run(host='0.0.0.0', port=1337, workers=4, debug=True)

Solution

  • Finally managed to run unittests by moving app.run statement to main block

    # tiny app server starts here
    app = Sanic(__name__)
    generate_crud(app, [Metrics, ...])
    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=1337, debug=True)
            # workers=4, log_config=LOGGING)
    

    and

    from restapi import app
    import json
    import unittest
    
    class AutoRestTests(unittest.TestCase):
        ''' Unit testcases for REST APIs '''
    
        def test_get_metrics_all(self):
            request, response = app.test_client.get('/metrics')
            self.assertEqual(response.status, 200)
            data = json.loads(response.text)
            self.assertEqual(data['metric_name'], 'vCPU')
    
    if __name__ == '__main__':
        unittest.main()