Skip to content

Commit a8c5219

Browse files
authored
Add a pytest based testing framework and tests for build (#160)
Closes #154
2 parents 26b55f8 + 0382efa commit a8c5219

6 files changed

Lines changed: 211 additions & 130 deletions

File tree

.github/workflows/test.sh

Lines changed: 0 additions & 122 deletions
This file was deleted.

.github/workflows/test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@ jobs:
3030
run: |
3131
sudo apt-get update
3232
sudo apt-get install -y gdb
33-
- name: Tests
33+
- name: Tests PyTest
3434
run: |
35-
pipx run nox --forcecolor -s tests
35+
pipx run nox --forcecolor -s test

noxfile.py

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

33

44
@nox.session
5-
def tests(session: nox.Session) -> None:
6-
"""
7-
Run the unit and regular tests.
8-
"""
9-
session.install(".", "pytest", "build")
5+
def test(session: nox.Session) -> None:
6+
session.install(".", "pytest", "build", "meson-python", "ninja")
107
session.run("pytest", "spin", *session.posargs)
11-
session.run("bash", ".github/workflows/test.sh", external=True)

spin/tests/conftest.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import os
2+
3+
import pytest
4+
5+
from spin import util
6+
7+
8+
@pytest.fixture(autouse=True)
9+
def pre_post_test():
10+
# Pre-test code
11+
cwd = os.getcwd()
12+
os.chdir("example_pkg")
13+
14+
try:
15+
yield
16+
finally:
17+
# Post test code
18+
os.chdir(cwd)
19+
util.run(["git", "clean", "-xdf"], cwd="example_pkg")
20+
os.chdir(cwd)

spin/tests/test_build_cmds.py

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
import os
2+
import subprocess
3+
import sys
4+
import tempfile
5+
from pathlib import Path
6+
7+
import pytest
8+
9+
import spin as libspin
10+
from spin.cmds.util import run
11+
12+
skip_on_windows = pytest.mark.skipif(
13+
sys.platform.startswith("win"), reason="Skipped; platform is Windows"
14+
)
15+
16+
on_linux = pytest.mark.skipif(
17+
not sys.platform.startswith("linux"), reason="Skipped; platform not Linux"
18+
)
19+
20+
21+
def spin(*args, **user_kwargs):
22+
default_kwargs = {
23+
"stdout": subprocess.PIPE,
24+
"stderr": subprocess.PIPE,
25+
"sys_exit": True,
26+
}
27+
return run(["spin"] + list(args), **{**default_kwargs, **user_kwargs})
28+
29+
30+
def stdout(p):
31+
return p.stdout.decode("utf-8").strip()
32+
33+
34+
def stderr(p):
35+
return p.stderr.decode("utf-8").strip()
36+
37+
38+
def test_get_version():
39+
p = spin("--version")
40+
assert stdout(p) == f"spin {libspin.__version__}"
41+
42+
43+
def test_basic_build():
44+
"""Does the package build?"""
45+
spin("build")
46+
47+
assert Path("build").exists(), "`build` folder not created after `spin build`"
48+
assert Path(
49+
"build-install"
50+
).exists(), "`build-install` folder not created after `spin build`"
51+
52+
53+
def test_debug_builds():
54+
"""Does spin generate gcov debug output files?"""
55+
spin("build", "--gcov")
56+
57+
debug_files = Path(".").rglob("*.gcno")
58+
assert len(list(debug_files)) != 0, "debug files not generated for gcov build"
59+
60+
61+
def test_expand_pythonpath():
62+
"""Does an $ENV_VAR get expanded in `spin run`?"""
63+
output = spin("run", "echo $PYTHONPATH")
64+
assert any(
65+
p in stdout(output) for p in ("site-packages", "dist-packages")
66+
), f"Expected value of $PYTHONPATH, got {stdout(output)} instead"
67+
68+
69+
def test_run_stdout():
70+
"""Ensure `spin run` only includes command output on stdout."""
71+
p = spin(
72+
"run",
73+
sys.executable,
74+
"-c",
75+
"import sys; del sys.path[0]; import example_pkg; print(example_pkg.__version__)",
76+
)
77+
assert (
78+
stdout(p) == "0.0.0dev0"
79+
), f"`spin run` stdout did not yield version, but {stdout(p)}"
80+
81+
82+
def test_editable_conflict():
83+
"""Do we warn when a conflicting editable install is present?"""
84+
try:
85+
run(["pip", "install", "--quiet", "-e", "."])
86+
assert "Warning! An editable installation" in stdout(
87+
spin("run", "ls")
88+
), "Failed to detect and warn about editable install"
89+
finally:
90+
run(["pip", "uninstall", "--quiet", "-y", "example_pkg"])
91+
92+
93+
# Detecting whether a file is executable is not that easy on Windows,
94+
# as it seems to take into consideration whether that file is associated as an executable.
95+
@skip_on_windows
96+
def test_recommend_run_python():
97+
"""If `spin run file.py` is called, is `spin run python file.py` recommended?"""
98+
with tempfile.NamedTemporaryFile(suffix=".py") as f:
99+
p = spin("run", f.name, sys_exit=False)
100+
assert "Did you mean to call" in stdout(
101+
p
102+
), "Failed to recommend `python run python file.py`"
103+
104+
105+
def test_test():
106+
"""Does the test command run?"""
107+
spin("test")
108+
109+
110+
def test_test_with_pythonpath():
111+
"""Does `spin test` work when PYTHONPATH is set?"""
112+
spin("test", env={**os.environ, "PYTHONPATH": "/tmp"})
113+
114+
115+
def test_sdist():
116+
spin("sdist")
117+
118+
119+
def test_example():
120+
spin("example")
121+
122+
123+
def test_docs():
124+
run(["pip", "install", "--quiet", "sphinx"])
125+
spin("docs")
126+
127+
128+
def test_spin_install():
129+
cwd = os.getcwd()
130+
spin("install")
131+
with tempfile.TemporaryDirectory() as d:
132+
try:
133+
os.chdir(d)
134+
p = run(
135+
[
136+
sys.executable,
137+
"-c",
138+
"import example_pkg; print(example_pkg.__version__)",
139+
],
140+
stdout=subprocess.PIPE,
141+
)
142+
assert stdout(p) == "0.0.0dev0"
143+
finally:
144+
os.chdir(cwd)
145+
run(["pip", "uninstall", "-y", "--quiet", "example_pkg"])
146+
147+
148+
@on_linux
149+
def test_gdb():
150+
p = spin(
151+
"gdb",
152+
"-c",
153+
'import example_pkg; example_pkg.echo("hi")',
154+
"--",
155+
"--eval",
156+
"run",
157+
"--batch",
158+
)
159+
assert "hi" in stdout(p)

spin/tests/util.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import os
2+
import subprocess
3+
4+
from spin.cmds import util
5+
6+
PKG_NAME = "example_pkg"
7+
8+
9+
def assert_cmd(cmd, *args, **kwargs) -> str:
10+
cwd = os.getcwd()
11+
p = util.run(
12+
cmd,
13+
*args,
14+
cwd=PKG_NAME,
15+
replace=False,
16+
sys_exit=False,
17+
output=False,
18+
echo=True,
19+
stdout=subprocess.PIPE,
20+
stderr=subprocess.PIPE,
21+
**kwargs,
22+
)
23+
os.chdir(cwd)
24+
stdout = p.stdout.decode("utf-8").strip()
25+
if not p.returncode == 0:
26+
print(stdout)
27+
raise AssertionError(f"[{cmd}] failed with exit code {p.returncode}")
28+
return p

0 commit comments

Comments
 (0)