Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using pytest parametrize with DRF test

Now I have code like this:

from rest_framework.test import APITestCase

class MyTestClass(ApiTestCase):
    fixtures = ['some_fixtures.json', ]

    @pytest.mark.parametrize('field, reverse_ordering', [
        ('id', False),
        ('id', True)])
    def test_ordering(self, field, reverse_ordering):
        # some test function

Every time it is failed with that error:

======================================================================
ERROR: test_ordering (my_module.tests.MyTestClass)
----------------------------------------------------------------------
TypeError: test_ordering() missing 2 required positional arguments: 'field' and 'reverse_ordering'

How it is possible to use @pytest.mark.parametrize decorator with tests inside of APITestCase from DRF tests class?
Maybe there is some another way to parametrize tests (but not loops)?

like image 575
ncopiy Avatar asked Dec 11 '22 05:12

ncopiy


1 Answers

Maybe there is some another way to parametrize tests (but not loops)?

Since Python 3.4, parametrizing is available in the standard library using subTest:

class MyTest(APITestCase):

    test_ordering_params = [('id', False), ('id', True)]

    def test_ordering(self):
        for field, reverse_ordering in self.test_ordering_params:
            with self.subTest(field=field, reverse=reverse_ordering):
                query = ('-' if reverse_ordering else '') + field
                resp = self.client.get(reverse('url-name'), {'ordering': query}, format='json')
                assert resp.data

However, if you want to gain real benefits from using pytest, consider moving away from unittest-style class tests to test functions. The same test using pytest combined with pytest-django plugin:

import pytest
from rest_framework.test import APIClient

@pytest.fixture
def apiclient():
    return APIClient()

@pytest.mark.parametrize('field, reverse_ordering', [('id', False), ('id', True)])
def test_ordering(apiclient, db, field, reverse_ordering):
    query = ('-' if reverse_ordering else '') + field
    resp = apiclient.get(reverse('url-name'), {'ordering': query}, format='json')
    assert resp.data

Edit

You may also take a look at the parameterized library, which offers pytest-like parametrization for test class methods. Example:

from parameterized import parameterized


class MyTest(APITestCase):

    @parameterized.expand([('id', False), ('id', True)])
    def test_ordering(self, field, reverse_ordering):
        query = ('-' if reverse_ordering else '') + field
        resp = self.client.get(reverse('url-name'), {'ordering': query}, format='json')
        assert resp.data
like image 140
hoefling Avatar answered Dec 12 '22 18:12

hoefling