Skip to content

Commit bebe815

Browse files
henryiiilayday
authored andcommitted
tests: faster testing with less duplication
Signed-off-by: Henry Schreiner <[email protected]>
1 parent cb394c6 commit bebe815

File tree

5 files changed

+128
-69
lines changed

5 files changed

+128
-69
lines changed

.github/workflows/test.yml

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ on:
1414
- '*.md'
1515
schedule:
1616
- cron: "0 8 * * *"
17+
workflow_dispatch:
1718

1819
concurrency:
1920
group: test-${{ github.ref }}
@@ -33,6 +34,8 @@ jobs:
3334
- windows
3435
py:
3536
- 'pypy-3.7'
37+
- 'pypy-3.8'
38+
- 'pypy-3.9'
3639
- '3.11-dev'
3740
- '3.10'
3841
- '3.9'
@@ -41,9 +44,6 @@ jobs:
4144
- '3.6'
4245
tox-target:
4346
- 'tox'
44-
- 'path'
45-
- 'sdist'
46-
- 'wheel'
4747
- 'min'
4848
exclude:
4949
- { py: '3.11-dev', os: macos }
@@ -64,7 +64,7 @@ jobs:
6464
import sys
6565
6666
if platform.python_implementation() == "PyPy":
67-
base = f"pypy{sys.version_info.major}"
67+
base = f"pypy{sys.version_info.major}{sys.version_info.minor}"
6868
else:
6969
base = f"py{sys.version_info.major}{sys.version_info.minor}"
7070
env = f"BASE={base}\n"
@@ -87,12 +87,6 @@ jobs:
8787
tox -vv --notest -e ${{env.BASE}}
8888
tox -e ${{env.BASE}} --skip-pkg-install
8989
90-
- name: Run test suite via ${{ matrix.tox-target }}
91-
if: matrix.tox-target != 'tox' && matrix.tox-target != 'min'
92-
run: |
93-
tox -vv --notest -e ${{env.BASE}}-${{ matrix.tox-target }}
94-
tox -e ${{env.BASE}}-${{ matrix.tox-target }} --skip-pkg-install
95-
9690
- name: Run minimum version test
9791
if: matrix.tox-target == 'min'
9892
run: tox -e ${{env.BASE}}-${{ matrix.tox-target }}
@@ -103,7 +97,7 @@ jobs:
10397
shell: bash
10498

10599
- uses: codecov/codecov-action@v1
106-
if: ${{ always() }}
100+
if: always()
107101
env:
108102
PYTHON: ${{ matrix.python }}
109103
with:
@@ -112,6 +106,10 @@ jobs:
112106
env_vars: PYTHON
113107
name: ${{ matrix.py }} - ${{ matrix.os }}
114108

