Skip to content

Commit 303e6e6

Browse files
committed
Add performance test for the ordering overhead
1 parent fc26863 commit 303e6e6

12 files changed

+154
-39
lines changed

.github/workflows/performance.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: PerformanceTests
2+
3+
on:
4+
push
5+
6+
defaults:
7+
run:
8+
shell: bash
9+
10+
jobs:
11+
test:
12+
runs-on: ${{ matrix.os }}
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
os: [ubuntu-latest]
17+
python-version: [2.7, 3.6, 3.9]
18+
env:
19+
OS: ${{ matrix.os }}
20+
steps:
21+
- uses: actions/checkout@v2
22+
- name: Set up Python ${{ matrix.python-version }}
23+
uses: actions/setup-python@v2
24+
with:
25+
python-version: ${{ matrix.python-version }}
26+
- name: Get pip cache dir
27+
id: pip-cache
28+
run: |
29+
python -m pip install -U pip
30+
echo "::set-output name=dir::$(pip cache dir)"
31+
- name: pip cache
32+
uses: actions/cache@v2
33+
with:
34+
path: ${{ steps.pip-cache.outputs.dir }}
35+
key: py${{ matrix.python-version }}-${{ matrix.os }}-pip
36+
- name: Test environment setup
37+
run: |
38+
python -m pip install wheel
39+
python -m pip install pytest
40+
- name: Run tests
41+
run: |
42+
python -m pytest -s perf_tests

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
## Unreleased
44

5+
### Infrastructure
6+
- add performance tests to prevent performance degradation
7+
58
## [Version 0.9.5](https://pypi.org/project/pytest-order/0.9.5/) (2021-02-16)
69
Introduces hierarchical ordering option and fixes ordering of session-scoped
710
dependency markers.

perf_tests/test_order.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import os
2+
import shutil
3+
import time
4+
5+
import pytest
6+
7+
import pytest_order
8+
from tests.utils import write_test
9+
10+
11+
@pytest.fixture
12+
def fixture_path_baseline(tmpdir_factory):
13+
fixture_path = str(tmpdir_factory.mktemp("baseline"))
14+
for module_index in range(10):
15+
testname = os.path.join(
16+
fixture_path, "test_baseline{}.py".format(module_index))
17+
test_contents = """
18+
import pytest
19+
"""
20+
for i in range(100):
21+
test_contents += """
22+
def test_{}():
23+
assert True
24+
""".format(i)
25+
write_test(testname, test_contents)
26+
yield fixture_path
27+
shutil.rmtree(fixture_path, ignore_errors=True)
28+
29+
30+
@pytest.fixture
31+
def fixture_path_relative(tmpdir_factory):
32+
fixture_path = str(tmpdir_factory.mktemp("relative_perf"))
33+
for module_index in range(10):
34+
testname = os.path.join(
35+
fixture_path, "test_relative_perf{}.py".format(module_index))
36+
test_contents = """
37+
import pytest
38+
"""
39+
for i in range(100):
40+
test_contents += """
41+
@pytest.mark.order(after="test_{}")
42+
def test_{}():
43+
assert True
44+
""".format(i + 10 % 100, i)
45+
write_test(testname, test_contents)
46+
yield fixture_path
47+
shutil.rmtree(fixture_path, ignore_errors=True)
48+
49+
50+
@pytest.fixture
51+
def fixture_path_ordinal(tmpdir_factory):
52+
fixture_path = str(tmpdir_factory.mktemp("ordinal_perf"))
53+
for module_index in range(10):
54+
testname = os.path.join(
55+
fixture_path, "test_performance{}.py".format(module_index))
56+
test_contents = """
57+
import pytest
58+
"""
59+
for i in range(100):
60+
test_contents += """
61+
@pytest.mark.order({})
62+
def test_{}():
63+
assert True
64+
""".format(50 - i, i)
65+
write_test(testname, test_contents)
66+
yield fixture_path
67+
shutil.rmtree(fixture_path, ignore_errors=True)
68+
69+
70+
class TestPerformance:
71+
base_time = None
72+
73+
@pytest.mark.order(0)
74+
def test_baseline_times(self, fixture_path_baseline):
75+
start_time = time.time()
76+
args = [fixture_path_baseline]
77+
pytest.main(args, [pytest_order])
78+
self.__class__.base_time = time.time() - start_time
79+
80+
def test_performance_ordinal(self, fixture_path_ordinal):
81+
start_time = time.time()
82+
args = [fixture_path_ordinal]
83+
pytest.main(args, [pytest_order])
84+
overhead_time = time.time() - start_time - self.__class__.base_time
85+
print("Overhead per test: {:.3f} ms".format(overhead_time))
86+
assert overhead_time < 0.4
87+
88+
def test_performance_relative(self, fixture_path_relative):
89+
start_time = time.time()
90+
args = ["--quiet", fixture_path_relative]
91+
pytest.main(args, [pytest_order])
92+
overhead_time = time.time() - start_time - self.__class__.base_time
93+
print("Overhead per test: {:.3f} ms".format(overhead_time))
94+
assert overhead_time < 0.8

tests/__init__.py

Whitespace-only changes.

tests/conftest.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
import os
22
import shutil
33
import uuid
4+
from random import randint
45

56
import pytest
67

78
from pytest_order.sorter import SESSION
8-
9-
try:
10-
from tests.utils import write_test
11-
except ImportError:
12-
from utils import write_test
9+
from tests.utils import write_test
1310

1411
pytest_plugins = ["pytester"]
1512

@@ -73,3 +70,9 @@ def test_node(nodeid):
7370

7471
yield fixture_path
7572
shutil.rmtree(fixture_path, ignore_errors=True)
73+
74+
75+
def pytest_collection_modifyitems(config, items):
76+
for item in items:
77+
if item.name.startswith("test_performance"):
78+
item.add_marker(pytest.mark.order(randint(-100, 100)))

tests/test_dependency.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,7 @@
66
import pytest
77

88
import pytest_order
9-
10-
try:
11-
from tests.utils import write_test, assert_test_order
12-
except ImportError:
13-
from utils import write_test, assert_test_order
14-
9+
from tests.utils import write_test, assert_test_order
1510

1611
NODEID_ROOT = ""
1712

tests/test_order_group_scope.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,7 @@
55
import pytest
66

77
import pytest_order
8-
9-
try:
10-
from tests.utils import write_test, assert_test_order
11-
except ImportError:
12-
from utils import write_test, assert_test_order
8+
from tests.utils import write_test, assert_test_order
139

1410

1511
@pytest.fixture(scope="module")

tests/test_order_group_scope_dep.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,7 @@
66
import pytest
77

88
import pytest_order
9-
10-
try:
11-
from tests.utils import write_test, assert_test_order
12-
except ImportError:
13-
from utils import write_test, assert_test_order
14-
9+
from tests.utils import write_test, assert_test_order
1510

1611
NODEID_ROOT = ""
1712

tests/test_order_group_scope_named_dep.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@
66

77
import pytest_order
88

9-
try:
10-
from tests.utils import write_test, assert_test_order
11-
except ImportError:
12-
from utils import write_test, assert_test_order
9+
from tests.utils import write_test, assert_test_order
1310

1411

1512
@pytest.fixture(scope="module")

tests/test_order_group_scope_relative.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@
66

77
import pytest_order
88

9-
try:
10-
from tests.utils import write_test, assert_test_order
11-
except ImportError:
12-
from utils import write_test, assert_test_order
9+
from tests.utils import write_test, assert_test_order
1310

1411

1512
@pytest.fixture(scope="module")

0 commit comments

Comments
 (0)