Skip to content

Commit 777f676

Browse files
committed
Run tests in the same order as Django
This uses `pytest_collection_modifyitems` to order the tests. Fixes #214.
1 parent d4f42ea commit 777f676

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

pytest_django/plugin.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,35 @@ def pytest_runtest_setup(item):
319319
_disable_class_methods(cls)
320320

321321

322+
def pytest_collection_modifyitems(session, config, items):
323+
def get_marker_transaction(test):
324+
marker = test.get_marker("django_db")
325+
if marker:
326+
validate_django_db(marker)
327+
if marker:
328+
return marker.transaction
329+
return None
330+
331+
def has_fixture(test, fixture):
332+
funcargnames = getattr(test, 'funcargnames', None)
333+
return funcargnames and fixture in funcargnames
334+
335+
def get_order_number(test):
336+
if get_marker_transaction(test) is True:
337+
return 1
338+
if has_fixture(test, 'transactional_db'):
339+
return 1
340+
341+
if get_marker_transaction(test) is False:
342+
return 0
343+
if has_fixture(test, 'db'):
344+
return 0
345+
346+
return 2
347+
348+
items[:] = sorted(items, key=get_order_number)
349+
350+
322351
@pytest.fixture(autouse=True, scope='session')
323352
def django_test_environment(request):
324353
"""

tests/test_db_setup.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,38 @@ def test_db_can_be_accessed():
2525
])
2626

2727

28+
def test_db_order(testdir, django_testdir):
29+
"""Test order in which tests are being executed."""
30+
31+
testdir.create_test_module('''
32+
import pytest
33+
34+
from .app.models import Item
35+
36+
@pytest.mark.django_db(transaction=True)
37+
def test_run_second_decorator():
38+
pass
39+
40+
def test_run_second_fixture(transactional_db):
41+
pass
42+
43+
def test_run_first_fixture(db):
44+
pass
45+
46+
@pytest.mark.django_db
47+
def test_run_first_decorator():
48+
pass
49+
''')
50+
result = django_testdir.runpytest('-v', '-s')
51+
assert result.ret == 0
52+
result.stdout.fnmatch_lines([
53+
"*test_run_first_fixture*",
54+
"*test_run_first_decorator*",
55+
"*test_run_second_decorator*",
56+
"*test_run_second_fixture*",
57+
])
58+
59+
2860
def test_db_reuse(django_testdir):
2961
"""
3062
Test the re-use db functionality.

0 commit comments

Comments
 (0)