109+
- name: Run path test
110+
if: matrix.tox-target == 'tox' && matrix.py == '3.10'
111+
run: tox -e path
112+
115113
type:
116114
runs-on: ubuntu-latest
117115
env:

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ build = [
2525
show_contexts = true
2626

2727
[tool.pytest.ini_options]
28+
minversion = "6.0"
2829
addopts = ["--strict-config", "--strict-markers"]
30+
testpaths = ["tests"]
2931
xfail_strict = true
3032
junit_family = "xunit2"
3133
norecursedirs = "tests/integration/*"

tests/conftest.py

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,60 +4,15 @@
44
import os.path
55
import shutil
66
import stat
7-
import subprocess
87
import sys
98
import sysconfig
109
import tempfile
1110

1211
import pytest
1312

14-
from filelock import FileLock
15-
1613
import build.env
1714

1815

19-
def _build_and_reinstall_build(test_mode):
20-
temp = tempfile.mkdtemp()
21-
try:
22-
subprocess.check_output(
23-
[sys.executable, '-m', 'build', f'--{test_mode}', '--no-isolation', '--outdir', temp],
24-
)
25-
dist_file = next(d for d in os.listdir(temp) if d.endswith('.whl' if test_mode == 'wheel' else '.tar.gz'))
26-
subprocess.check_call(
27-
[
28-
sys.executable,
29-
'-m',
30-
'pip',
31-
'install',
32-
'--upgrade', # ``--upgrade`` will uninstall build prior to installing the ``dist_file``
33-
os.path.join(temp, dist_file),
34-
],
35-
)
36-
finally:
37-
shutil.rmtree(temp)
38-
39-
40-
def _one_time_setup():
41-
test_mode = os.environ.get('TEST_MODE')
42-
if not test_mode:
43-
return
44-
45-
if test_mode == 'path':
46-
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
47-
sys.path.insert(0, os.path.join(project_root, 'src'))
48-
elif test_mode in {'sdist', 'wheel'}:
49-
status_marker_file = os.path.join(os.environ['TEST_STATUS_DIR'], 'status-marker')
50-
with FileLock(status_marker_file + '.lock'):
51-
if not os.path.exists(status_marker_file):
52-
_build_and_reinstall_build(test_mode)
53-
54-
with open(status_marker_file, 'wb'):
55-
pass
56-
57-
58-
_one_time_setup()
59-
60-
6116
def pytest_addoption(parser):
6217
os.environ['PYTHONWARNINGS'] = 'ignore:DEPRECATION::pip._internal.cli.base_command' # for when not run within tox
6318
os.environ['PIP_DISABLE_PIP_VERSION_CHECK'] = '1' # do not pollute stderr with upgrade advisory

tests/test_self_packaging.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# These tests check the sdist, path, and wheel of build to ensure that all are valid.
2+
3+
import subprocess
4+
import sys
5+
import tarfile
6+
import zipfile
7+
8+
from pathlib import Path
9+
10+
import pytest
11+
12+
13+
DIR = Path(__file__).parent.resolve()
14+
MAIN_DIR = DIR.parent
15+
16+
sdist_files = {
17+
'LICENSE',
18+
'PKG-INFO',
19+
'README.md',
20+
'pyproject.toml',
21+
'setup.cfg',
22+
'setup.py',
23+
'src',
24+
'src/build',
25+
'src/build.egg-info',
26+
'src/build.egg-info/PKG-INFO',
27+
'src/build.egg-info/SOURCES.txt',
28+
'src/build.egg-info/dependency_links.txt',
29+
'src/build.egg-info/entry_points.txt',
30+
'src/build.egg-info/requires.txt',
31+
'src/build.egg-info/top_level.txt',
32+
'src/build/__init__.py',
33+
'src/build/__main__.py',
34+
'src/build/env.py',
35+
'src/build/py.typed',
36+
'src/build/util.py',
37+
}
38+
39+
wheel_files = {
40+
'build/__init__.py',
41+
'build/__main__.py',
42+
'build/env.py',
43+
'build/py.typed',
44+
'build/util.py',
45+
'dist-info/LICENSE',
46+
'dist-info/METADATA',
47+
'dist-info/RECORD',
48+
'dist-info/WHEEL',
49+
'dist-info/entry_points.txt',
50+
'dist-info/top_level.txt',
51+
}
52+
53+
54+
def test_build_sdist(monkeypatch, tmpdir):
55+
56+
monkeypatch.chdir(MAIN_DIR)
57+
58+
subprocess.run(
59+
[
60+
sys.executable,
61+
'-m',
62+
'build',
63+
'--sdist',
64+
'--outdir',
65+
str(tmpdir),
66+
],
67+
check=True,
68+
).stdout
69+
70+
(sdist,) = tmpdir.visit('*.tar.gz')
71+
72+
with tarfile.open(str(sdist), 'r:gz') as tar:
73+
simpler = {n.split('/', 1)[-1] for n in tar.getnames()[1:]}
74+
75+
assert simpler == sdist_files
76+
77+
78+
@pytest.mark.parametrize('args', ((), ('--wheel',)), ids=('from_sdist', 'direct'))
79+
def test_build_wheel(monkeypatch, tmpdir, args):
80+
81+
monkeypatch.chdir(MAIN_DIR)
82+
83+
subprocess.run(
84+
[
85+
sys.executable,
86+
'-m',
87+
'build',
88+
*args,
89+
'--outdir',
90+
str(tmpdir),
91+
],
92+
check=True,
93+
)
94+
95+
(wheel,) = tmpdir.visit('*.whl')
96+
97+
with zipfile.ZipFile(str(wheel)) as z:
98+
names = z.namelist()
99+
100+
trimmed = {n for n in names if 'dist-info' not in n}
101+
trimmed |= {f"dist-info/{n.split('/', 1)[-1]}" for n in names if 'dist-info' in n}
102+
103+
assert trimmed == wheel_files

tox.ini

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ envlist =
33
fix
44
type
55
docs
6-
{py311, py310, py39, py38, py37, py36, pypy3}{, -path, -sdist, -wheel, -min}
6+
path
7+
{py311, py310, py39, py38, py37, py36, pypy37, pypy38, pypy39}{, -min}
78
isolated_build = true
89
skip_missing_interpreters = true
910
minversion = 3.14
@@ -13,9 +14,6 @@ requires =
1314
[testenv]
1415
description =
1516
run test suite with {basepython}
16-
path: via PYTHONPATH
17-
sdist: via source distribution
18-
wheel: via wheel
1917
passenv =
2018
LC_ALL
2119
PIP_*
@@ -24,16 +22,12 @@ setenv =
2422
COVERAGE_FILE = {toxworkdir}/.coverage.{envname}
2523
TEST_STATUS_DIR = {envtmpdir}
2624
PYPY3323BUG = 1
27-
path: TEST_MODE = path
28-
sdist: TEST_MODE = sdist
29-
wheel: TEST_MODE = wheel
3025
extras =
3126
test
3227
commands =
3328
pytest -ra --cov --cov-config pyproject.toml \
3429
--cov-report=html:{envdir}/htmlcov --cov-context=test \
35-
--cov-report=xml:{toxworkdir}/coverage.{envname}.xml \
36-
tests {posargs:-n auto}
30+
--cov-report=xml:{toxworkdir}/coverage.{envname}.xml {posargs:-n auto}
3731

3832
[testenv:fix]
3933
description = run static analysis and style checks
@@ -48,18 +42,26 @@ commands =
4842
pre-commit run --all-files --show-diff-on-failure
4943
python -c 'print("hint: run {envdir}/bin/pre-commit install to add checks as pre-commit hook")'
5044

45+
[testenv:path]
46+
description = verify build can run from source (bootstrap)
47+
setenv =
48+
PYTHONPATH = {toxinidir}/src
49+
commands =
50+
python -E -m pip uninstall -y build
51+
pytest -ra {posargs:-n auto}
52+
5153
[testenv:type]
5254
description = run type check on code base
5355
extras = typing
5456
commands =
5557
mypy
5658

57-
[testenv:{py311, py310, py39, py38, py37, py36, pypy3}-min]
59+
[testenv:{py311, py310, py39, py38, py37, py36, pypy37, pypy38, pypy39}-min]
5860
description = check minimum versions required of all dependencies
5961
skip_install = true
6062
commands =
6163
pip install .[test] -c tests/constraints.txt
62-
pytest -ra tests {posargs:-n auto}
64+
pytest -ra {posargs:-n auto}
6365

6466
[testenv:docs]
6567
description = build documentations
@@ -75,7 +77,6 @@ description = generate a DEV environment
7577
usedevelop = true
7678
deps =
7779
virtualenv>=20.0.34
78-
7980
extras =
8081
doc
8182
test
@@ -100,7 +101,7 @@ commands =
100101
coverage xml -o {toxworkdir}/coverage.xml -i
101102
coverage html -d {toxworkdir}/htmlcov -i
102103
python -m diff_cover.diff_cover_tool --compare-branch {env:DIFF_AGAINST:origin/main} {toxworkdir}/coverage.xml
103-
depends = {py311, py310, py39, py38, py37, py36, pypy3}{, -path, -sdist, -wheel}
104+
depends = {py311, py310, py39, py38, py37, py36, pypy37, pypy38, pypy39}
104105

105106
[flake8]
106107
max-line-length = 127

0 commit comments

Comments
 (0)