Skip to content

Commit c0986b3

Browse files
committed
Run tests in the same order as Django
This uses `pytest_collection_modifyitems` to order the tests. Fixes #214.
1 parent 0ec741b commit c0986b3

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

pytest_django/plugin.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,35 @@ def pytest_runtest_setup(item):
221221
cls.tearDownClass = types.MethodType(lambda cls: None, cls)
222222

223223

224+
def pytest_collection_modifyitems(session, config, items):
225+
def get_marker_transaction(test):
226+
marker = test.get_marker("django_db")
227+
if marker:
228+
validate_django_db(marker)
229+
if marker:
230+
return marker.transaction
231+
return None
232+
233+
def has_fixture(test, fixture):
234+
funcargnames = getattr(test, 'funcargnames', None)
235+
return funcargnames and fixture in funcargnames
236+
237+
def get_order_number(test):
238+
if get_marker_transaction(test) is True:
239+
return 1
240+
if has_fixture(test, 'transactional_db'):
241+
return 1
242+
243+
if get_marker_transaction(test) is False:
244+
return 0
245+
if has_fixture(test, 'db'):
246+
return 0
247+
248+
return 2
249+
250+
items[:] = sorted(items, key=get_order_number)
251+
252+
224253
@pytest.fixture(autouse=True, scope='session')
225254
def _django_test_environment(request):
226255
"""

tests/test_db_setup.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,37 @@ def test_db_can_be_accessed():
3030
])
3131

3232

33+
def test_db_order(testdir, django_testdir):
34+
"""Test order in which tests are being executed."""
35+
36+
testdir.create_test_module('''
37+
import pytest
38+
39+
from .app.models import Item
40+
41+
@pytest.mark.django_db(transaction=True)
42+
def test_run_second_decorator():
43+
pass
44+
45+
def test_run_second_fixture(transactional_db):
46+
pass
47+
48+
def test_run_first_fixture(db):
49+
pass
50+
51+
@pytest.mark.django_db
52+
def test_run_first_decorator():
53+
pass
54+
''')
55+
result = django_testdir.runpytest('-vv', '-s')
56+
result.stdout.fnmatch_lines([
57+
"*test_run_first_fixture PASSED*",
58+
"*test_run_first_decorator PASSED*",
59+
"*test_run_second_decorator PASSED*",
60+
"*test_run_second_fixture PASSED*",
61+
])
62+
63+
3364
def test_db_reuse(django_testdir):
3465
"""
3566
Test the re-use db functionality. This test requires a PostgreSQL server

0 commit comments

Comments
 (0)