Skip to content

Commit d2b5f95

Browse files
authored
Add a check for tests which are always skipped (#240)
* Add a check for tests which are always skipped This takes the form of a new script which crawls pytest XML reports and collates them into a single aggregate. It checks for tests which are skipped or missing in all of the reports. The aggregator can be run along with a suite of tox environments via `make collatd-test-report`, and a new CI job runs this in a build. * Don't run tests twice in CI As a first draft, tests ran twice (one for the "test" and once for the skipped test collator). Switch to upload/download of junitxml report data to pass the reports from the matrix to the collator.
1 parent 5c71afa commit d2b5f95

File tree

4 files changed

+73
-3
lines changed

4 files changed

+73
-3
lines changed

.github/workflows/build.yaml

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,30 @@ jobs:
7575
7676
- name: test
7777
run: |
78-
python -m tox run-parallel -m ci
78+
python -m tox run-parallel -m ci -- --junitxml pytest.{envname}.xml
7979
python -m tox run -e cov
8080
81+
- uses: actions/upload-artifact@v3
82+
with:
83+
name: pytest-report-py${{ matrix.py }}-${{ matrix.os }}
84+
path: pytest.*.xml
85+
86+
collate-tests:
87+
needs: [ci-test-matrix]
88+
runs-on: ubuntu-latest
89+
name: "Collate results to check for skipped tests"
90+
steps:
91+
- uses: actions/checkout@v3
92+
- uses: actions/setup-python@v4
93+
with:
94+
python-version: "3.x"
95+
# download everything
96+
- uses: actions/download-artifact@v3
97+
with:
98+
path: artifacts/
99+
# collate and report
100+
- run: python ./scripts/aggregate-pytest-reports.py artifacts/*/pytest.*.xml
101+
81102
self-check:
82103
name: "Self-Check"
83104
runs-on: ubuntu-latest

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ release:
1717
-git push $(shell git rev-parse --abbrev-ref @{push} | cut -d '/' -f1) refs/tags/$(PKG_VERSION)
1818
tox run -e publish-release
1919

20+
.PHONY: collated-test-report
21+
collated-test-report:
22+
tox p
23+
python ./scripts/aggregate-pytest-reports.py .tox/*/pytest.xml
24+
2025
.PHONY: clean
2126
clean:
2227
rm -rf dist build *.egg-info .tox .coverage.*

scripts/aggregate-pytest-reports.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import argparse
2+
import sys
3+
from collections import defaultdict
4+
from xml.etree import ElementTree # nosec
5+
6+
7+
def main():
8+
parser = argparse.ArgumentParser()
9+
parser.add_argument("FILES", nargs="+")
10+
args = parser.parse_args()
11+
12+
tests_by_name = defaultdict(dict)
13+
for filename in args.FILES:
14+
tree = ElementTree.parse(filename)
15+
root = tree.getroot()
16+
17+
for testcase in root.findall("./testsuite/testcase"):
18+
classname = testcase.get("classname")
19+
name = testcase.get("name")
20+
nodename = f"{classname.replace('.', '/')}.py::{name}"
21+
22+
skip_node = testcase.find("skipped")
23+
if skip_node is not None:
24+
if "skipped" not in tests_by_name[nodename]:
25+
tests_by_name[nodename]["skipped"] = True
26+
else:
27+
tests_by_name[nodename]["skipped"] = False
28+
29+
fail = False
30+
for nodename, attributes in tests_by_name.items():
31+
if attributes.get("skipped") is True:
32+
print(f"ALWAYS SKIPPED: {nodename}")
33+
fail = True
34+
35+
if fail:
36+
print("fail")
37+
sys.exit(1)
38+
print("ok")
39+
sys.exit(0)
40+
41+
42+
if __name__ == "__main__":
43+
main()

tox.ini

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ skip_missing_interpreters = true
1111
minversion = 4.0.0
1212

1313
labels =
14-
ci = py-notoml, py-tomli-format, py-json5, py-pyjson5
14+
ci = py, py-notoml, py-tomli-format, py-json5, py-pyjson5
1515

1616
[testenv]
1717
description = "run tests with pytest"
@@ -28,7 +28,8 @@ deps =
2828
format: jsonschema[format]
2929
set_env =
3030
notoml: FORCE_TOML_DISABLED=1
31-
commands = coverage run -m pytest {posargs}
31+
commands =
32+
coverage run -m pytest {posargs:--junitxml={envdir}/pytest.xml}
3233

3334
[testenv:cov_clean]
3435
description = "erase coverage data to prepare for a new run"

0 commit comments

Comments
 (0)