404pio
404pio

Reputation: 1030

Pytest fixture for pytest-httpserver with unittest TestCase

I have written api client in Python - I should write tests for it. I dediced to use pytest and unittest as core tools. To simulate http server, I choose pytest-httpserver. My tests are organized into classes and methods - not simple functions.

This is my simple testcase:

from pytest_httpserver import HTTPServer
import requests
import unittest
import pytest
from urllib.parse import urlencode

FAKE_SERVER = "localhost"
FAKE_PORT = 8888

@pytest.fixture(scope="class")
def httpserver_listen_address(request):
    request.cls.httpserver = HTTPServer(FAKE_SERVER, FAKE_PORT)


@pytest.mark.usefixtures("httpserver_listen_address")
class LoginTestCase(unittest.TestCase):

    def test_check_auth_url(self):
        auth_url = f'http://{FAKE_SERVER}:{FAKE_PORT}/auth-token/'

        self.httpserver\
            .expect_request("/auth-token/", method="POST", data=urlencode({}))\
            .respond_with_json({"test": "test"})

        requests.post(self.httpserver.url_for("/auth-token/"), {})

And I'm getting stacktrace:

E           requests.exceptions.ConnectionError: HTTPConnectionPool(
host='localhost', port=8888): 
Max retries exceeded with url: /auth-token/ (
Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f055c2c1480>: 
Failed to establish a new connection: [Errno 111] Connection refused'))

How should I configure fixtures for httpserver to play with TestCases?

Upvotes: 1

Views: 1238

Answers (1)

404pio
404pio

Reputation: 1030

Ok, I'm pretty sure it can be realized in many ways. But I have found only one:

from pytest_httpserver import HTTPServer
import requests
import unittest
import pytest
from urllib.parse import urlencode

FAKE_SERVER = "localhost"
FAKE_PORT = 8888


@pytest.fixture
def my_httpserver(request, httpserver):
    request.cls.httpserver = httpserver


@pytest.mark.usefixtures("my_httpserver")
class Login2TestCase(unittest.TestCase):

    def test_check_auth_url(self):
        auth_url = f'http://{FAKE_SERVER}:{FAKE_PORT}/auth-token/'

        self.httpserver\
            .expect_request("/auth-token/", method="POST", data=urlencode({}))\
            .respond_with_json({"test": "test"})

        requests.post(self.httpserver.url_for("/auth-token/"), {})

What is going on?

  1. I'm creating my fixture, my_httpserver - it uses 2 built-in fixtures: request and httpserver. Request is fixture of core pytest - it is some kind of relection mechanism - I'm using it to bind httpserver to my TestCase. Httpserver is pytest-httpserver fixtures for managing httpserver.
  2. I'm telling that my class will be using this fixture @pytest.mark.usefixtures.
  3. httpserver is visible in self.httpserver field.

Upvotes: 1

Related Questions