Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -108,17 +108,27 @@ Advanced Options
Disable Shuffling In a Module
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

You can disable shuffling of tests within a single module by placing a pytest marker in the module:
You can disable shuffling of tests within a single module or class by marking the module or class
with ``random_order`` marker and passing ``disabled=True`` to it:

::

pytest.mark.random_order_disabled = True
pytestmark = pytest.mark.random_order(disabled=True)

def test_number_one():
pass
assert True

def test_number_two():
pass
assert True

::

class MyTest(TestCase):
pytestmark = pytest.mark.random_order(disabled=True)

def test_number_one(self):
self.assertTrue(True)


No matter what will be the bucket type for the test run, ``test_number_one`` will always run
before ``test_number_two``.
Expand Down
22 changes: 7 additions & 15 deletions pytest_random_order/shuffler.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-

import collections
import operator
import random


Expand Down Expand Up @@ -97,19 +96,12 @@ def _get_set_of_item_ids(items):
return s


_is_random_order_disabled = operator.attrgetter('pytest.mark.random_order_disabled')


def _disable(item):
try:
# In actual test runs, this is returned as a truthy instance of MarkDecorator even when you don't have
# set the marker. This is a hack.
is_disabled = _is_random_order_disabled(item.module)
if is_disabled and is_disabled is True:
# It is not enough to return just True because in case the shuffling
# is disabled on module, we must preserve the module unchanged
# even when the bucket type for this test run is say package or global.
return item.module.__name__
except AttributeError:
pass
marker = item.get_marker('random_order')
if marker:
is_disabled = marker.kwargs.get('disabled', False)
if is_disabled:
# A test item can only be disabled in its parent context -- where it is part of some order.
# We use parent name as the key so that all children of the same parent get the same disabled key.
return item.parent.name
return False
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def read(fname):

setup(
name='pytest-random-order',
version='0.4.3',
version='0.5.0',
author='Jazeps Basko',
author_email='jazeps.basko@gmail.com',
maintainer='Jazeps Basko',
Expand Down
35 changes: 32 additions & 3 deletions tests/test_markers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,19 @@ def twenty_tests():
return ''.join(code)


@pytest.mark.parametrize('disabled', [True])
def test_pytest_mark_random_order_disabled(testdir, twenty_tests, get_test_calls, disabled):
@pytest.fixture
def twenty_cls_tests():
code = []
for i in range(20):
code.append('\tdef test_b{}(self): self.assertTrue\n'.format(str(i).zfill(2)))
return ''.join(code)


@pytest.mark.parametrize('disabled', [True, False])
def test_marker_disables_random_order_in_module(testdir, twenty_tests, get_test_calls, disabled):
testdir.makepyfile(
'import pytest\n' +
'pytest.mark.random_order_disabled = {}\n'.format(disabled) +
('pytestmark = pytest.mark.random_order(disabled={})\n'.format(disabled)) +
twenty_tests
)

Expand All @@ -26,3 +34,24 @@ def test_pytest_mark_random_order_disabled(testdir, twenty_tests, get_test_calls
assert names == sorted_names
else:
assert names != sorted_names


@pytest.mark.parametrize('disabled', [True, False])
def test_marker_disables_random_order_in_class(testdir, twenty_cls_tests, get_test_calls, disabled):
testdir.makepyfile(
'import pytest\n\n' +
'from unittest import TestCase\n\n' +
'class MyTest(TestCase):\n' +
'\tpytestmark = pytest.mark.random_order(disabled={})\n'.format(disabled) +
twenty_cls_tests + '\n'
)

result = testdir.runpytest('--random-order-bucket=module', '-v')
result.assert_outcomes(passed=20)
names = [c.name for c in get_test_calls(testdir.runpytest())]
sorted_names = sorted(list(names))

if disabled:
assert names == sorted_names
else:
assert names != sorted_names