Skip to content

Making tests with AioHTTPTestCase #2032

Closed
@cecton

Description

Long story short

I'm trying to make my test to run on the same port instead of a random port. The reason is that I'm making integration tests and I need it to receive calls from another service that I can't really configure the port easily.

My idea is that I need to make a class FixedPortTestServer that will inherit from TestServer and override the start_server method to force a specific port.

Then I need to pass this instance to the TestClient initialization. The AioHTTPTestCase use the result of get_application and give it to TestClient init parameters. This makes me think that I can make get_application return the FixedPortTestServer instance instead of the application instance:

    async def get_application(self):
        return FixedPortTestServer(my_app)

Which is wrong... Now I have a properly initialized TestClient using my TestServer but self.app in the AioHTTPTestCase give me the TestServer instead of my application which doesn't make any sense.

Expected behaviour

I expect to get the application from self.app within a test method of AioHTTPTestCase and I want to be able to override the TestServer instance with whatever BaseTestServer instance I want without needing to override a private method.

Actual behaviour

Currently, my only way to override the TestServer instance in the initialization of the TestClient is to override the private method _get_client in the AioHTTPTestCase.

Steps to reproduce

import asyncio
import socket
from aiohttp.helpers import sentinel
from aiohttp.test_utils import AioHTTPTestCase, TestServer, unittest_run_loop
from yarl import URL

from mymodule import myapp


class FixedPortTestServer(TestServer):
    @asyncio.coroutine
    def start_server(self, loop=None, **kwargs):
        if self.server:
            return
        self._loop = loop
        self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._socket.bind((self.host, 8080)) # force port
        self.port = self._socket.getsockname()[1]
        self._ssl = kwargs.pop('ssl', None)
        if self.scheme is sentinel:
            if self._ssl:
                scheme = 'https'
            else:
                scheme = 'http'
            self.scheme = 'http'
        self._root = URL('{}://{}:{}'.format(self.scheme,
                                             self.host,
                                             self.port))

        handler = yield from self._make_factory(**kwargs)
        self.server = yield from self._loop.create_server(
            handler, ssl=self._ssl, sock=self._socket)


class MyTestCase(AioHTTPTestCase):
    async def get_application(self):
        return FixedPortTestServer(myapp)

    @unittest_run_loop
    async def test_initialization(self):
        self.assertIs(self.app, myapp)

Your environment

Python 3.6

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions