summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2021-10-24 09:54:25 -0400
committerNed Batchelder <ned@nedbatchelder.com>2021-10-24 10:14:29 -0400
commit49ac989e7a425c5a15ed4dd46ab09c7c18b36f95 (patch)
treef49b168c9bf2513cbb70fb19acca5c8744a61c4e
parent20baf284341555803d800ec4c248fd0f1b5351f1 (diff)
downloadpython-coveragepy-git-nedbat/test_goldtest.tar.gz
test: test test/goldtest.pynedbat/test_goldtest
-rw-r--r--tests/gold/testing/gettysburg.txt4
-rw-r--r--tests/goldtest.py63
-rw-r--r--tests/test_goldtest.py85
3 files changed, 108 insertions, 44 deletions
diff --git a/tests/gold/testing/gettysburg.txt b/tests/gold/testing/gettysburg.txt
new file mode 100644
index 00000000..e759ba87
--- /dev/null
+++ b/tests/gold/testing/gettysburg.txt
@@ -0,0 +1,4 @@
+Four score and seven years ago our fathers brought forth upon this continent, a
+new nation, conceived in Liberty, and dedicated to the proposition that all men
+are created equal.
+11/19/1863, Gettysburg, Pennsylvania
diff --git a/tests/goldtest.py b/tests/goldtest.py
index 57fa5c06..4f3f882a 100644
--- a/tests/goldtest.py
+++ b/tests/goldtest.py
@@ -9,10 +9,10 @@ import fnmatch
import os
import os.path
import re
-import sys
import xml.etree.ElementTree
from tests.coveragetest import TESTS_DIR
+from tests.helpers import os_sep
def gold_path(path):
@@ -20,58 +20,34 @@ def gold_path(path):
return os.path.join(TESTS_DIR, "gold", path)
-def versioned_directory(d):
- """Find a subdirectory of d specific to the Python version.
- For example, on Python 3.6.4 rc 1, it returns the first of these
- directories that exists::
- d/3.6.4.candidate.1
- d/3.6.4.candidate
- d/3.6.4
- d/3.6
- d/3
- d
- Returns: a string, the path to an existing directory.
- """
- ver_parts = list(map(str, sys.version_info))
- for nparts in range(len(ver_parts), -1, -1):
- version = ".".join(ver_parts[:nparts])
- subdir = os.path.join(d, version)
- if os.path.exists(subdir):
- return subdir
- raise Exception(f"Directory missing: {d}") # pragma: only failure
-
-
def compare(
expected_dir, actual_dir, file_pattern=None,
actual_extra=False, scrubs=None,
):
"""Compare files matching `file_pattern` in `expected_dir` and `actual_dir`.
- A version-specific subdirectory of `expected_dir` will be used if
- it exists.
-
`actual_extra` true means `actual_dir` can have extra files in it
without triggering an assertion.
`scrubs` is a list of pairs: regexes to find and replace to scrub the
files of unimportant differences.
- An assertion will be raised if the directories fail one of their
- matches.
+ If a comparison fails, a message will be written to stdout, the original
+ unscrubbed output of the test will be written to an "/actual/" directory
+ alongside the "/gold/" directory, and an assertion will be raised.
"""
__tracebackhide__ = True # pytest, please don't show me this function.
-
- expected_dir = versioned_directory(expected_dir)
+ assert os_sep("/gold/") in expected_dir
dc = filecmp.dircmp(expected_dir, actual_dir)
diff_files = fnmatch_list(dc.diff_files, file_pattern)
expected_only = fnmatch_list(dc.left_only, file_pattern)
actual_only = fnmatch_list(dc.right_only, file_pattern)
- def save_mismatch(f): # pragma: only failure
+ def save_mismatch(f):
"""Save a mismatched result to tests/actual."""
- save_path = expected_dir.replace("/gold/", "/actual/")
+ save_path = expected_dir.replace(os_sep("/gold/"), os_sep("/actual/"))
os.makedirs(save_path, exist_ok=True)
with open(os.path.join(save_path, f), "w") as savef:
with open(os.path.join(actual_dir, f)) as readf:
@@ -82,7 +58,6 @@ def compare(
# ourselves.
text_diff = []
for f in diff_files:
-
expected_file = os.path.join(expected_dir, f)
with open(expected_file) as fobj:
expected = fobj.read()
@@ -98,13 +73,13 @@ def compare(
if scrubs:
expected = scrub(expected, scrubs)
actual = scrub(actual, scrubs)
- if expected != actual: # pragma: only failure
+ if expected != actual:
text_diff.append(f'{expected_file} != {actual_file}')
expected = expected.splitlines()
actual = actual.splitlines()
- print(f":::: diff {expected_file!r} and {actual_file!r}")
+ print(f":::: diff '{expected_file}' and '{actual_file}'")
print("\n".join(difflib.Differ().compare(expected, actual)))
- print(f":::: end diff {expected_file!r} and {actual_file!r}")
+ print(f":::: end diff '{expected_file}' and '{actual_file}'")
save_mismatch(f)
if not actual_extra: # pragma: only failure
@@ -118,15 +93,6 @@ def compare(
assert not actual_only, f"Files in {actual_dir} only: {actual_only}"
-def canonicalize_xml(xtext):
- """Canonicalize some XML text."""
- root = xml.etree.ElementTree.fromstring(xtext)
- for node in root.iter():
- node.attrib = dict(sorted(node.items()))
- xtext = xml.etree.ElementTree.tostring(root)
- return xtext.decode("utf-8")
-
-
def contains(filename, *strlist):
"""Check that the file contains all of a list of strings.
@@ -190,6 +156,15 @@ def doesnt_contain(filename, *strlist):
# Helpers
+def canonicalize_xml(xtext):
+ """Canonicalize some XML text."""
+ root = xml.etree.ElementTree.fromstring(xtext)
+ for node in root.iter():
+ node.attrib = dict(sorted(node.items()))
+ xtext = xml.etree.ElementTree.tostring(root)
+ return xtext.decode("utf-8")
+
+
def fnmatch_list(files, file_pattern):
"""Filter the list of `files` to only those that match `file_pattern`.
If `file_pattern` is None, then return the entire list of files.
diff --git a/tests/test_goldtest.py b/tests/test_goldtest.py
new file mode 100644
index 00000000..fcd41579
--- /dev/null
+++ b/tests/test_goldtest.py
@@ -0,0 +1,85 @@
+# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
+# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
+
+"""Tests of the helpers in goldtest.py"""
+
+import os.path
+import re
+
+import pytest
+
+from tests.coveragetest import CoverageTest, TESTS_DIR
+from tests.goldtest import compare, gold_path
+from tests.helpers import os_sep, re_line, remove_tree
+
+GOOD_GETTY = """\
+Four score and seven years ago our fathers brought forth upon this continent, a
+new nation, conceived in Liberty, and dedicated to the proposition that all men
+are created equal.
+11/19/9999, Gettysburg, Pennsylvania
+"""
+
+BAD_GETTY = """\
+Five score and seven years ago our fathers brought forth upon this continent, a
+new nation, conceived in Liberty, and dedicated to the proposition that all men
+are created equal.
+333/4444/55555, Gettysburg, Pennsylvania
+"""
+
+SCRUBS = [
+ # Numbers don't matter when comparing.
+ (r'\d+', 'D'),
+]
+
+ACTUAL_DIR = os.path.join(TESTS_DIR, "actual/testing")
+ACTUAL_GETTY_FILE = os.path.join(ACTUAL_DIR, "gettysburg.txt")
+
+GOLD_PATH_RE = re.escape(os_sep("/tests/gold/testing/gettysburg.txt"))
+OUT_PATH_RE = re.escape(os_sep("out/gettysburg.txt"))
+
+class CompareTest(CoverageTest):
+ """Tests of goldtest.py:compare()"""
+
+ def setup_test(self):
+ super().setup_test()
+ self.addCleanup(remove_tree, ACTUAL_DIR)
+
+ def test_compare_good(self):
+ self.make_file("out/gettysburg.txt", GOOD_GETTY)
+ compare(gold_path("testing"), "out", scrubs=SCRUBS)
+ self.assert_doesnt_exist(ACTUAL_GETTY_FILE)
+
+ def test_compare_bad(self):
+ self.make_file("out/gettysburg.txt", BAD_GETTY)
+
+ # compare() raises an assertion.
+ msg = rf"Files differ: .*{GOLD_PATH_RE} != {OUT_PATH_RE}"
+ with pytest.raises(AssertionError, match=msg):
+ compare(gold_path("testing"), "out", scrubs=SCRUBS)
+
+ # Stdout has a description of the diff. The diff shows the scrubbed content.
+ stdout = self.stdout()
+ print(stdout)
+ assert "- Four score" in stdout
+ assert "+ Five score" in stdout
+ assert re_line(stdout, rf"^:::: diff '.*{GOLD_PATH_RE}' and '{OUT_PATH_RE}'")
+ assert re_line(stdout, rf"^:::: end diff '.*{GOLD_PATH_RE}' and '{OUT_PATH_RE}'")
+ assert " D/D/D, Gettysburg, Pennsylvania" in stdout
+
+ # The actual file was saved.
+ with open(ACTUAL_GETTY_FILE) as f:
+ saved = f.read()
+ assert saved == BAD_GETTY
+
+ def test_compare_good_needs_scrubs(self):
+ # Comparing the "good" result without scrubbing the variable parts will fail.
+ self.make_file("out/gettysburg.txt", GOOD_GETTY)
+
+ # compare() raises an assertion.
+ msg = rf"Files differ: .*{GOLD_PATH_RE} != {OUT_PATH_RE}"
+ with pytest.raises(AssertionError, match=msg):
+ compare(gold_path("testing"), "out")
+
+ stdout = self.stdout()
+ assert "- 11/19/1863, Gettysburg, Pennsylvania" in stdout
+ assert "+ 11/19/9999, Gettysburg, Pennsylvania" in stdout