Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use fixtures on Django TestCase #570

Closed
rlskoeser opened this issue Jan 4, 2018 · 7 comments
Closed

Use fixtures on Django TestCase #570

rlskoeser opened this issue Jan 4, 2018 · 7 comments

Comments

@rlskoeser
Copy link

I'm using the Django TestCase class for some of the conveniences - fixture loading, special assertions, etc - but I'd like to use some of the pytest fixtures if possible. I can use @pytest.mark.usefixtures but that doesn't to give me access to the objects returned by the fixtures, as far as I can tell. For example, if I use @pytest.mark.usefixtures("admin_client"), the admin client generated by the fixture isn't available anywhere that I can find.

Is there a way to do this that I'm missing? Or just something that's not supported?

I see in the pytest documentation that fixtures can be written to support working with unit test style TestCase classes - https://docs.pytest.org/en/latest/unittest.html#mixing-pytest-fixtures-into-unittest-testcase-subclasses-using-marks ; would that be an option for pytest-django fixtures?

@gsong
Copy link

gsong commented Jan 19, 2018

@rlskoeser Yup, using the same strategy for Python unittest.TestCase as you would for django.test.TestCase works. You can either inject the pytest fixture(s) into the test class or instance, depending on what you need.

@rlskoeser
Copy link
Author

@gsong sorry, are you saying this works currently? Could you provide example code showing how I would access e.g. admin_client within a class?

@aalvrz
Copy link

aalvrz commented Jan 25, 2018

@rlskoeser Have you tried something like:

import pytest


class TestOrders:
    def test_create_order(self, admin_client):
        response = admin_client.get('/myurl')
        assert response.status_code == 200

Not sure if this is what you are looking for.

@gsong
Copy link

gsong commented Jan 26, 2018

@rlskoeser Something like this:

from django.test import TestCase

import pytest

from ..client import MagicClient


@pytest.mark.usefixtures("inject_attrs")
class TestGetSubjectId(TestCase):
    def test_something(self):
        result = self.admin_client.do_something()
        assert result is True


@pytest.fixture(scope="class")
def inject_attrs(request, admin_client):
    request.cls.admin_client = admin_client


@pytest.fixture
def admin_client():
    return MagicClient()

You can inject as many pytest fixtures as you want in the inject_attrs fixture. If you would rather attach the fixture to the TestCase instance, just use request.instance instead of request.cls.

Let me know if this isn't clear.

@scythargon
Copy link

scythargon commented Jun 18, 2018

@gsong Thank you for your snippet! Unfortunately it looks like DB records of the objects created in the fixtures are not getting wiped out between calls, right? I mean if I have few test_... methods in my class, wrapped with @pytest.mark.usefixtures then the fixture get called for the each test method, but the DB is not getting cleaned.

UPD: That's because fixtures used in a class-decoration should be defined via @pytest.fixture(scope="class"), then everything is fine.

@westurner
Copy link

see also: #13 "Easy fixture loading"

@bluetech
Copy link
Member

Closing as answered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants