From 843de4ea235e7eee3ff24a39a2f8b14da9ef0db0 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Sun, 31 Jan 2021 07:16:56 -0500 Subject: refactor: unittest2pytest -w tests One step of moving to pure pytest tests. --- tests/coveragetest.py | 24 ++-- tests/test_api.py | 201 +++++++++++++-------------- tests/test_arcs.py | 20 ++- tests/test_backward.py | 22 ++- tests/test_cmdline.py | 104 +++++++------- tests/test_collector.py | 4 +- tests/test_concurrency.py | 31 +++-- tests/test_config.py | 261 +++++++++++++++++------------------ tests/test_context.py | 34 +++-- tests/test_coverage.py | 21 +-- tests/test_data.py | 159 +++++++++++----------- tests/test_debug.py | 55 ++++---- tests/test_execfile.py | 81 +++++------ tests/test_filereporter.py | 52 +++---- tests/test_files.py | 53 ++++---- tests/test_html.py | 82 +++++------ tests/test_misc.py | 14 +- tests/test_numbits.py | 26 ++-- tests/test_oddball.py | 59 ++++---- tests/test_parser.py | 169 +++++++++-------------- tests/test_phystokens.py | 49 ++++--- tests/test_plugins.py | 153 +++++++++++---------- tests/test_process.py | 332 ++++++++++++++++++++++----------------------- tests/test_python.py | 2 +- tests/test_results.py | 48 +++---- tests/test_setup.py | 22 +-- tests/test_summary.py | 255 +++++++++++++++++----------------- tests/test_templite.py | 19 ++- tests/test_testing.py | 68 +++++----- tests/test_version.py | 26 ++-- tests/test_xml.py | 13 +- 31 files changed, 1165 insertions(+), 1294 deletions(-) (limited to 'tests') diff --git a/tests/coveragetest.py b/tests/coveragetest.py index dbadd226..ed3f1839 100644 --- a/tests/coveragetest.py +++ b/tests/coveragetest.py @@ -139,7 +139,7 @@ class CoverageTest( # Make them into multi-line strings so we can see what's going wrong. s1 = arcs_to_arcz_repr(a1) s2 = arcs_to_arcz_repr(a2) - self.assertMultiLineEqual(s1, s2, msg) + assert s1 == s2, msg def check_coverage( self, text, lines=None, missing="", report="", @@ -198,7 +198,7 @@ class CoverageTest( if isinstance(lines[0], int): # lines is just a list of numbers, it must match the statements # found in the code. - self.assertEqual(statements, lines) + assert statements == lines else: # lines is a list of possible line number lists, one of them # must match. @@ -210,7 +210,7 @@ class CoverageTest( missing_formatted = analysis.missing_formatted() if isinstance(missing, string_class): - self.assertEqual(missing_formatted, missing) + assert missing_formatted == missing else: for missing_list in missing: if missing_formatted == missing_list: @@ -244,7 +244,7 @@ class CoverageTest( frep = StringIO() cov.report(mod, file=frep, show_missing=True) rep = " ".join(frep.getvalue().split("\n")[2].split()[1:]) - self.assertEqual(report, rep) + assert report == rep return cov @@ -313,19 +313,19 @@ class CoverageTest( def assert_exists(self, fname): """Assert that `fname` is a file that exists.""" msg = "File %r should exist" % fname - self.assertTrue(os.path.exists(fname), msg) + assert os.path.exists(fname), msg def assert_doesnt_exist(self, fname): """Assert that `fname` is a file that doesn't exist.""" msg = "File %r shouldn't exist" % fname - self.assertTrue(not os.path.exists(fname), msg) + assert not os.path.exists(fname), msg def assert_file_count(self, pattern, count): """Assert that there are `count` files matching `pattern`.""" files = sorted(glob.glob(pattern)) msg = "There should be {} files matching {!r}, but there are these: {}" msg = msg.format(count, pattern, files) - self.assertEqual(len(files), count, msg) + assert len(files) == count, msg def assert_starts_with(self, s, prefix, msg=None): """Assert that `s` starts with `prefix`.""" @@ -335,8 +335,8 @@ class CoverageTest( def assert_recent_datetime(self, dt, seconds=10, msg=None): """Assert that `dt` marks a time at most `seconds` seconds ago.""" age = datetime.datetime.now() - dt - self.assertGreaterEqual(age.total_seconds(), 0, msg) - self.assertLessEqual(age.total_seconds(), seconds, msg) + assert age.total_seconds() >= 0, msg + assert age.total_seconds() <= seconds, msg def command_line(self, args, ret=OK): """Run `args` through the command line. @@ -351,7 +351,7 @@ class CoverageTest( """ ret_actual = command_line(args) - self.assertEqual(ret_actual, ret) + assert ret_actual == ret # Some distros rename the coverage command, and need a way to indicate # their new command name to the tests. This is here for them to override, @@ -454,13 +454,13 @@ class CoverageTest( def report_from_command(self, cmd): """Return the report from the `cmd`, with some convenience added.""" report = self.run_command(cmd).replace('\\', '/') - self.assertNotIn("error", report.lower()) + assert "error" not in report.lower() return report def report_lines(self, report): """Return the lines of the report, as a list.""" lines = report.split('\n') - self.assertEqual(lines[-1], "") + assert lines[-1] == "" return lines[:-1] def line_count(self, report): diff --git a/tests/test_api.py b/tests/test_api.py index 62fd9ebc..95559986 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -22,6 +22,7 @@ from coverage.files import abs_file, relative_filename from coverage.misc import CoverageException from tests.coveragetest import CoverageTest, CoverageTestMethodsMixin, TESTS_DIR, UsingModulesMixin +import pytest class ApiTest(CoverageTest): @@ -63,8 +64,8 @@ class ApiTest(CoverageTest): self.start_import_stop(cov, "mycode") _, statements, missing, _ = cov.analysis("not_run.py") - self.assertEqual(statements, [1]) - self.assertEqual(missing, [1]) + assert statements == [1] + assert missing == [1] def test_filenames(self): @@ -82,14 +83,14 @@ class ApiTest(CoverageTest): self.start_import_stop(cov, "mymain") filename, _, _, _ = cov.analysis("mymain.py") - self.assertEqual(os.path.basename(filename), "mymain.py") + assert os.path.basename(filename) == "mymain.py" filename, _, _, _ = cov.analysis("mymod.py") - self.assertEqual(os.path.basename(filename), "mymod.py") + assert os.path.basename(filename) == "mymod.py" filename, _, _, _ = cov.analysis(sys.modules["mymain"]) - self.assertEqual(os.path.basename(filename), "mymain.py") + assert os.path.basename(filename) == "mymain.py" filename, _, _, _ = cov.analysis(sys.modules["mymod"]) - self.assertEqual(os.path.basename(filename), "mymod.py") + assert os.path.basename(filename) == "mymod.py" # Import the Python file, executing it again, once it's been compiled # already. @@ -97,14 +98,14 @@ class ApiTest(CoverageTest): self.start_import_stop(cov, "mymain") filename, _, _, _ = cov.analysis("mymain.py") - self.assertEqual(os.path.basename(filename), "mymain.py") + assert os.path.basename(filename) == "mymain.py" filename, _, _, _ = cov.analysis("mymod.py") - self.assertEqual(os.path.basename(filename), "mymod.py") + assert os.path.basename(filename) == "mymod.py" filename, _, _, _ = cov.analysis(sys.modules["mymain"]) - self.assertEqual(os.path.basename(filename), "mymain.py") + assert os.path.basename(filename) == "mymain.py" filename, _, _, _ = cov.analysis(sys.modules["mymod"]) - self.assertEqual(os.path.basename(filename), "mymod.py") + assert os.path.basename(filename) == "mymod.py" def test_ignore_stdlib(self): self.make_file("mymain.py", """\ @@ -115,15 +116,15 @@ class ApiTest(CoverageTest): # Measure without the stdlib. cov1 = coverage.Coverage() - self.assertEqual(cov1.config.cover_pylib, False) + assert cov1.config.cover_pylib == False self.start_import_stop(cov1, "mymain") # some statements were marked executed in mymain.py _, statements, missing, _ = cov1.analysis("mymain.py") - self.assertNotEqual(statements, missing) + assert statements != missing # but none were in colorsys.py _, statements, missing, _ = cov1.analysis("colorsys.py") - self.assertEqual(statements, missing) + assert statements == missing # Measure with the stdlib. cov2 = coverage.Coverage(cover_pylib=True) @@ -131,10 +132,10 @@ class ApiTest(CoverageTest): # some statements were marked executed in mymain.py _, statements, missing, _ = cov2.analysis("mymain.py") - self.assertNotEqual(statements, missing) + assert statements != missing # and some were marked executed in colorsys.py _, statements, missing, _ = cov2.analysis("colorsys.py") - self.assertNotEqual(statements, missing) + assert statements != missing def test_include_can_measure_stdlib(self): self.make_file("mymain.py", """\ @@ -150,57 +151,55 @@ class ApiTest(CoverageTest): # some statements were marked executed in colorsys.py _, statements, missing, _ = cov1.analysis("colorsys.py") - self.assertNotEqual(statements, missing) + assert statements != missing # but none were in random.py _, statements, missing, _ = cov1.analysis("random.py") - self.assertEqual(statements, missing) + assert statements == missing def test_exclude_list(self): cov = coverage.Coverage() cov.clear_exclude() - self.assertEqual(cov.get_exclude_list(), []) + assert cov.get_exclude_list() == [] cov.exclude("foo") - self.assertEqual(cov.get_exclude_list(), ["foo"]) + assert cov.get_exclude_list() == ["foo"] cov.exclude("bar") - self.assertEqual(cov.get_exclude_list(), ["foo", "bar"]) - self.assertEqual(cov._exclude_regex('exclude'), "(?:foo)|(?:bar)") + assert cov.get_exclude_list() == ["foo", "bar"] + assert cov._exclude_regex('exclude') == "(?:foo)|(?:bar)" cov.clear_exclude() - self.assertEqual(cov.get_exclude_list(), []) + assert cov.get_exclude_list() == [] def test_exclude_partial_list(self): cov = coverage.Coverage() cov.clear_exclude(which='partial') - self.assertEqual(cov.get_exclude_list(which='partial'), []) + assert cov.get_exclude_list(which='partial') == [] cov.exclude("foo", which='partial') - self.assertEqual(cov.get_exclude_list(which='partial'), ["foo"]) + assert cov.get_exclude_list(which='partial') == ["foo"] cov.exclude("bar", which='partial') - self.assertEqual(cov.get_exclude_list(which='partial'), ["foo", "bar"]) - self.assertEqual( - cov._exclude_regex(which='partial'), "(?:foo)|(?:bar)" - ) + assert cov.get_exclude_list(which='partial') == ["foo", "bar"] + assert cov._exclude_regex(which='partial') == "(?:foo)|(?:bar)" cov.clear_exclude(which='partial') - self.assertEqual(cov.get_exclude_list(which='partial'), []) + assert cov.get_exclude_list(which='partial') == [] def test_exclude_and_partial_are_separate_lists(self): cov = coverage.Coverage() cov.clear_exclude(which='partial') cov.clear_exclude(which='exclude') cov.exclude("foo", which='partial') - self.assertEqual(cov.get_exclude_list(which='partial'), ['foo']) - self.assertEqual(cov.get_exclude_list(which='exclude'), []) + assert cov.get_exclude_list(which='partial') == ['foo'] + assert cov.get_exclude_list(which='exclude') == [] cov.exclude("bar", which='exclude') - self.assertEqual(cov.get_exclude_list(which='partial'), ['foo']) - self.assertEqual(cov.get_exclude_list(which='exclude'), ['bar']) + assert cov.get_exclude_list(which='partial') == ['foo'] + assert cov.get_exclude_list(which='exclude') == ['bar'] cov.exclude("p2", which='partial') cov.exclude("e2", which='exclude') - self.assertEqual(cov.get_exclude_list(which='partial'), ['foo', 'p2']) - self.assertEqual(cov.get_exclude_list(which='exclude'), ['bar', 'e2']) + assert cov.get_exclude_list(which='partial') == ['foo', 'p2'] + assert cov.get_exclude_list(which='exclude') == ['bar', 'e2'] cov.clear_exclude(which='partial') - self.assertEqual(cov.get_exclude_list(which='partial'), []) - self.assertEqual(cov.get_exclude_list(which='exclude'), ['bar', 'e2']) + assert cov.get_exclude_list(which='partial') == [] + assert cov.get_exclude_list(which='exclude') == ['bar', 'e2'] cov.clear_exclude(which='exclude') - self.assertEqual(cov.get_exclude_list(which='partial'), []) - self.assertEqual(cov.get_exclude_list(which='exclude'), []) + assert cov.get_exclude_list(which='partial') == [] + assert cov.get_exclude_list(which='exclude') == [] def test_datafile_default(self): # Default data file behavior: it's .coverage @@ -292,7 +291,7 @@ class ApiTest(CoverageTest): # empty summary reports raise exception, just like the xml report cov = coverage.Coverage() cov.erase() - with self.assertRaisesRegex(CoverageException, "No data to report."): + with pytest.raises(CoverageException, match="No data to report."): cov.report() def test_completely_zero_reporting(self): @@ -310,7 +309,7 @@ class ApiTest(CoverageTest): # TOTAL 1 1 0% last = self.last_line_squeezed(self.stdout()) - self.assertEqual("TOTAL 1 1 0%", last) + assert "TOTAL 1 1 0%" == last def test_cov4_data_file(self): cov4_data = ( @@ -319,7 +318,7 @@ class ApiTest(CoverageTest): ) self.make_file(".coverage", cov4_data) cov = coverage.Coverage() - with self.assertRaisesRegex(CoverageException, "Looks like a coverage 4.x data file"): + with pytest.raises(CoverageException, match="Looks like a coverage 4.x data file"): cov.load() cov.erase() @@ -336,11 +335,11 @@ class ApiTest(CoverageTest): def check_code1_code2(self, cov): """Check the analysis is correct for code1.py and code2.py.""" _, statements, missing, _ = cov.analysis("code1.py") - self.assertEqual(statements, [1]) - self.assertEqual(missing, []) + assert statements == [1] + assert missing == [] _, statements, missing, _ = cov.analysis("code2.py") - self.assertEqual(statements, [1, 2]) - self.assertEqual(missing, []) + assert statements == [1, 2] + assert missing == [] def test_start_stop_start_stop(self): self.make_code1_code2() @@ -441,18 +440,18 @@ class ApiTest(CoverageTest): self.assert_exists(".coverage") cov2 = coverage.Coverage() - with self.assertRaisesRegex(CoverageException, r"No data to combine"): + with pytest.raises(CoverageException, match=r"No data to combine"): cov2.combine(strict=True, keep=False) cov3 = coverage.Coverage() cov3.combine() # Now the data is empty! _, statements, missing, _ = cov3.analysis("code1.py") - self.assertEqual(statements, [1]) - self.assertEqual(missing, [1]) + assert statements == [1] + assert missing == [1] _, statements, missing, _ = cov3.analysis("code2.py") - self.assertEqual(statements, [1, 2]) - self.assertEqual(missing, [1, 2]) + assert statements == [1, 2] + assert missing == [1, 2] def test_combining_with_a_used_coverage(self): # Can you use a coverage object to run one shard of a parallel suite, @@ -522,15 +521,15 @@ class ApiTest(CoverageTest): cov.get_data() out = self.stdout() - self.assertIn("Hello\n", out) + assert "Hello\n" in out err = self.stderr() - self.assertIn(textwrap.dedent("""\ + assert textwrap.dedent("""\ Coverage.py warning: Module sys has no Python source. (module-not-python) Coverage.py warning: Module xyzzy was never imported. (module-not-imported) Coverage.py warning: Module quux was never imported. (module-not-imported) Coverage.py warning: No data was collected. (no-data-collected) - """), err) + """) in err def test_warnings_suppressed(self): self.make_file("hello.py", """\ @@ -546,15 +545,13 @@ class ApiTest(CoverageTest): cov.get_data() out = self.stdout() - self.assertIn("Hello\n", out) + assert "Hello\n" in out err = self.stderr() - self.assertIn( - "Coverage.py warning: Module sys has no Python source. (module-not-python)", + assert "Coverage.py warning: Module sys has no Python source. (module-not-python)" in \ err - ) - self.assertNotIn("module-not-imported", err) - self.assertNotIn("no-data-collected", err) + assert "module-not-imported" not in err + assert "no-data-collected" not in err def test_warn_once(self): cov = coverage.Coverage() @@ -562,8 +559,8 @@ class ApiTest(CoverageTest): cov._warn("Warning, warning 1!", slug="bot", once=True) cov._warn("Warning, warning 2!", slug="bot", once=True) err = self.stderr() - self.assertIn("Warning, warning 1!", err) - self.assertNotIn("Warning, warning 2!", err) + assert "Warning, warning 1!" in err + assert "Warning, warning 2!" not in err def test_source_and_include_dont_conflict(self): # A bad fix made this case fail: https://github.com/nedbat/coveragepy/issues/541 @@ -592,7 +589,7 @@ class ApiTest(CoverageTest): --------------------------- TOTAL 1 0 100% """) - self.assertEqual(expected, self.stdout()) + assert expected == self.stdout() def make_test_files(self): """Create a simple file representing a method with two tests. @@ -637,18 +634,16 @@ class ApiTest(CoverageTest): # Labeled data is collected data = cov.get_data() - self.assertEqual( - [u'', u'multiply_six', u'multiply_zero'], + assert [u'', u'multiply_six', u'multiply_zero'] == \ sorted(data.measured_contexts()) - ) filenames = self.get_measured_filenames(data) suite_filename = filenames['testsuite.py'] data.set_query_context("multiply_six") - self.assertEqual([2, 8], sorted(data.lines(suite_filename))) + assert [2, 8] == sorted(data.lines(suite_filename)) data.set_query_context("multiply_zero") - self.assertEqual([2, 5], sorted(data.lines(suite_filename))) + assert [2, 5] == sorted(data.lines(suite_filename)) def test_switch_context_with_static(self): # This test simulates a coverage-aware test runner, @@ -678,18 +673,16 @@ class ApiTest(CoverageTest): # Labeled data is collected data = cov.get_data() - self.assertEqual( - [u'mysuite', u'mysuite|multiply_six', u'mysuite|multiply_zero'], - sorted(data.measured_contexts()), - ) + assert [u'mysuite', u'mysuite|multiply_six', u'mysuite|multiply_zero'] == \ + sorted(data.measured_contexts()) filenames = self.get_measured_filenames(data) suite_filename = filenames['testsuite.py'] data.set_query_context("mysuite|multiply_six") - self.assertEqual([2, 8], sorted(data.lines(suite_filename))) + assert [2, 8] == sorted(data.lines(suite_filename)) data.set_query_context("mysuite|multiply_zero") - self.assertEqual([2, 5], sorted(data.lines(suite_filename))) + assert [2, 5] == sorted(data.lines(suite_filename)) def test_dynamic_context_conflict(self): cov = coverage.Coverage(source=["."]) @@ -698,24 +691,22 @@ class ApiTest(CoverageTest): # Switch twice, but only get one warning. cov.switch_context("test1") # pragma: nested cov.switch_context("test2") # pragma: nested - self.assertEqual( # pragma: nested - self.stderr(), + assert self.stderr() == \ "Coverage.py warning: Conflicting dynamic contexts (dynamic-conflict)\n" - ) cov.stop() # pragma: nested def test_switch_context_unstarted(self): # Coverage must be started to switch context msg = "Cannot switch context, coverage is not started" cov = coverage.Coverage() - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): cov.switch_context("test1") cov.start() cov.switch_context("test2") # pragma: nested cov.stop() # pragma: nested - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): cov.switch_context("test3") def test_config_crash(self): @@ -723,7 +714,7 @@ class ApiTest(CoverageTest): # exceptions from inside Coverage. cov = coverage.Coverage() cov.set_option("run:_crash", "test_config_crash") - with self.assertRaisesRegex(Exception, "Crashing because called by test_config_crash"): + with pytest.raises(Exception, match="Crashing because called by test_config_crash"): cov.start() def test_config_crash_no_crash(self): @@ -791,7 +782,7 @@ class NamespaceModuleTest(UsingModulesMixin, CoverageTest): cov = coverage.Coverage() self.start_import_stop(cov, "main") - with self.assertRaisesRegex(CoverageException, r"Module .* has no file"): + with pytest.raises(CoverageException, match=r"Module .* has no file"): cov.analysis(sys.modules['namespace_420']) def test_bug_572(self): @@ -815,12 +806,12 @@ class IncludeOmitTestsMixin(UsingModulesMixin, CoverageTestMethodsMixin): def filenames_in(self, summary, filenames): """Assert the `filenames` are in the keys of `summary`.""" for filename in filenames.split(): - self.assertIn(filename, summary) + assert filename in summary def filenames_not_in(self, summary, filenames): """Assert the `filenames` are not in the keys of `summary`.""" for filename in filenames.split(): - self.assertNotIn(filename, summary) + assert filename not in summary def test_nothing_specified(self): result = self.coverage_usepkgs() @@ -892,27 +883,27 @@ class SourceIncludeOmitTest(IncludeOmitTestsMixin, CoverageTest): cov.stop() # pragma: nested def test_source_package_as_package(self): - self.assertFalse(os.path.isdir("pkg1")) + assert not os.path.isdir("pkg1") lines = self.coverage_usepkgs(source=["pkg1"]) self.filenames_in(lines, "p1a p1b") self.filenames_not_in(lines, "p2a p2b othera otherb osa osb") # Because source= was specified, we do search for unexecuted files. - self.assertEqual(lines['p1c'], 0) + assert lines['p1c'] == 0 def test_source_package_as_dir(self): self.chdir(self.nice_file(TESTS_DIR, 'modules')) - self.assertTrue(os.path.isdir("pkg1")) + assert os.path.isdir("pkg1") lines = self.coverage_usepkgs(source=["pkg1"]) self.filenames_in(lines, "p1a p1b") self.filenames_not_in(lines, "p2a p2b othera otherb osa osb") # Because source= was specified, we do search for unexecuted files. - self.assertEqual(lines['p1c'], 0) + assert lines['p1c'] == 0 def test_source_package_dotted_sub(self): lines = self.coverage_usepkgs(source=["pkg1.sub"]) self.filenames_not_in(lines, "p2a p2b othera otherb osa osb") # Because source= was specified, we do search for unexecuted files. - self.assertEqual(lines['runmod3'], 0) + assert lines['runmod3'] == 0 def test_source_package_dotted_p1b(self): lines = self.coverage_usepkgs(source=["pkg1.p1b"]) @@ -930,14 +921,14 @@ class SourceIncludeOmitTest(IncludeOmitTestsMixin, CoverageTest): lines = self.coverage_usepkgs(source=["pkg1"], omit=["pkg1/p1b.py"]) self.filenames_in(lines, "p1a") self.filenames_not_in(lines, "p1b") - self.assertEqual(lines['p1c'], 0) + assert lines['p1c'] == 0 def test_source_package_as_package_part_omitted(self): # https://github.com/nedbat/coveragepy/issues/638 lines = self.coverage_usepkgs(source=["pkg1"], omit=["*/p1b.py"]) self.filenames_in(lines, "p1a") self.filenames_not_in(lines, "p1b") - self.assertEqual(lines['p1c'], 0) + assert lines['p1c'] == 0 def test_ambiguous_source_package_as_dir(self): # pkg1 is a directory and a pkg, since we cd into tests/modules/ambiguous @@ -954,7 +945,7 @@ class SourceIncludeOmitTest(IncludeOmitTestsMixin, CoverageTest): self.filenames_in(lines, "p1a p1b") self.filenames_not_in(lines, "p2a p2b othera otherb osa osb ambiguous") # Because source= was specified, we do search for unexecuted files. - self.assertEqual(lines['p1c'], 0) + assert lines['p1c'] == 0 class ReportIncludeOmitTest(IncludeOmitTestsMixin, CoverageTest): @@ -1012,13 +1003,13 @@ class AnalysisTest(CoverageTest): self.start_import_stop(cov, "missing") nums = cov._analyze("missing.py").numbers - self.assertEqual(nums.n_files, 1) - self.assertEqual(nums.n_statements, 7) - self.assertEqual(nums.n_excluded, 1) - self.assertEqual(nums.n_missing, 3) - self.assertEqual(nums.n_branches, 2) - self.assertEqual(nums.n_partial_branches, 0) - self.assertEqual(nums.n_missing_branches, 2) + assert nums.n_files == 1 + assert nums.n_statements == 7 + assert nums.n_excluded == 1 + assert nums.n_missing == 3 + assert nums.n_branches == 2 + assert nums.n_partial_branches == 0 + assert nums.n_missing_branches == 2 class TestRunnerPluginTest(CoverageTest): @@ -1049,13 +1040,13 @@ class TestRunnerPluginTest(CoverageTest): cov.combine() cov.save() cov.report(["no_biggie.py"], show_missing=True) - self.assertEqual(self.stdout(), textwrap.dedent("""\ + assert self.stdout() == textwrap.dedent("""\ Name Stmts Miss Cover Missing -------------------------------------------- no_biggie.py 4 1 75% 4 -------------------------------------------- TOTAL 4 1 75% - """)) + """) if cd: os.chdir("..") @@ -1094,13 +1085,13 @@ class TestRunnerPluginTest(CoverageTest): report = StringIO() cov.report(show_missing=None, ignore_errors=True, file=report, skip_covered=None, skip_empty=None) - self.assertEqual(report.getvalue(), textwrap.dedent("""\ + assert report.getvalue() == textwrap.dedent("""\ Name Stmts Miss Cover ----------------------------- prog.py 4 1 75% ----------------------------- TOTAL 4 1 75% - """)) + """) self.assert_file_count(".coverage", 0) self.assert_file_count(".coverage.*", 1) @@ -1117,9 +1108,9 @@ class ImmutableConfigTest(CoverageTest): self.make_file("simple.py", "a = 1") cov = coverage.Coverage() self.start_import_stop(cov, "simple") - self.assertEqual(cov.get_option("report:show_missing"), False) + assert cov.get_option("report:show_missing") == False cov.report(show_missing=True) - self.assertEqual(cov.get_option("report:show_missing"), False) + assert cov.get_option("report:show_missing") == False class RelativePathTest(CoverageTest): @@ -1140,7 +1131,7 @@ class RelativePathTest(CoverageTest): with change_dir("new"): cov = coverage.Coverage() cov.load() - with self.assertRaisesRegex(CoverageException, expected): + with pytest.raises(CoverageException, match=expected): cov.report() def test_moving_stuff_with_relative(self): diff --git a/tests/test_arcs.py b/tests/test_arcs.py index f3aa8ebb..79280e2d 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -322,7 +322,7 @@ class LoopArcTest(CoverageTest): return 1 """) out = self.run_command("coverage run --branch --source=. main.py") - self.assertEqual(out, 'done\n') + assert out == 'done\n' if env.PYBEHAVIOR.keep_constant_test: num_stmts = 3 elif env.PYBEHAVIOR.nix_while_true: @@ -332,7 +332,7 @@ class LoopArcTest(CoverageTest): expected = "zero.py {n} {n} 0 0 0% 1-3".format(n=num_stmts) report = self.report_from_command("coverage report -m") squeezed = self.squeezed_lines(report) - self.assertIn(expected, squeezed[3]) + assert expected in squeezed[3] def test_bug_496_continue_in_constant_while(self): # https://github.com/nedbat/coveragepy/issues/496 @@ -1086,7 +1086,7 @@ class YieldTest(CoverageTest): ".2 23 34 45 52 2.", arcz_missing="2.", ) - self.assertEqual(self.stdout(), "20\n12\n") + assert self.stdout() == "20\n12\n" def test_yield_from(self): if not env.PYBEHAVIOR.yield_from: @@ -1387,7 +1387,7 @@ class MiscArcTest(CoverageTest): print(len(data)) """ self.check_coverage(code, arcs=[(-1, 1), (1, 2*n+4), (2*n+4, -1)]) - self.assertEqual(self.stdout().split()[-1], str(n)) + assert self.stdout().split()[-1] == str(n) def test_partial_generators(self): # https://github.com/nedbat/coveragepy/issues/475 @@ -1410,14 +1410,10 @@ class MiscArcTest(CoverageTest): filename = self.last_module_name + ".py" fr = cov._get_file_reporter(filename) arcs_executed = cov._analyze(filename).arcs_executed() - self.assertEqual( - fr.missing_arc_description(3, -3, arcs_executed), + assert fr.missing_arc_description(3, -3, arcs_executed) == \ "line 3 didn't finish the generator expression on line 3" - ) - self.assertEqual( - fr.missing_arc_description(4, -4, arcs_executed), + assert fr.missing_arc_description(4, -4, arcs_executed) == \ "line 4 didn't run the generator expression on line 4" - ) class DecoratorArcTest(CoverageTest): @@ -1620,7 +1616,7 @@ class AsyncTest(CoverageTest): "-89 9C C-8", arcz_unpredicted="5-3 9-8", ) - self.assertEqual(self.stdout(), "Compute 1 + 2 ...\n1 + 2 = 3\n") + assert self.stdout() == "Compute 1 + 2 ...\n1 + 2 = 3\n" def test_async_for(self): self.check_coverage("""\ @@ -1657,7 +1653,7 @@ class AsyncTest(CoverageTest): "-AB BC C-A DE E-A ", # __anext__ arcz_unpredicted="CD", ) - self.assertEqual(self.stdout(), "a\nb\nc\n.\n") + assert self.stdout() == "a\nb\nc\n.\n" def test_async_with(self): self.check_coverage("""\ diff --git a/tests/test_backward.py b/tests/test_backward.py index 8acb8707..01cc8dac 100644 --- a/tests/test_backward.py +++ b/tests/test_backward.py @@ -5,18 +5,14 @@ from coverage.backunittest import TestCase from coverage.backward import iitems, binary_bytes, bytes_to_ints - - -class BackwardTest(TestCase): - """Tests of things from backward.py.""" - - def test_iitems(self): - d = {'a': 1, 'b': 2, 'c': 3} - items = [('a', 1), ('b', 2), ('c', 3)] - self.assertCountEqual(list(iitems(d)), items) +"""Tests of things from backward.py.""" +deftest_iitems(self): + d = {'a': 1, 'b': 2, 'c': 3} + items = [('a', 1), ('b', 2), ('c', 3)] + self.assertCountEqual(list(iitems(d)), items) def test_binary_bytes(self): - byte_values = [0, 255, 17, 23, 42, 57] - bb = binary_bytes(byte_values) - self.assertEqual(len(bb), len(byte_values)) - self.assertEqual(byte_values, list(bytes_to_ints(bb))) + byte_values = [0, 255, 17, 23, 42, 57] + bb = binary_bytes(byte_values) + assert len(bb) == len(byte_values) + assert byte_values == list(bytes_to_ints(bb)) diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py index 3b11881b..2c24c598 100644 --- a/tests/test_cmdline.py +++ b/tests/test_cmdline.py @@ -113,7 +113,7 @@ class BaseCmdLineTest(CoverageTest): def cmd_executes(self, args, code, ret=OK, options=None): """Assert that the `args` end up executing the sequence in `code`.""" called, status = self.mock_command_line(args, options=options) - self.assertEqual(status, ret, "Wrong status: got %r, wanted %r" % (status, ret)) + assert status == ret, "Wrong status: got %r, wanted %r" % (status, ret) # Remove all indentation, and execute with mock globals code = textwrap.dedent(code) @@ -136,7 +136,7 @@ class BaseCmdLineTest(CoverageTest): """Assert that the `args1` executes the same as `args2`.""" m1, r1 = self.mock_command_line(args1) m2, r2 = self.mock_command_line(args2) - self.assertEqual(r1, r2) + assert r1 == r2 self.assert_same_mock_calls(m1, m2) def assert_same_mock_calls(self, m1, m2): @@ -147,7 +147,7 @@ class BaseCmdLineTest(CoverageTest): if m1.mock_calls != m2.mock_calls: pp1 = pprint.pformat(m1.mock_calls) pp2 = pprint.pformat(m2.mock_calls) - self.assertMultiLineEqual(pp1+'\n', pp2+'\n') + assert pp1+'\n' == pp2+'\n' def cmd_help(self, args, help_msg=None, topic=None, ret=ERR): """Run a command line, and check that it prints the right help. @@ -157,11 +157,11 @@ class BaseCmdLineTest(CoverageTest): """ mk, status = self.mock_command_line(args) - self.assertEqual(status, ret, "Wrong status: got %s, wanted %s" % (status, ret)) + assert status == ret, "Wrong status: got %s, wanted %s" % (status, ret) if help_msg: - self.assertEqual(mk.mock_calls[-1], ('show_help', (help_msg,), {})) + assert mk.mock_calls[-1] == ('show_help', (help_msg,), {}) else: - self.assertEqual(mk.mock_calls[-1], ('show_help', (), {'topic': topic})) + assert mk.mock_calls[-1] == ('show_help', (), {'topic': topic}) class BaseCmdLineTestTest(BaseCmdLineTest): @@ -169,7 +169,7 @@ class BaseCmdLineTestTest(BaseCmdLineTest): def test_cmd_executes_same(self): # All the other tests here use self.cmd_executes_same in successful # ways, so here we just check that it fails. - with self.assertRaises(AssertionError): + with pytest.raises(AssertionError): self.cmd_executes_same("run", "debug") @@ -255,15 +255,15 @@ class CmdLineTest(BaseCmdLineTest): def test_debug_sys(self): self.command_line("debug sys") out = self.stdout() - self.assertIn("version:", out) - self.assertIn("data_file:", out) + assert "version:" in out + assert "data_file:" in out def test_debug_config(self): self.command_line("debug config") out = self.stdout() - self.assertIn("cover_pylib:", out) - self.assertIn("skip_covered:", out) - self.assertIn("skip_empty:", out) + assert "cover_pylib:" in out + assert "skip_covered:" in out + assert "skip_empty:" in out def test_erase(self): # coverage erase @@ -529,7 +529,7 @@ class CmdLineTest(BaseCmdLineTest): def test_bad_concurrency(self): self.command_line("run --concurrency=nothing", ret=ERR) err = self.stderr() - self.assertIn("option --concurrency: invalid choice: 'nothing'", err) + assert "option --concurrency: invalid choice: 'nothing'" in err def test_no_multiple_concurrency(self): # You can't use multiple concurrency values on the command line. @@ -537,21 +537,17 @@ class CmdLineTest(BaseCmdLineTest): # values for this option, but optparse is not that flexible. self.command_line("run --concurrency=multiprocessing,gevent foo.py", ret=ERR) err = self.stderr() - self.assertIn("option --concurrency: invalid choice: 'multiprocessing,gevent'", err) + assert "option --concurrency: invalid choice: 'multiprocessing,gevent'" in err def test_multiprocessing_needs_config_file(self): # You can't use command-line args to add options to multiprocessing # runs, since they won't make it to the subprocesses. You need to use a # config file. self.command_line("run --concurrency=multiprocessing --branch foo.py", ret=ERR) - self.assertIn( - "Options affecting multiprocessing must only be specified in a configuration file.", + assert "Options affecting multiprocessing must only be specified in a configuration file." in \ self.stderr() - ) - self.assertIn( - "Remove --branch from the command line.", + assert "Remove --branch from the command line." in \ self.stderr() - ) def test_run_debug(self): self.cmd_executes("run --debug=opt1 foo.py", """\ @@ -605,7 +601,7 @@ class CmdLineTest(BaseCmdLineTest): def test_run_nothing(self): self.command_line("run", ret=ERR) - self.assertIn("Nothing to do", self.stderr()) + assert "Nothing to do" in self.stderr() def test_run_from_config(self): options = {"run:command_line": "myprog.py a 123 'a quoted thing' xyz"} @@ -660,7 +656,7 @@ class CmdLineTest(BaseCmdLineTest): def test_cant_append_parallel(self): self.command_line("run --append --parallel-mode foo.py", ret=ERR) - self.assertIn("Can't append to data files in parallel mode.", self.stderr()) + assert "Can't append to data files in parallel mode." in self.stderr() def test_xml(self): # coverage xml [-i] [--omit DIR,...] [FILE1 FILE2 ...] @@ -781,7 +777,7 @@ class CmdLineWithFilesTest(BaseCmdLineTest): data.write() self.command_line("debug data") - self.assertMultiLineEqual(self.stdout(), textwrap.dedent("""\ + assert self.stdout() == textwrap.dedent("""\ -- data ------------------------------------------------------ path: FILENAME has_arcs: False @@ -789,16 +785,16 @@ class CmdLineWithFilesTest(BaseCmdLineTest): 2 files: file1.py: 17 lines [a_plugin] file2.py: 23 lines - """).replace("FILENAME", data.data_filename())) + """).replace("FILENAME", data.data_filename()) def test_debug_data_with_no_data(self): data = CoverageData() self.command_line("debug data") - self.assertMultiLineEqual(self.stdout(), textwrap.dedent("""\ + assert self.stdout() == textwrap.dedent("""\ -- data ------------------------------------------------------ path: FILENAME No data collected - """).replace("FILENAME", data.data_filename())) + """).replace("FILENAME", data.data_filename()) class CmdLineStdoutTest(BaseCmdLineTest): @@ -807,18 +803,18 @@ class CmdLineStdoutTest(BaseCmdLineTest): def test_minimum_help(self): self.command_line("") out = self.stdout() - self.assertIn("Code coverage for Python", out) - self.assertLess(out.count("\n"), 4) + assert "Code coverage for Python" in out + assert out.count("\n") < 4 def test_version(self): self.command_line("--version") out = self.stdout() - self.assertIn("ersion ", out) + assert "ersion " in out if env.C_TRACER: - self.assertIn("with C extension", out) + assert "with C extension" in out else: - self.assertIn("without C extension", out) - self.assertLess(out.count("\n"), 4) + assert "without C extension" in out + assert out.count("\n") < 4 def test_help_contains_command_name(self): # Command name should be present in help output. @@ -830,7 +826,7 @@ class CmdLineStdoutTest(BaseCmdLineTest): with mock.patch.object(sys, 'argv', new=fake_argv): self.command_line("help") out = self.stdout() - self.assertIn(expected_command_name, out) + assert expected_command_name in out def test_help_contains_command_name_from_package(self): # Command package name should be present in help output. @@ -847,38 +843,38 @@ class CmdLineStdoutTest(BaseCmdLineTest): with mock.patch.object(sys, 'argv', new=fake_argv): self.command_line("help") out = self.stdout() - self.assertIn(expected_command_name, out) + assert expected_command_name in out def test_help(self): self.command_line("help") lines = self.stdout().splitlines() - self.assertGreater(len(lines), 10) - self.assertEqual(lines[-1], "Full documentation is at {}".format(__url__)) + assert len(lines) > 10 + assert lines[-1] == "Full documentation is at {}".format(__url__) def test_cmd_help(self): self.command_line("help run") out = self.stdout() lines = out.splitlines() - self.assertIn("", lines[0]) - self.assertIn("--timid", out) - self.assertGreater(len(lines), 20) - self.assertEqual(lines[-1], "Full documentation is at {}".format(__url__)) + assert "" in lines[0] + assert "--timid" in out + assert len(lines) > 20 + assert lines[-1] == "Full documentation is at {}".format(__url__) def test_unknown_topic(self): # Should probably be an ERR return, but meh. self.command_line("help foobar") lines = self.stdout().splitlines() - self.assertEqual(lines[0], "Don't know topic 'foobar'") - self.assertEqual(lines[-1], "Full documentation is at {}".format(__url__)) + assert lines[0] == "Don't know topic 'foobar'" + assert lines[-1] == "Full documentation is at {}".format(__url__) def test_error(self): self.command_line("fooey kablooey", ret=ERR) err = self.stderr() - self.assertIn("fooey", err) - self.assertIn("help", err) + assert "fooey" in err + assert "help" in err def test_doc_url(self): - self.assertTrue(__url__.startswith("https://coverage.readthedocs.io")) + assert __url__.startswith("https://coverage.readthedocs.io") class CmdMainTest(CoverageTest): @@ -914,25 +910,25 @@ class CmdMainTest(CoverageTest): def test_normal(self): ret = coverage.cmdline.main(['hello']) - self.assertEqual(ret, 0) - self.assertEqual(self.stdout(), "Hello, world!\n") + assert ret == 0 + assert self.stdout() == "Hello, world!\n" def test_raise(self): ret = coverage.cmdline.main(['raise']) - self.assertEqual(ret, 1) - self.assertEqual(self.stdout(), "") + assert ret == 1 + assert self.stdout() == "" err = self.stderr().split('\n') - self.assertEqual(err[0], 'Traceback (most recent call last):') - self.assertEqual(err[-3], ' raise Exception("oh noes!")') - self.assertEqual(err[-2], 'Exception: oh noes!') + assert err[0] == 'Traceback (most recent call last):' + assert err[-3] == ' raise Exception("oh noes!")' + assert err[-2] == 'Exception: oh noes!' def test_internalraise(self): - with self.assertRaisesRegex(ValueError, "coverage is broken"): + with pytest.raises(ValueError, match="coverage is broken"): coverage.cmdline.main(['internalraise']) def test_exit(self): ret = coverage.cmdline.main(['exit']) - self.assertEqual(ret, 23) + assert ret == 23 class CoverageReportingFake(object): diff --git a/tests/test_collector.py b/tests/test_collector.py index f7e8a4c4..53d7f175 100644 --- a/tests/test_collector.py +++ b/tests/test_collector.py @@ -46,5 +46,5 @@ class CollectorTest(CoverageTest): # Double-check that our files were checked. abs_files = {os.path.abspath(f) for f in should_trace_hook.filenames} - self.assertIn(os.path.abspath("f1.py"), abs_files) - self.assertIn(os.path.abspath("f2.py"), abs_files) + assert os.path.abspath("f1.py") in abs_files + assert os.path.abspath("f2.py") in abs_files diff --git a/tests/test_concurrency.py b/tests/test_concurrency.py index 2469e296..cc9622d1 100644 --- a/tests/test_concurrency.py +++ b/tests/test_concurrency.py @@ -20,6 +20,7 @@ from coverage.files import abs_file from tests.coveragetest import CoverageTest from tests.helpers import remove_files +import re # These libraries aren't always available, we'll skip tests if they aren't. @@ -91,7 +92,7 @@ class LineCountTest(CoverageTest): print("done") """ - self.assertEqual(line_count(CODE), 5) + assert line_count(CODE) == 5 # The code common to all the concurrency models. @@ -227,14 +228,14 @@ class ConcurrencyTest(CoverageTest): expected_cant_trace = cant_trace_msg(concurrency, the_module) if expected_cant_trace is not None: - self.assertEqual(out, expected_cant_trace) + assert out == expected_cant_trace else: # We can fully measure the code if we are using the C tracer, which # can support all the concurrency, or if we are using threads. if expected_out is None: expected_out = "%d\n" % (sum(range(self.QLIMIT))) print(code) - self.assertEqual(out, expected_out) + assert out == expected_out # Read the coverage file and see that try_it.py has all its lines # executed. @@ -248,7 +249,7 @@ class ConcurrencyTest(CoverageTest): print_simple_annotation(code, linenos) lines = line_count(code) - self.assertEqual(line_counts(data)['try_it.py'], lines) + assert line_counts(data)['try_it.py'] == lines def test_threads(self): code = (THREAD + SUM_RANGE_Q + PRINT_SUM_RANGE).format(QLIMIT=self.QLIMIT) @@ -399,17 +400,17 @@ class MultiprocessingTest(CoverageTest): expected_cant_trace = cant_trace_msg(concurrency, the_module) if expected_cant_trace is not None: - self.assertEqual(out, expected_cant_trace) + assert out == expected_cant_trace else: - self.assertEqual(out.rstrip(), expected_out) - self.assertEqual(len(glob.glob(".coverage.*")), nprocs + 1) + assert out.rstrip() == expected_out + assert len(glob.glob(".coverage.*")) == nprocs + 1 out = self.run_command("coverage combine") - self.assertEqual(out, "") + assert out == "" out = self.run_command("coverage report -m") last_line = self.squeezed_lines(out)[-1] - self.assertRegex(last_line, r"TOTAL \d+ 0 100%") + assert re.search(r"TOTAL \d+ 0 100%", last_line) def test_multiprocessing_simple(self): nprocs = 3 @@ -459,14 +460,14 @@ class MultiprocessingTest(CoverageTest): continue out = self.run_command("coverage run --rcfile=multi.rc multi.py %s" % (start_method,)) - self.assertEqual(out.rstrip(), expected_out) + assert out.rstrip() == expected_out out = self.run_command("coverage combine") - self.assertEqual(out, "") + assert out == "" out = self.run_command("coverage report -m") last_line = self.squeezed_lines(out)[-1] - self.assertRegex(last_line, r"TOTAL \d+ 0 \d+ 0 100%") + assert re.search(r"TOTAL \d+ 0 \d+ 0 100%", last_line) def test_multiprocessing_with_branching(self): nprocs = 3 @@ -490,8 +491,8 @@ class MultiprocessingTest(CoverageTest): _crash = _bootstrap """) out = self.run_command("coverage run multi.py") - self.assertIn("Exception during multiprocessing bootstrap init", out) - self.assertIn("Exception: Crashing because called by _bootstrap", out) + assert "Exception during multiprocessing bootstrap init" in out + assert "Exception: Crashing because called by _bootstrap" in out def test_bug890(self): # chdir in multiprocessing shouldn't keep us from finding the @@ -510,7 +511,7 @@ class MultiprocessingTest(CoverageTest): concurrency = multiprocessing """) out = self.run_command("coverage run multi.py") - self.assertEqual(out.splitlines()[-1], "ok") + assert out.splitlines()[-1] == "ok" def test_coverage_stop_in_threads(): diff --git a/tests/test_config.py b/tests/test_config.py index 4225540c..0a742f3d 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -13,6 +13,7 @@ from coverage.misc import CoverageException from tests.coveragetest import CoverageTest, UsingModulesMixin from tests.helpers import without_module +import pytest class ConfigTest(CoverageTest): @@ -21,17 +22,17 @@ class ConfigTest(CoverageTest): def test_default_config(self): # Just constructing a coverage() object gets the right defaults. cov = coverage.Coverage() - self.assertFalse(cov.config.timid) - self.assertFalse(cov.config.branch) - self.assertEqual(cov.config.data_file, ".coverage") + assert not cov.config.timid + assert not cov.config.branch + assert cov.config.data_file == ".coverage" def test_arguments(self): # Arguments to the constructor are applied to the configuration. cov = coverage.Coverage(timid=True, data_file="fooey.dat", concurrency="multiprocessing") - self.assertTrue(cov.config.timid) - self.assertFalse(cov.config.branch) - self.assertEqual(cov.config.data_file, "fooey.dat") - self.assertEqual(cov.config.concurrency, ["multiprocessing"]) + assert cov.config.timid + assert not cov.config.branch + assert cov.config.data_file == "fooey.dat" + assert cov.config.concurrency == ["multiprocessing"] def test_config_file(self): # A .coveragerc file will be read into the configuration. @@ -42,9 +43,9 @@ class ConfigTest(CoverageTest): data_file = .hello_kitty.data """) cov = coverage.Coverage() - self.assertTrue(cov.config.timid) - self.assertFalse(cov.config.branch) - self.assertEqual(cov.config.data_file, ".hello_kitty.data") + assert cov.config.timid + assert not cov.config.branch + assert cov.config.data_file == ".hello_kitty.data" def test_named_config_file(self): # You can name the config file what you like. @@ -55,9 +56,9 @@ class ConfigTest(CoverageTest): data_file = delete.me """) cov = coverage.Coverage(config_file="my_cov.ini") - self.assertTrue(cov.config.timid) - self.assertFalse(cov.config.branch) - self.assertEqual(cov.config.data_file, "delete.me") + assert cov.config.timid + assert not cov.config.branch + assert cov.config.data_file == "delete.me" def test_toml_config_file(self): # A .coveragerc file will be read into the configuration. @@ -79,18 +80,16 @@ class ConfigTest(CoverageTest): hello = "world" """) cov = coverage.Coverage(config_file="pyproject.toml") - self.assertTrue(cov.config.timid) - self.assertFalse(cov.config.branch) - self.assertEqual(cov.config.concurrency, [u"a", u"b"]) - self.assertEqual(cov.config.data_file, u".hello_kitty.data") - self.assertEqual(cov.config.plugins, [u"plugins.a_plugin"]) - self.assertEqual(cov.config.precision, 3) - self.assertEqual(cov.config.html_title, u"tabblo & «ταБЬℓσ»") - self.assertAlmostEqual(cov.config.fail_under, 90.5) - self.assertEqual( - cov.config.get_plugin_options("plugins.a_plugin"), + assert cov.config.timid + assert not cov.config.branch + assert cov.config.concurrency == [u"a", u"b"] + assert cov.config.data_file == u".hello_kitty.data" + assert cov.config.plugins == [u"plugins.a_plugin"] + assert cov.config.precision == 3 + assert cov.config.html_title == u"tabblo & «ταБЬℓσ»" + assert round(abs(cov.config.fail_under-90.5), 7) == 0 + assert cov.config.get_plugin_options("plugins.a_plugin") == \ {u"hello": u"world"} - ) # Test that our class doesn't reject integers when loading floats self.make_file("pyproject.toml", """\ @@ -99,8 +98,8 @@ class ConfigTest(CoverageTest): fail_under = 90 """) cov = coverage.Coverage(config_file="pyproject.toml") - self.assertAlmostEqual(cov.config.fail_under, 90) - self.assertIsInstance(cov.config.fail_under, float) + assert round(abs(cov.config.fail_under-90), 7) == 0 + assert isinstance(cov.config.fail_under, float) def test_ignored_config_file(self): # You can disable reading the .coveragerc file. @@ -110,9 +109,9 @@ class ConfigTest(CoverageTest): data_file = delete.me """) cov = coverage.Coverage(config_file=False) - self.assertFalse(cov.config.timid) - self.assertFalse(cov.config.branch) - self.assertEqual(cov.config.data_file, ".coverage") + assert not cov.config.timid + assert not cov.config.branch + assert cov.config.data_file == ".coverage" def test_config_file_then_args(self): # The arguments override the .coveragerc file. @@ -122,9 +121,9 @@ class ConfigTest(CoverageTest): data_file = weirdo.file """) cov = coverage.Coverage(timid=False, data_file=".mycov") - self.assertFalse(cov.config.timid) - self.assertFalse(cov.config.branch) - self.assertEqual(cov.config.data_file, ".mycov") + assert not cov.config.timid + assert not cov.config.branch + assert cov.config.data_file == ".mycov" def test_data_file_from_environment(self): # There's an environment variable for the data_file. @@ -135,10 +134,10 @@ class ConfigTest(CoverageTest): """) self.set_environ("COVERAGE_FILE", "fromenv.dat") cov = coverage.Coverage() - self.assertEqual(cov.config.data_file, "fromenv.dat") + assert cov.config.data_file == "fromenv.dat" # But the constructor arguments override the environment variable. cov = coverage.Coverage(data_file="fromarg.dat") - self.assertEqual(cov.config.data_file, "fromarg.dat") + assert cov.config.data_file == "fromarg.dat" def test_debug_from_environment(self): self.make_file(".coveragerc", """\ @@ -147,7 +146,7 @@ class ConfigTest(CoverageTest): """) self.set_environ("COVERAGE_DEBUG", "callers, fooey") cov = coverage.Coverage() - self.assertEqual(cov.config.debug, ["dataio", "pids", "callers", "fooey"]) + assert cov.config.debug == ["dataio", "pids", "callers", "fooey"] def test_rcfile_from_environment(self): self.make_file("here.ini", """\ @@ -156,12 +155,12 @@ class ConfigTest(CoverageTest): """) self.set_environ("COVERAGE_RCFILE", "here.ini") cov = coverage.Coverage() - self.assertEqual(cov.config.data_file, "overthere.dat") + assert cov.config.data_file == "overthere.dat" def test_missing_rcfile_from_environment(self): self.set_environ("COVERAGE_RCFILE", "nowhere.ini") msg = "Couldn't read 'nowhere.ini' as a config file" - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): coverage.Coverage() def test_parse_errors(self): @@ -185,7 +184,7 @@ class ConfigTest(CoverageTest): for bad_config, msg in bad_configs_and_msgs: print("Trying %r" % bad_config) self.make_file(".coveragerc", bad_config) - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): coverage.Coverage() def test_toml_parse_errors(self): @@ -211,7 +210,7 @@ class ConfigTest(CoverageTest): for bad_config, msg in bad_configs_and_msgs: print("Trying %r" % bad_config) self.make_file("pyproject.toml", bad_config) - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): coverage.Coverage() def test_environment_vars_in_config(self): @@ -232,12 +231,10 @@ class ConfigTest(CoverageTest): self.set_environ("THING", "ZZZ") self.set_environ("OKAY", "yes") cov = coverage.Coverage() - self.assertEqual(cov.config.data_file, "hello-world.fooey") - self.assertEqual(cov.config.branch, True) - self.assertEqual( - cov.config.exclude_list, + assert cov.config.data_file == "hello-world.fooey" + assert cov.config.branch == True + assert cov.config.exclude_list == \ ["the_$one", "anotherZZZ", "xZZZy", "xy", "huh${X}what"] - ) def test_environment_vars_in_toml_config(self): # Config files can have $envvars in them. @@ -258,12 +255,10 @@ class ConfigTest(CoverageTest): self.set_environ("DATA_FILE", "hello-world") self.set_environ("THING", "ZZZ") cov = coverage.Coverage() - self.assertEqual(cov.config.data_file, "hello-world.fooey") - self.assertEqual(cov.config.branch, True) - self.assertEqual( - cov.config.exclude_list, + assert cov.config.data_file == "hello-world.fooey" + assert cov.config.branch == True + assert cov.config.exclude_list == \ ["the_$one", "anotherZZZ", "xZZZy", "xy", "huh${X}what"] - ) def test_tilde_in_config(self): # Config entries that are file paths can be tilde-expanded. @@ -296,11 +291,11 @@ class ConfigTest(CoverageTest): with mock.patch.object(coverage.config.os.path, 'expanduser', new=expanduser): cov = coverage.Coverage() - self.assertEqual(cov.config.data_file, "/Users/me/data.file") - self.assertEqual(cov.config.html_dir, "/Users/joe/html_dir") - self.assertEqual(cov.config.xml_output, "/Users/me/somewhere/xml.out") - self.assertEqual(cov.config.exclude_list, ["~/data.file", "~joe/html_dir"]) - self.assertEqual(cov.config.paths, {'mapping': ['/Users/me/src', '/Users/joe/source']}) + assert cov.config.data_file == "/Users/me/data.file" + assert cov.config.html_dir == "/Users/joe/html_dir" + assert cov.config.xml_output == "/Users/me/somewhere/xml.out" + assert cov.config.exclude_list == ["~/data.file", "~joe/html_dir"] + assert cov.config.paths == {'mapping': ['/Users/me/src', '/Users/joe/source']} def test_tilde_in_toml_config(self): # Config entries that are file paths can be tilde-expanded. @@ -329,23 +324,23 @@ class ConfigTest(CoverageTest): with mock.patch.object(coverage.config.os.path, 'expanduser', new=expanduser): cov = coverage.Coverage() - self.assertEqual(cov.config.data_file, "/Users/me/data.file") - self.assertEqual(cov.config.html_dir, "/Users/joe/html_dir") - self.assertEqual(cov.config.xml_output, "/Users/me/somewhere/xml.out") - self.assertEqual(cov.config.exclude_list, ["~/data.file", "~joe/html_dir"]) + assert cov.config.data_file == "/Users/me/data.file" + assert cov.config.html_dir == "/Users/joe/html_dir" + assert cov.config.xml_output == "/Users/me/somewhere/xml.out" + assert cov.config.exclude_list == ["~/data.file", "~joe/html_dir"] def test_tweaks_after_constructor(self): # set_option can be used after construction to affect the config. cov = coverage.Coverage(timid=True, data_file="fooey.dat") cov.set_option("run:timid", False) - self.assertFalse(cov.config.timid) - self.assertFalse(cov.config.branch) - self.assertEqual(cov.config.data_file, "fooey.dat") + assert not cov.config.timid + assert not cov.config.branch + assert cov.config.data_file == "fooey.dat" - self.assertFalse(cov.get_option("run:timid")) - self.assertFalse(cov.get_option("run:branch")) - self.assertEqual(cov.get_option("run:data_file"), "fooey.dat") + assert not cov.get_option("run:timid") + assert not cov.get_option("run:branch") + assert cov.get_option("run:data_file") == "fooey.dat" def test_tweaks_paths_after_constructor(self): self.make_file(".coveragerc", """\ @@ -363,24 +358,24 @@ class ConfigTest(CoverageTest): old_paths["second"] = ["/second/a", "/second/b"] cov = coverage.Coverage() paths = cov.get_option("paths") - self.assertEqual(paths, old_paths) + assert paths == old_paths new_paths = OrderedDict() new_paths['magic'] = ['src', 'ok'] cov.set_option("paths", new_paths) - self.assertEqual(cov.get_option("paths"), new_paths) + assert cov.get_option("paths") == new_paths def test_tweak_error_checking(self): # Trying to set an unknown config value raises an error. cov = coverage.Coverage() - with self.assertRaisesRegex(CoverageException, "No such option: 'run:xyzzy'"): + with pytest.raises(CoverageException, match="No such option: 'run:xyzzy'"): cov.set_option("run:xyzzy", 12) - with self.assertRaisesRegex(CoverageException, "No such option: 'xyzzy:foo'"): + with pytest.raises(CoverageException, match="No such option: 'xyzzy:foo'"): cov.set_option("xyzzy:foo", 12) - with self.assertRaisesRegex(CoverageException, "No such option: 'run:xyzzy'"): + with pytest.raises(CoverageException, match="No such option: 'run:xyzzy'"): _ = cov.get_option("run:xyzzy") - with self.assertRaisesRegex(CoverageException, "No such option: 'xyzzy:foo'"): + with pytest.raises(CoverageException, match="No such option: 'xyzzy:foo'"): _ = cov.get_option("xyzzy:foo") def test_tweak_plugin_options(self): @@ -389,12 +384,12 @@ class ConfigTest(CoverageTest): cov.set_option("run:plugins", ["fooey.plugin", "xyzzy.coverage.plugin"]) cov.set_option("fooey.plugin:xyzzy", 17) cov.set_option("xyzzy.coverage.plugin:plugh", ["a", "b"]) - with self.assertRaisesRegex(CoverageException, "No such option: 'no_such.plugin:foo'"): + with pytest.raises(CoverageException, match="No such option: 'no_such.plugin:foo'"): cov.set_option("no_such.plugin:foo", 23) - self.assertEqual(cov.get_option("fooey.plugin:xyzzy"), 17) - self.assertEqual(cov.get_option("xyzzy.coverage.plugin:plugh"), ["a", "b"]) - with self.assertRaisesRegex(CoverageException, "No such option: 'no_such.plugin:foo'"): + assert cov.get_option("fooey.plugin:xyzzy") == 17 + assert cov.get_option("xyzzy.coverage.plugin:plugh") == ["a", "b"] + with pytest.raises(CoverageException, match="No such option: 'no_such.plugin:foo'"): _ = cov.get_option("no_such.plugin:foo") def test_unknown_option(self): @@ -403,7 +398,7 @@ class ConfigTest(CoverageTest): xyzzy = 17 """) msg = r"Unrecognized option '\[run\] xyzzy=' in config file .coveragerc" - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): _ = coverage.Coverage() def test_unknown_option_toml(self): @@ -412,7 +407,7 @@ class ConfigTest(CoverageTest): xyzzy = 17 """) msg = r"Unrecognized option '\[tool.coverage.run\] xyzzy=' in config file pyproject.toml" - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): _ = coverage.Coverage() def test_misplaced_option(self): @@ -421,7 +416,7 @@ class ConfigTest(CoverageTest): branch = True """) msg = r"Unrecognized option '\[report\] branch=' in config file .coveragerc" - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): _ = coverage.Coverage() def test_unknown_option_in_other_ini_file(self): @@ -430,7 +425,7 @@ class ConfigTest(CoverageTest): huh = what? """) msg = (r"Unrecognized option '\[coverage:run\] huh=' in config file setup.cfg") - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): _ = coverage.Coverage() def test_note_is_obsolete(self): @@ -546,49 +541,49 @@ class ConfigFileTest(UsingModulesMixin, CoverageTest): def assert_config_settings_are_correct(self, cov): """Check that `cov` has all the settings from LOTSA_SETTINGS.""" - self.assertTrue(cov.config.timid) - self.assertEqual(cov.config.data_file, "something_or_other.dat") - self.assertTrue(cov.config.branch) - self.assertTrue(cov.config.cover_pylib) - self.assertEqual(cov.config.debug, ["callers", "pids", "dataio"]) - self.assertTrue(cov.config.parallel) - self.assertEqual(cov.config.concurrency, ["thread"]) - self.assertEqual(cov.config.source, ["myapp"]) - self.assertEqual(cov.config.source_pkgs, ["ned"]) - self.assertEqual(cov.config.disable_warnings, ["abcd", "efgh"]) - - self.assertEqual(cov.get_exclude_list(), ["if 0:", r"pragma:?\s+no cover", "another_tab"]) - self.assertTrue(cov.config.ignore_errors) - self.assertEqual(cov.config.run_omit, ["twenty"]) - self.assertEqual(cov.config.report_omit, ["one", "another", "some_more", "yet_more"]) - self.assertEqual(cov.config.report_include, ["thirty"]) - self.assertEqual(cov.config.precision, 3) - - self.assertEqual(cov.config.partial_list, [r"pragma:?\s+no branch"]) - self.assertEqual(cov.config.partial_always_list, ["if 0:", "while True:"]) - self.assertEqual(cov.config.plugins, ["plugins.a_plugin", "plugins.another"]) - self.assertTrue(cov.config.show_missing) - self.assertTrue(cov.config.skip_covered) - self.assertTrue(cov.config.skip_empty) - self.assertEqual(cov.config.html_dir, r"c:\tricky\dir.somewhere") - self.assertEqual(cov.config.extra_css, "something/extra.css") - self.assertEqual(cov.config.html_title, "Title & nums # nums!") - - self.assertEqual(cov.config.xml_output, "mycov.xml") - self.assertEqual(cov.config.xml_package_depth, 17) - - self.assertEqual(cov.config.paths, { + assert cov.config.timid + assert cov.config.data_file == "something_or_other.dat" + assert cov.config.branch + assert cov.config.cover_pylib + assert cov.config.debug == ["callers", "pids", "dataio"] + assert cov.config.parallel + assert cov.config.concurrency == ["thread"] + assert cov.config.source == ["myapp"] + assert cov.config.source_pkgs == ["ned"] + assert cov.config.disable_warnings == ["abcd", "efgh"] + + assert cov.get_exclude_list() == ["if 0:", r"pragma:?\s+no cover", "another_tab"] + assert cov.config.ignore_errors + assert cov.config.run_omit == ["twenty"] + assert cov.config.report_omit == ["one", "another", "some_more", "yet_more"] + assert cov.config.report_include == ["thirty"] + assert cov.config.precision == 3 + + assert cov.config.partial_list == [r"pragma:?\s+no branch"] + assert cov.config.partial_always_list == ["if 0:", "while True:"] + assert cov.config.plugins == ["plugins.a_plugin", "plugins.another"] + assert cov.config.show_missing + assert cov.config.skip_covered + assert cov.config.skip_empty + assert cov.config.html_dir == r"c:\tricky\dir.somewhere" + assert cov.config.extra_css == "something/extra.css" + assert cov.config.html_title == "Title & nums # nums!" + + assert cov.config.xml_output == "mycov.xml" + assert cov.config.xml_package_depth == 17 + + assert cov.config.paths == { 'source': ['.', '/home/ned/src/'], 'other': ['other', '/home/ned/other', 'c:\\Ned\\etc'] - }) + } - self.assertEqual(cov.config.get_plugin_options("plugins.a_plugin"), { + assert cov.config.get_plugin_options("plugins.a_plugin") == { 'hello': 'world', 'names': 'Jane/John/Jenny', - }) - self.assertEqual(cov.config.get_plugin_options("plugins.another"), {}) - self.assertEqual(cov.config.json_show_contexts, True) - self.assertEqual(cov.config.json_pretty_print, True) + } + assert cov.config.get_plugin_options("plugins.another") == {} + assert cov.config.json_show_contexts == True + assert cov.config.json_pretty_print == True def test_config_file_settings(self): self.make_file(".coveragerc", self.LOTSA_SETTINGS.format(section="")) @@ -633,9 +628,9 @@ class ConfigFileTest(UsingModulesMixin, CoverageTest): branch = true """) cov = coverage.Coverage() - self.assertEqual(cov.config.run_include, ["foo"]) - self.assertEqual(cov.config.run_omit, None) - self.assertEqual(cov.config.branch, False) + assert cov.config.run_include == ["foo"] + assert cov.config.run_omit == None + assert cov.config.branch == False def test_setupcfg_only_if_not_coveragerc(self): self.check_other_not_read_if_coveragerc("setup.cfg") @@ -651,8 +646,8 @@ class ConfigFileTest(UsingModulesMixin, CoverageTest): branch = true """) cov = coverage.Coverage() - self.assertEqual(cov.config.run_omit, None) - self.assertEqual(cov.config.branch, False) + assert cov.config.run_omit == None + assert cov.config.branch == False def test_setupcfg_only_if_prefixed(self): self.check_other_config_need_prefixes("setup.cfg") @@ -689,8 +684,8 @@ class ConfigFileTest(UsingModulesMixin, CoverageTest): self.set_environ("TOX_ENVNAME", "weirdo") cov = coverage.Coverage() - self.assertEqual(cov.config.exclude_list, ["first", "✘weirdo", "third"]) - self.assertEqual(cov.config.html_title, "tabblo & «ταБЬℓσ» # numbers") + assert cov.config.exclude_list == ["first", "✘weirdo", "third"] + assert cov.config.html_title == "tabblo & «ταБЬℓσ» # numbers" def test_unreadable_config(self): # If a config file is explicitly specified, then it is an error for it @@ -701,20 +696,20 @@ class ConfigFileTest(UsingModulesMixin, CoverageTest): ] for bad_file in bad_files: msg = "Couldn't read %r as a config file" % bad_file - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): coverage.Coverage(config_file=bad_file) def test_nocoveragerc_file_when_specified(self): cov = coverage.Coverage(config_file=".coveragerc") - self.assertFalse(cov.config.timid) - self.assertFalse(cov.config.branch) - self.assertEqual(cov.config.data_file, ".coverage") + assert not cov.config.timid + assert not cov.config.branch + assert cov.config.data_file == ".coverage" def test_no_toml_installed_no_toml(self): # Can't read a toml file that doesn't exist. with without_module(coverage.tomlconfig, 'toml'): msg = "Couldn't read 'cov.toml' as a config file" - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): coverage.Coverage(config_file="cov.toml") def test_no_toml_installed_explicit_toml(self): @@ -722,7 +717,7 @@ class ConfigFileTest(UsingModulesMixin, CoverageTest): self.make_file("cov.toml", "# A toml file!") with without_module(coverage.tomlconfig, 'toml'): msg = "Can't read 'cov.toml' without TOML support" - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): coverage.Coverage(config_file="cov.toml") def test_no_toml_installed_pyproject_toml(self): @@ -734,7 +729,7 @@ class ConfigFileTest(UsingModulesMixin, CoverageTest): """) with without_module(coverage.tomlconfig, 'toml'): msg = "Can't read 'pyproject.toml' without TOML support" - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): coverage.Coverage() def test_no_toml_installed_pyproject_no_coverage(self): @@ -747,6 +742,6 @@ class ConfigFileTest(UsingModulesMixin, CoverageTest): with without_module(coverage.tomlconfig, 'toml'): cov = coverage.Coverage() # We get default settings: - self.assertFalse(cov.config.timid) - self.assertFalse(cov.config.branch) - self.assertEqual(cov.config.data_file, ".coverage") + assert not cov.config.timid + assert not cov.config.branch + assert cov.config.data_file == ".coverage" diff --git a/tests/test_context.py b/tests/test_context.py index 137300a5..be478760 100644 --- a/tests/test_context.py +++ b/tests/test_context.py @@ -64,7 +64,7 @@ class StaticContextTest(CoverageTest): for data in datas: combined.update(data) - self.assertEqual(combined.measured_contexts(), {'red', 'blue'}) + assert combined.measured_contexts() == {'red', 'blue'} full_names = {os.path.basename(f): f for f in combined.measured_files()} self.assertCountEqual(full_names, ['red.py', 'blue.py']) @@ -75,7 +75,7 @@ class StaticContextTest(CoverageTest): def assert_combined_lines(filename, context, lines): # pylint: disable=cell-var-from-loop combined.set_query_context(context) - self.assertEqual(combined.lines(filename), lines) + assert combined.lines(filename) == lines assert_combined_lines(fred, 'red', self.LINES) assert_combined_lines(fred, 'blue', []) @@ -89,7 +89,7 @@ class StaticContextTest(CoverageTest): for data in datas: combined.update(data) - self.assertEqual(combined.measured_contexts(), {'red', 'blue'}) + assert combined.measured_contexts() == {'red', 'blue'} full_names = {os.path.basename(f): f for f in combined.measured_files()} self.assertCountEqual(full_names, ['red.py', 'blue.py']) @@ -100,7 +100,7 @@ class StaticContextTest(CoverageTest): def assert_combined_lines(filename, context, lines): # pylint: disable=cell-var-from-loop combined.set_query_context(context) - self.assertEqual(combined.lines(filename), lines) + assert combined.lines(filename) == lines assert_combined_lines(fred, 'red', self.LINES) assert_combined_lines(fred, 'blue', []) @@ -110,7 +110,7 @@ class StaticContextTest(CoverageTest): def assert_combined_arcs(filename, context, lines): # pylint: disable=cell-var-from-loop combined.set_query_context(context) - self.assertEqual(combined.arcs(filename), lines) + assert combined.arcs(filename) == lines assert_combined_arcs(fred, 'red', self.ARCS) assert_combined_arcs(fred, 'blue', []) @@ -251,40 +251,38 @@ class QualnameTest(CoverageTest): run_in_temp_dir = False def test_method(self): - self.assertEqual(Parent().meth(), "tests.test_context.Parent.meth") + assert Parent().meth() == "tests.test_context.Parent.meth" def test_inherited_method(self): - self.assertEqual(Child().meth(), "tests.test_context.Parent.meth") + assert Child().meth() == "tests.test_context.Parent.meth" def test_mi_inherited_method(self): - self.assertEqual(MultiChild().meth(), "tests.test_context.Parent.meth") + assert MultiChild().meth() == "tests.test_context.Parent.meth" def test_no_arguments(self): - self.assertEqual(no_arguments(), "tests.test_context.no_arguments") + assert no_arguments() == "tests.test_context.no_arguments" def test_plain_old_function(self): - self.assertEqual( - plain_old_function(0, 1), "tests.test_context.plain_old_function") + assert plain_old_function(0, 1) == "tests.test_context.plain_old_function" def test_fake_out(self): - self.assertEqual(fake_out(0), "tests.test_context.fake_out") + assert fake_out(0) == "tests.test_context.fake_out" def test_property(self): - self.assertEqual( - Parent().a_property, "tests.test_context.Parent.a_property") + assert Parent().a_property == "tests.test_context.Parent.a_property" def test_changeling(self): c = Child() c.meth = patch_meth - self.assertEqual(c.meth(c), "tests.test_context.patch_meth") + assert c.meth(c) == "tests.test_context.patch_meth" def test_oldstyle(self): if not env.PY2: self.skipTest("Old-style classes are only in Python 2") - self.assertEqual(OldStyle().meth(), "tests.test_context.OldStyle.meth") - self.assertEqual(OldChild().meth(), "tests.test_context.OldStyle.meth") + assert OldStyle().meth() == "tests.test_context.OldStyle.meth" + assert OldChild().meth() == "tests.test_context.OldStyle.meth" def test_bug_829(self): # A class with a name like a function shouldn't confuse qualname_from_frame. class test_something(object): # pylint: disable=unused-variable - self.assertEqual(get_qualname(), None) + assert get_qualname() == None diff --git a/tests/test_coverage.py b/tests/test_coverage.py index 68eea115..6529aa72 100644 --- a/tests/test_coverage.py +++ b/tests/test_coverage.py @@ -9,6 +9,7 @@ from coverage import env from coverage.misc import CoverageException from tests.coveragetest import CoverageTest +import pytest class TestCoverageTest(CoverageTest): @@ -50,7 +51,7 @@ class TestCoverageTest(CoverageTest): def test_failed_coverage(self): # If the lines are wrong, the message shows right and wrong. - with self.assertRaisesRegex(AssertionError, r"\[1, 2] != \[1]"): + with pytest.raises(AssertionError, match=r"\[1, 2] != \[1]"): self.check_coverage("""\ a = 1 b = 2 @@ -59,7 +60,7 @@ class TestCoverageTest(CoverageTest): ) # If the list of lines possibilities is wrong, the msg shows right. msg = r"None of the lines choices matched \[1, 2]" - with self.assertRaisesRegex(AssertionError, msg): + with pytest.raises(AssertionError, match=msg): self.check_coverage("""\ a = 1 b = 2 @@ -67,7 +68,7 @@ class TestCoverageTest(CoverageTest): ([1], [2]) ) # If the missing lines are wrong, the message shows right and wrong. - with self.assertRaisesRegex(AssertionError, r"'3' != '37'"): + with pytest.raises(AssertionError, match=r"'3' != '37'"): self.check_coverage("""\ a = 1 if a == 2: @@ -78,7 +79,7 @@ class TestCoverageTest(CoverageTest): ) # If the missing lines possibilities are wrong, the msg shows right. msg = r"None of the missing choices matched '3'" - with self.assertRaisesRegex(AssertionError, msg): + with pytest.raises(AssertionError, match=msg): self.check_coverage("""\ a = 1 if a == 2: @@ -90,14 +91,14 @@ class TestCoverageTest(CoverageTest): def test_exceptions_really_fail(self): # An assert in the checked code will really raise up to us. - with self.assertRaisesRegex(AssertionError, "This is bad"): + with pytest.raises(AssertionError, match="This is bad"): self.check_coverage("""\ a = 1 assert a == 99, "This is bad" """ ) # Other exceptions too. - with self.assertRaisesRegex(ZeroDivisionError, "division"): + with pytest.raises(ZeroDivisionError, match="division"): self.check_coverage("""\ a = 1 assert a == 1, "This is good" @@ -1844,7 +1845,7 @@ class ModuleTest(CoverageTest): coverage.Coverage() def test_old_name_and_new_name(self): - self.assertIs(coverage.coverage, coverage.Coverage) + assert coverage.coverage is coverage.Coverage class ReportingTest(CoverageTest): @@ -1857,19 +1858,19 @@ class ReportingTest(CoverageTest): def test_no_data_to_report_on_annotate(self): # Reporting with no data produces a nice message and no output # directory. - with self.assertRaisesRegex(CoverageException, "No data to report."): + with pytest.raises(CoverageException, match="No data to report."): self.command_line("annotate -d ann") self.assert_doesnt_exist("ann") def test_no_data_to_report_on_html(self): # Reporting with no data produces a nice message and no output # directory. - with self.assertRaisesRegex(CoverageException, "No data to report."): + with pytest.raises(CoverageException, match="No data to report."): self.command_line("html -d htmlcov") self.assert_doesnt_exist("htmlcov") def test_no_data_to_report_on_xml(self): # Reporting with no data produces a nice message. - with self.assertRaisesRegex(CoverageException, "No data to report."): + with pytest.raises(CoverageException, match="No data to report."): self.command_line("xml") self.assert_doesnt_exist("coverage.xml") diff --git a/tests/test_data.py b/tests/test_data.py index b3ac718e..d1ed04e1 100644 --- a/tests/test_data.py +++ b/tests/test_data.py @@ -19,6 +19,7 @@ from coverage.files import PathAliases, canonical_filename from coverage.misc import CoverageException from tests.coveragetest import CoverageTest +import pytest LINES_1 = { @@ -77,7 +78,7 @@ class DataTestHelpers(CoverageTest): def assert_line_counts(self, covdata, counts, fullpath=False): """Check that the line_counts of `covdata` is `counts`.""" - self.assertEqual(line_counts(covdata, fullpath), counts) + assert line_counts(covdata, fullpath) == counts def assert_measured_files(self, covdata, measured): """Check that `covdata`'s measured files are `measured`.""" @@ -88,7 +89,7 @@ class DataTestHelpers(CoverageTest): self.assert_line_counts(covdata, SUMMARY_1) self.assert_measured_files(covdata, MEASURED_FILES_1) self.assertCountEqual(covdata.lines("a.py"), A_PY_LINES_1) - self.assertFalse(covdata.has_arcs()) + assert not covdata.has_arcs() def assert_arcs3_data(self, covdata): """Check that `covdata` has the data from ARCS3.""" @@ -98,7 +99,7 @@ class DataTestHelpers(CoverageTest): self.assertCountEqual(covdata.arcs("x.py"), X_PY_ARCS_3) self.assertCountEqual(covdata.lines("y.py"), Y_PY_LINES_3) self.assertCountEqual(covdata.arcs("y.py"), Y_PY_ARCS_3) - self.assertTrue(covdata.has_arcs()) + assert covdata.has_arcs() class CoverageDataTest(DataTestHelpers, CoverageTest): @@ -108,27 +109,27 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): def test_empty_data_is_false(self): covdata = CoverageData() - self.assertFalse(covdata) + assert not covdata def test_line_data_is_true(self): covdata = CoverageData() covdata.add_lines(LINES_1) - self.assertTrue(covdata) + assert covdata def test_arc_data_is_true(self): covdata = CoverageData() covdata.add_arcs(ARCS_3) - self.assertTrue(covdata) + assert covdata def test_empty_line_data_is_false(self): covdata = CoverageData() covdata.add_lines({}) - self.assertFalse(covdata) + assert not covdata def test_empty_arc_data_is_false(self): covdata = CoverageData() covdata.add_arcs({}) - self.assertFalse(covdata) + assert not covdata def test_adding_lines(self): covdata = CoverageData() @@ -157,13 +158,13 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): def test_cant_add_arcs_with_lines(self): covdata = CoverageData() covdata.add_lines(LINES_1) - with self.assertRaisesRegex(CoverageException, "Can't add arcs to existing line data"): + with pytest.raises(CoverageException, match="Can't add arcs to existing line data"): covdata.add_arcs(ARCS_3) def test_cant_add_lines_with_arcs(self): covdata = CoverageData() covdata.add_arcs(ARCS_3) - with self.assertRaisesRegex(CoverageException, "Can't add lines to existing arc data"): + with pytest.raises(CoverageException, match="Can't add lines to existing arc data"): covdata.add_lines(LINES_1) def test_touch_file_with_lines(self): @@ -183,34 +184,33 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): covdata.set_context('test_a') covdata.add_lines(LINES_1) covdata.set_query_contexts(['test_*']) - self.assertEqual(covdata.lines('a.py'), [1, 2]) + assert covdata.lines('a.py') == [1, 2] covdata.set_query_contexts(['other*']) - self.assertEqual(covdata.lines('a.py'), []) + assert covdata.lines('a.py') == [] def test_no_lines_vs_unmeasured_file(self): covdata = CoverageData() covdata.add_lines(LINES_1) covdata.touch_file('zzz.py') - self.assertEqual(covdata.lines('zzz.py'), []) - self.assertIsNone(covdata.lines('no_such_file.py')) + assert covdata.lines('zzz.py') == [] + assert covdata.lines('no_such_file.py') is None def test_lines_with_contexts(self): covdata = CoverageData() covdata.set_context('test_a') covdata.add_lines(LINES_1) - self.assertEqual(covdata.lines('a.py'), [1, 2]) + assert covdata.lines('a.py') == [1, 2] covdata.set_query_contexts(['test*']) - self.assertEqual(covdata.lines('a.py'), [1, 2]) + assert covdata.lines('a.py') == [1, 2] covdata.set_query_contexts(['other*']) - self.assertEqual(covdata.lines('a.py'), []) + assert covdata.lines('a.py') == [] def test_contexts_by_lineno_with_lines(self): covdata = CoverageData() covdata.set_context('test_a') covdata.add_lines(LINES_1) - self.assertDictEqual( - covdata.contexts_by_lineno('a.py'), - {1: ['test_a'], 2: ['test_a']}) + assert covdata.contexts_by_lineno('a.py') == \ + {1: ['test_a'], 2: ['test_a']} def test_no_duplicate_lines(self): covdata = CoverageData() @@ -218,7 +218,7 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): covdata.add_lines(LINES_1) covdata.set_context("context2") covdata.add_lines(LINES_1) - self.assertEqual(covdata.lines('a.py'), A_PY_LINES_1) + assert covdata.lines('a.py') == A_PY_LINES_1 def test_no_duplicate_arcs(self): covdata = CoverageData() @@ -226,39 +226,37 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): covdata.add_arcs(ARCS_3) covdata.set_context("context2") covdata.add_arcs(ARCS_3) - self.assertEqual(covdata.arcs('x.py'), X_PY_ARCS_3) + assert covdata.arcs('x.py') == X_PY_ARCS_3 def test_no_arcs_vs_unmeasured_file(self): covdata = CoverageData() covdata.add_arcs(ARCS_3) covdata.touch_file('zzz.py') - self.assertEqual(covdata.lines('zzz.py'), []) - self.assertIsNone(covdata.lines('no_such_file.py')) - self.assertEqual(covdata.arcs('zzz.py'), []) - self.assertIsNone(covdata.arcs('no_such_file.py')) + assert covdata.lines('zzz.py') == [] + assert covdata.lines('no_such_file.py') is None + assert covdata.arcs('zzz.py') == [] + assert covdata.arcs('no_such_file.py') is None def test_arcs_with_contexts(self): covdata = CoverageData() covdata.set_context('test_x') covdata.add_arcs(ARCS_3) - self.assertEqual(covdata.arcs('x.py'), [(-1, 1), (1, 2), (2, 3), (3, -1)]) + assert covdata.arcs('x.py') == [(-1, 1), (1, 2), (2, 3), (3, -1)] covdata.set_query_contexts(['test*']) - self.assertEqual(covdata.arcs('x.py'), [(-1, 1), (1, 2), (2, 3), (3, -1)]) + assert covdata.arcs('x.py') == [(-1, 1), (1, 2), (2, 3), (3, -1)] covdata.set_query_contexts(['other*']) - self.assertEqual(covdata.arcs('x.py'), []) + assert covdata.arcs('x.py') == [] def test_contexts_by_lineno_with_arcs(self): covdata = CoverageData() covdata.set_context('test_x') covdata.add_arcs(ARCS_3) - self.assertDictEqual( - covdata.contexts_by_lineno('x.py'), - {-1: ['test_x'], 1: ['test_x'], 2: ['test_x'], 3: ['test_x']}) + assert covdata.contexts_by_lineno('x.py') == \ + {-1: ['test_x'], 1: ['test_x'], 2: ['test_x'], 3: ['test_x']} def test_contexts_by_lineno_with_unknown_file(self): covdata = CoverageData() - self.assertDictEqual( - covdata.contexts_by_lineno('xyz.py'), {}) + assert covdata.contexts_by_lineno('xyz.py') == {} def test_file_tracer_name(self): covdata = CoverageData() @@ -268,18 +266,18 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): "main.py": dict.fromkeys([20]), }) covdata.add_file_tracers({"p1.foo": "p1.plugin", "p2.html": "p2.plugin"}) - self.assertEqual(covdata.file_tracer("p1.foo"), "p1.plugin") - self.assertEqual(covdata.file_tracer("main.py"), "") - self.assertIsNone(covdata.file_tracer("p3.not_here")) + assert covdata.file_tracer("p1.foo") == "p1.plugin" + assert covdata.file_tracer("main.py") == "" + assert covdata.file_tracer("p3.not_here") is None def test_cant_file_tracer_unmeasured_files(self): covdata = CoverageData() msg = "Can't add file tracer data for unmeasured file 'p1.foo'" - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): covdata.add_file_tracers({"p1.foo": "p1.plugin"}) covdata.add_lines({"p2.html": dict.fromkeys([10, 11, 12])}) - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): covdata.add_file_tracers({"p1.foo": "p1.plugin"}) def test_cant_change_file_tracer_name(self): @@ -288,7 +286,7 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): covdata.add_file_tracers({"p1.foo": "p1.plugin"}) msg = "Conflicting file tracer name for 'p1.foo': u?'p1.plugin' vs u?'p1.plugin.foo'" - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): covdata.add_file_tracers({"p1.foo": "p1.plugin.foo"}) def test_update_lines(self): @@ -326,10 +324,10 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): covdata2 = CoverageData(suffix='2') covdata2.add_arcs(ARCS_3) - with self.assertRaisesRegex(CoverageException, "Can't combine arc data with line data"): + with pytest.raises(CoverageException, match="Can't combine arc data with line data"): covdata1.update(covdata2) - with self.assertRaisesRegex(CoverageException, "Can't combine line data with arc data"): + with pytest.raises(CoverageException, match="Can't combine line data with arc data"): covdata2.update(covdata1) def test_update_file_tracers(self): @@ -360,10 +358,10 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): covdata3 = CoverageData(suffix='3') covdata3.update(covdata1) covdata3.update(covdata2) - self.assertEqual(covdata3.file_tracer("p1.html"), "html.plugin") - self.assertEqual(covdata3.file_tracer("p2.html"), "html.plugin2") - self.assertEqual(covdata3.file_tracer("p3.foo"), "foo_plugin") - self.assertEqual(covdata3.file_tracer("main.py"), "") + assert covdata3.file_tracer("p1.html") == "html.plugin" + assert covdata3.file_tracer("p2.html") == "html.plugin2" + assert covdata3.file_tracer("p3.foo") == "foo_plugin" + assert covdata3.file_tracer("main.py") == "" def test_update_conflicting_file_tracers(self): covdata1 = CoverageData(suffix='1') @@ -375,11 +373,11 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): covdata2.add_file_tracers({"p1.html": "html.other_plugin"}) msg = "Conflicting file tracer name for 'p1.html': u?'html.plugin' vs u?'html.other_plugin'" - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): covdata1.update(covdata2) msg = "Conflicting file tracer name for 'p1.html': u?'html.other_plugin' vs u?'html.plugin'" - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): covdata2.update(covdata1) def test_update_file_tracer_vs_no_file_tracer(self): @@ -391,11 +389,11 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): covdata2.add_lines({"p1.html": dict.fromkeys([1, 2, 3])}) msg = "Conflicting file tracer name for 'p1.html': u?'html.plugin' vs u?''" - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): covdata1.update(covdata2) msg = "Conflicting file tracer name for 'p1.html': u?'' vs u?'html.plugin'" - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): covdata2.update(covdata1) def test_update_lines_empty(self): @@ -418,7 +416,7 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): # Asking about an unmeasured file shouldn't make it seem measured. covdata = CoverageData() self.assert_measured_files(covdata, []) - self.assertEqual(covdata.arcs("missing.py"), None) + assert covdata.arcs("missing.py") == None self.assert_measured_files(covdata, []) def test_add_to_hash_with_lines(self): @@ -426,10 +424,10 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): covdata.add_lines(LINES_1) hasher = mock.Mock() add_data_to_hash(covdata, "a.py", hasher) - self.assertEqual(hasher.method_calls, [ + assert hasher.method_calls == [ mock.call.update([1, 2]), # lines mock.call.update(""), # file_tracer name - ]) + ] def test_add_to_hash_with_arcs(self): covdata = CoverageData() @@ -437,10 +435,10 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): covdata.add_file_tracers({"y.py": "hologram_plugin"}) hasher = mock.Mock() add_data_to_hash(covdata, "y.py", hasher) - self.assertEqual(hasher.method_calls, [ + assert hasher.method_calls == [ mock.call.update([(-1, 17), (17, 23), (23, -1)]), # arcs mock.call.update("hologram_plugin"), # file_tracer name - ]) + ] def test_add_to_lines_hash_with_missing_file(self): # https://github.com/nedbat/coveragepy/issues/403 @@ -448,10 +446,10 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): covdata.add_lines(LINES_1) hasher = mock.Mock() add_data_to_hash(covdata, "missing.py", hasher) - self.assertEqual(hasher.method_calls, [ + assert hasher.method_calls == [ mock.call.update([]), mock.call.update(None), - ]) + ] def test_add_to_arcs_hash_with_missing_file(self): # https://github.com/nedbat/coveragepy/issues/403 @@ -460,22 +458,22 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): covdata.add_file_tracers({"y.py": "hologram_plugin"}) hasher = mock.Mock() add_data_to_hash(covdata, "missing.py", hasher) - self.assertEqual(hasher.method_calls, [ + assert hasher.method_calls == [ mock.call.update([]), mock.call.update(None), - ]) + ] def test_empty_lines_are_still_lines(self): covdata = CoverageData() covdata.add_lines({}) covdata.touch_file("abc.py") - self.assertFalse(covdata.has_arcs()) + assert not covdata.has_arcs() def test_empty_arcs_are_still_arcs(self): covdata = CoverageData() covdata.add_arcs({}) covdata.touch_file("abc.py") - self.assertTrue(covdata.has_arcs()) + assert covdata.has_arcs() def test_read_and_write_are_opposites(self): covdata1 = CoverageData() @@ -527,34 +525,34 @@ class CoverageDataTestInTempDir(DataTestHelpers, CoverageTest): msg = r"Couldn't .* '.*[/\\]{0}': \S+" self.make_file("xyzzy.dat", "xyzzy") - with self.assertRaisesRegex(CoverageException, msg.format("xyzzy.dat")): + with pytest.raises(CoverageException, match=msg.format("xyzzy.dat")): covdata = CoverageData("xyzzy.dat") covdata.read() - self.assertFalse(covdata) + assert not covdata self.make_file("empty.dat", "") - with self.assertRaisesRegex(CoverageException, msg.format("empty.dat")): + with pytest.raises(CoverageException, match=msg.format("empty.dat")): covdata = CoverageData("empty.dat") covdata.read() - self.assertFalse(covdata) + assert not covdata def test_read_sql_errors(self): with sqlite3.connect("wrong_schema.db") as con: con.execute("create table coverage_schema (version integer)") con.execute("insert into coverage_schema (version) values (99)") msg = r"Couldn't .* '.*[/\\]{}': wrong schema: 99 instead of \d+".format("wrong_schema.db") - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): covdata = CoverageData("wrong_schema.db") covdata.read() - self.assertFalse(covdata) + assert not covdata with sqlite3.connect("no_schema.db") as con: con.execute("create table foobar (baz text)") msg = r"Couldn't .* '.*[/\\]{}': \S+".format("no_schema.db") - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): covdata = CoverageData("no_schema.db") covdata.read() - self.assertFalse(covdata) + assert not covdata class CoverageDataFilesTest(DataTestHelpers, CoverageTest): @@ -589,12 +587,9 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest): covdata2.read() self.assert_line_counts(covdata2, SUMMARY_1) - self.assertRegex( - debug.get_output(), - r"^Erasing data file '.*\.coverage'\n" - r"Creating data file '.*\.coverage'\n" - r"Opening data file '.*\.coverage'\n$" - ) + assert re.search(r"^Erasing data file '.*\.coverage'\n" \ + r"Creating data file '.*\.coverage'\n" \ + r"Opening data file '.*\.coverage'\n$", debug.get_output()) def test_debug_output_without_debug_option(self): # With a debug object, but not the dataio option, we don't get debug @@ -608,7 +603,7 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest): covdata2.read() self.assert_line_counts(covdata2, SUMMARY_1) - self.assertEqual(debug.get_output(), "") + assert debug.get_output() == "" def test_explicit_suffix(self): self.assert_doesnt_exist(".coverage.SUFFIX") @@ -627,7 +622,7 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest): covdata1.write() self.assert_doesnt_exist(".coverage") data_files1 = glob.glob(".coverage.*") - self.assertEqual(len(data_files1), 1) + assert len(data_files1) == 1 # Another suffix=True will choose a different name. covdata2 = CoverageData(suffix=True) @@ -635,10 +630,10 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest): covdata2.write() self.assert_doesnt_exist(".coverage") data_files2 = glob.glob(".coverage.*") - self.assertEqual(len(data_files2), 2) + assert len(data_files2) == 2 # In addition to being different, the suffixes have the pid in them. - self.assertTrue(all(str(os.getpid()) in fn for fn in data_files2)) + assert all(str(os.getpid()) in fn for fn in data_files2) def test_combining(self): self.assert_file_count(".coverage.*", 0) @@ -718,7 +713,7 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest): self.assert_line_counts(covdata3, {apy: 4, sub_bpy: 2, template_html: 1}, fullpath=True) self.assert_measured_files(covdata3, [apy, sub_bpy, template_html]) - self.assertEqual(covdata3.file_tracer(template_html), 'html.plugin') + assert covdata3.file_tracer(template_html) == 'html.plugin' def test_combining_from_different_directories(self): os.makedirs('cov1') @@ -778,7 +773,7 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest): def test_combining_from_nonexistent_directories(self): covdata = CoverageData() msg = "Couldn't combine from non-existent path 'xyzzy'" - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): combine_parallel_data(covdata, data_paths=['xyzzy']) def test_interleaved_erasing_bug716(self): @@ -817,5 +812,5 @@ class DumpsLoadsTest(DataTestHelpers, CoverageTest): re.escape(repr(bad_data[:40])), len(bad_data), ) - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): covdata.loads(bad_data) diff --git a/tests/test_debug.py b/tests/test_debug.py index 228e33b0..629665f9 100644 --- a/tests/test_debug.py +++ b/tests/test_debug.py @@ -15,6 +15,7 @@ from coverage.env import C_TRACER from tests.coveragetest import CoverageTest from tests.helpers import re_line, re_lines +import re class InfoFormatterTest(CoverageTest): @@ -38,7 +39,7 @@ class InfoFormatterTest(CoverageTest): ' jkl', ' nothing: -none-', ] - self.assertEqual(expected, lines) + assert expected == lines def test_info_formatter_with_generator(self): lines = list(info_formatter(('info%d' % i, i) for i in range(3))) @@ -47,10 +48,10 @@ class InfoFormatterTest(CoverageTest): ' info1: 1', ' info2: 2', ] - self.assertEqual(expected, lines) + assert expected == lines def test_too_long_label(self): - with self.assertRaises(AssertionError): + with pytest.raises(AssertionError): list(info_formatter([('this label is way too long and will not fit', 23)])) @@ -118,20 +119,20 @@ class DebugTraceTest(CoverageTest): out_lines = self.f1_debug_output([]) # We should have no output at all. - self.assertFalse(out_lines) + assert not out_lines def test_debug_trace(self): out_lines = self.f1_debug_output(["trace"]) # We should have a line like "Tracing 'f1.py'" - self.assertIn("Tracing 'f1.py'", out_lines) + assert "Tracing 'f1.py'" in out_lines # We should have lines like "Not tracing 'collector.py'..." coverage_lines = re_lines( out_lines, r"^Not tracing .*: is part of coverage.py$" ) - self.assertTrue(coverage_lines) + assert coverage_lines def test_debug_trace_pid(self): out_lines = self.f1_debug_output(["trace", "pid"]) @@ -139,11 +140,11 @@ class DebugTraceTest(CoverageTest): # Now our lines are always prefixed with the process id. pid_prefix = r"^%5d\.[0-9a-f]{4}: " % os.getpid() pid_lines = re_lines(out_lines, pid_prefix) - self.assertEqual(pid_lines, out_lines) + assert pid_lines == out_lines # We still have some tracing, and some not tracing. - self.assertTrue(re_lines(out_lines, pid_prefix + "Tracing ")) - self.assertTrue(re_lines(out_lines, pid_prefix + "Not tracing ")) + assert re_lines(out_lines, pid_prefix + "Tracing ") + assert re_lines(out_lines, pid_prefix + "Not tracing ") def test_debug_callers(self): out_lines = self.f1_debug_output(["pid", "dataop", "dataio", "callers"]) @@ -153,15 +154,15 @@ class DebugTraceTest(CoverageTest): real_messages = re_lines(out_lines, r":\d+", match=False).splitlines() frame_pattern = r"\s+f1_debug_output : .*tests[/\\]test_debug.py:\d+$" frames = re_lines(out_lines, frame_pattern).splitlines() - self.assertEqual(len(real_messages), len(frames)) + assert len(real_messages) == len(frames) last_line = out_lines.splitlines()[-1] # The details of what to expect on the stack are empirical, and can change # as the code changes. This test is here to ensure that the debug code # continues working. It's ok to adjust these details over time. - self.assertRegex(real_messages[-1], r"^\s*\d+\.\w{4}: Adding file tracers: 0 files") - self.assertRegex(last_line, r"\s+add_file_tracers : .*coverage[/\\]sqldata.py:\d+$") + assert re.search(r"^\s*\d+\.\w{4}: Adding file tracers: 0 files", real_messages[-1]) + assert re.search(r"\s+add_file_tracers : .*coverage[/\\]sqldata.py:\d+$", last_line) def test_debug_config(self): out_lines = self.f1_debug_output(["config"]) @@ -175,11 +176,9 @@ class DebugTraceTest(CoverageTest): """.split() for label in labels: label_pat = r"^\s*%s: " % label - self.assertEqual( - len(re_lines(out_lines, label_pat).splitlines()), - 1, - msg="Incorrect lines for %r" % label, - ) + assert len(re_lines(out_lines, label_pat).splitlines()) == \ + 1, \ + "Incorrect lines for %r" % label def test_debug_sys(self): out_lines = self.f1_debug_output(["sys"]) @@ -191,11 +190,9 @@ class DebugTraceTest(CoverageTest): """.split() for label in labels: label_pat = r"^\s*%s: " % label - self.assertEqual( - len(re_lines(out_lines, label_pat).splitlines()), - 1, - msg="Incorrect lines for %r" % label, - ) + assert len(re_lines(out_lines, label_pat).splitlines()) == \ + 1, \ + "Incorrect lines for %r" % label def test_debug_sys_ctracer(self): out_lines = self.f1_debug_output(["sys"]) @@ -204,7 +201,7 @@ class DebugTraceTest(CoverageTest): expected = "CTracer: available" else: expected = "CTracer: unavailable" - self.assertEqual(expected, tracer_line) + assert expected == tracer_line def f_one(*args, **kwargs): @@ -227,15 +224,15 @@ class ShortStackTest(CoverageTest): def test_short_stack(self): stack = f_one().splitlines() - self.assertGreater(len(stack), 10) - self.assertIn("f_three", stack[-1]) - self.assertIn("f_two", stack[-2]) - self.assertIn("f_one", stack[-3]) + assert len(stack) > 10 + assert "f_three" in stack[-1] + assert "f_two" in stack[-2] + assert "f_one" in stack[-3] def test_short_stack_limit(self): stack = f_one(limit=5).splitlines() - self.assertEqual(len(stack), 5) + assert len(stack) == 5 def test_short_stack_skip(self): stack = f_one(skip=1).splitlines() - self.assertIn("f_two", stack[-1]) + assert "f_two" in stack[-1] diff --git a/tests/test_execfile.py b/tests/test_execfile.py index 5a718aae..b740d2df 100644 --- a/tests/test_execfile.py +++ b/tests/test_execfile.py @@ -18,6 +18,7 @@ from coverage.files import python_reported_file from coverage.misc import NoCode, NoSource from tests.coveragetest import CoverageTest, TESTS_DIR, UsingModulesMixin +import pytest TRY_EXECFILE = os.path.join(TESTS_DIR, "modules/process_test/try_execfile.py") @@ -30,27 +31,27 @@ class RunFileTest(CoverageTest): mod_globs = json.loads(self.stdout()) # The file should think it is __main__ - self.assertEqual(mod_globs['__name__'], "__main__") + assert mod_globs['__name__'] == "__main__" # It should seem to come from a file named try_execfile.py dunder_file = os.path.basename(mod_globs['__file__']) - self.assertEqual(dunder_file, "try_execfile.py") + assert dunder_file == "try_execfile.py" # It should have its correct module data. - self.assertEqual(mod_globs['__doc__'].splitlines()[0], - "Test file for run_python_file.") - self.assertEqual(mod_globs['DATA'], "xyzzy") - self.assertEqual(mod_globs['FN_VAL'], "my_fn('fooey')") + assert mod_globs['__doc__'].splitlines()[0] == \ + "Test file for run_python_file." + assert mod_globs['DATA'] == "xyzzy" + assert mod_globs['FN_VAL'] == "my_fn('fooey')" # It must be self-importable as __main__. - self.assertEqual(mod_globs['__main__.DATA'], "xyzzy") + assert mod_globs['__main__.DATA'] == "xyzzy" # Argv should have the proper values. - self.assertEqual(mod_globs['argv0'], TRY_EXECFILE) - self.assertEqual(mod_globs['argv1-n'], ["arg1", "arg2"]) + assert mod_globs['argv0'] == TRY_EXECFILE + assert mod_globs['argv1-n'] == ["arg1", "arg2"] # __builtins__ should have the right values, like open(). - self.assertEqual(mod_globs['__builtins__.has_open'], True) + assert mod_globs['__builtins__.has_open'] == True def test_no_extra_file(self): # Make sure that running a file doesn't create an extra compiled file. @@ -58,9 +59,9 @@ class RunFileTest(CoverageTest): desc = "a non-.py file!" """) - self.assertEqual(os.listdir("."), ["xxx"]) + assert os.listdir(".") == ["xxx"] run_python_file(["xxx"]) - self.assertEqual(os.listdir("."), ["xxx"]) + assert os.listdir(".") == ["xxx"] def test_universal_newlines(self): # Make sure we can read any sort of line ending. @@ -69,7 +70,7 @@ class RunFileTest(CoverageTest): with open('nl.py', 'wb') as fpy: fpy.write(nl.join(pylines).encode('utf-8')) run_python_file(['nl.py']) - self.assertEqual(self.stdout(), "Hello, world!\n"*3) + assert self.stdout() == "Hello, world!\n"*3 def test_missing_final_newline(self): # Make sure we can deal with a Python file with no final newline. @@ -80,14 +81,14 @@ class RunFileTest(CoverageTest): #""") with open("abrupt.py") as f: abrupt = f.read() - self.assertEqual(abrupt[-1], '#') + assert abrupt[-1] == '#' run_python_file(["abrupt.py"]) - self.assertEqual(self.stdout(), "a is 1\n") + assert self.stdout() == "a is 1\n" def test_no_such_file(self): path = python_reported_file('xyzzy.py') msg = re.escape("No file to run: '{}'".format(path)) - with self.assertRaisesRegex(NoSource, msg): + with pytest.raises(NoSource, match=msg): run_python_file(["xyzzy.py"]) def test_directory_with_main(self): @@ -95,11 +96,11 @@ class RunFileTest(CoverageTest): print("I am __main__") """) run_python_file(["with_main"]) - self.assertEqual(self.stdout(), "I am __main__\n") + assert self.stdout() == "I am __main__\n" def test_directory_without_main(self): self.make_file("without_main/__init__.py", "") - with self.assertRaisesRegex(NoSource, "Can't find '__main__' module in 'without_main'"): + with pytest.raises(NoSource, match="Can't find '__main__' module in 'without_main'"): run_python_file(["without_main"]) @@ -134,15 +135,15 @@ class RunPycFileTest(CoverageTest): def test_running_pyc(self): pycfile = self.make_pyc() run_python_file([pycfile]) - self.assertEqual(self.stdout(), "I am here!\n") + assert self.stdout() == "I am here!\n" def test_running_pyo(self): pycfile = self.make_pyc() pyofile = re.sub(r"[.]pyc$", ".pyo", pycfile) - self.assertNotEqual(pycfile, pyofile) + assert pycfile != pyofile os.rename(pycfile, pyofile) run_python_file([pyofile]) - self.assertEqual(self.stdout(), "I am here!\n") + assert self.stdout() == "I am here!\n" def test_running_pyc_from_wrong_python(self): pycfile = self.make_pyc() @@ -152,7 +153,7 @@ class RunPycFileTest(CoverageTest): fpyc.seek(0) fpyc.write(binary_bytes([0x2a, 0xeb, 0x0d, 0x0a])) - with self.assertRaisesRegex(NoCode, "Bad magic number in .pyc file"): + with pytest.raises(NoCode, match="Bad magic number in .pyc file"): run_python_file([pycfile]) # In some environments, the pycfile persists and pollutes another test. @@ -161,7 +162,7 @@ class RunPycFileTest(CoverageTest): def test_no_such_pyc_file(self): path = python_reported_file('xyzzy.pyc') msg = re.escape("No file to run: '{}'".format(path)) - with self.assertRaisesRegex(NoCode, msg): + with pytest.raises(NoCode, match=msg): run_python_file(["xyzzy.pyc"]) def test_running_py_from_binary(self): @@ -181,7 +182,7 @@ class RunPycFileTest(CoverageTest): r"source code string cannot contain null bytes" # for py3 r")" ) - with self.assertRaisesRegex(Exception, msg): + with pytest.raises(Exception, match=msg): run_python_file([bf]) @@ -192,42 +193,42 @@ class RunModuleTest(UsingModulesMixin, CoverageTest): def test_runmod1(self): run_python_module(["runmod1", "hello"]) - self.assertEqual(self.stderr(), "") - self.assertEqual(self.stdout(), "runmod1: passed hello\n") + assert self.stderr() == "" + assert self.stdout() == "runmod1: passed hello\n" def test_runmod2(self): run_python_module(["pkg1.runmod2", "hello"]) - self.assertEqual(self.stderr(), "") - self.assertEqual(self.stdout(), "pkg1.__init__: pkg1\nrunmod2: passed hello\n") + assert self.stderr() == "" + assert self.stdout() == "pkg1.__init__: pkg1\nrunmod2: passed hello\n" def test_runmod3(self): run_python_module(["pkg1.sub.runmod3", "hello"]) - self.assertEqual(self.stderr(), "") - self.assertEqual(self.stdout(), "pkg1.__init__: pkg1\nrunmod3: passed hello\n") + assert self.stderr() == "" + assert self.stdout() == "pkg1.__init__: pkg1\nrunmod3: passed hello\n" def test_pkg1_main(self): run_python_module(["pkg1", "hello"]) - self.assertEqual(self.stderr(), "") - self.assertEqual(self.stdout(), "pkg1.__init__: pkg1\npkg1.__main__: passed hello\n") + assert self.stderr() == "" + assert self.stdout() == "pkg1.__init__: pkg1\npkg1.__main__: passed hello\n" def test_pkg1_sub_main(self): run_python_module(["pkg1.sub", "hello"]) - self.assertEqual(self.stderr(), "") - self.assertEqual(self.stdout(), "pkg1.__init__: pkg1\npkg1.sub.__main__: passed hello\n") + assert self.stderr() == "" + assert self.stdout() == "pkg1.__init__: pkg1\npkg1.sub.__main__: passed hello\n" def test_pkg1_init(self): run_python_module(["pkg1.__init__", "wut?"]) - self.assertEqual(self.stderr(), "") - self.assertEqual(self.stdout(), "pkg1.__init__: pkg1\npkg1.__init__: __main__\n") + assert self.stderr() == "" + assert self.stdout() == "pkg1.__init__: pkg1\npkg1.__init__: __main__\n" def test_no_such_module(self): - with self.assertRaisesRegex(NoSource, "No module named '?i_dont_exist'?"): + with pytest.raises(NoSource, match="No module named '?i_dont_exist'?"): run_python_module(["i_dont_exist"]) - with self.assertRaisesRegex(NoSource, "No module named '?i'?"): + with pytest.raises(NoSource, match="No module named '?i'?"): run_python_module(["i.dont_exist"]) - with self.assertRaisesRegex(NoSource, "No module named '?i'?"): + with pytest.raises(NoSource, match="No module named '?i'?"): run_python_module(["i.dont.exist"]) def test_no_main(self): - with self.assertRaises(NoSource): + with pytest.raises(NoSource): run_python_module(["pkg2", "hi"]) diff --git a/tests/test_filereporter.py b/tests/test_filereporter.py index eb1e91e8..d928eea4 100644 --- a/tests/test_filereporter.py +++ b/tests/test_filereporter.py @@ -28,23 +28,23 @@ class FileReporterTest(UsingModulesMixin, CoverageTest): acu = PythonFileReporter("aa/afile.py") bcu = PythonFileReporter("aa/bb/bfile.py") ccu = PythonFileReporter("aa/bb/cc/cfile.py") - self.assertEqual(acu.relative_filename(), "aa/afile.py") - self.assertEqual(bcu.relative_filename(), "aa/bb/bfile.py") - self.assertEqual(ccu.relative_filename(), "aa/bb/cc/cfile.py") - self.assertEqual(acu.source(), "# afile.py\n") - self.assertEqual(bcu.source(), "# bfile.py\n") - self.assertEqual(ccu.source(), "# cfile.py\n") + assert acu.relative_filename() == "aa/afile.py" + assert bcu.relative_filename() == "aa/bb/bfile.py" + assert ccu.relative_filename() == "aa/bb/cc/cfile.py" + assert acu.source() == "# afile.py\n" + assert bcu.source() == "# bfile.py\n" + assert ccu.source() == "# cfile.py\n" def test_odd_filenames(self): acu = PythonFileReporter("aa/afile.odd.py") bcu = PythonFileReporter("aa/bb/bfile.odd.py") b2cu = PythonFileReporter("aa/bb.odd/bfile.py") - self.assertEqual(acu.relative_filename(), "aa/afile.odd.py") - self.assertEqual(bcu.relative_filename(), "aa/bb/bfile.odd.py") - self.assertEqual(b2cu.relative_filename(), "aa/bb.odd/bfile.py") - self.assertEqual(acu.source(), "# afile.odd.py\n") - self.assertEqual(bcu.source(), "# bfile.odd.py\n") - self.assertEqual(b2cu.source(), "# bfile.py\n") + assert acu.relative_filename() == "aa/afile.odd.py" + assert bcu.relative_filename() == "aa/bb/bfile.odd.py" + assert b2cu.relative_filename() == "aa/bb.odd/bfile.py" + assert acu.source() == "# afile.odd.py\n" + assert bcu.source() == "# bfile.odd.py\n" + assert b2cu.source() == "# bfile.py\n" def test_modules(self): import aa @@ -54,12 +54,12 @@ class FileReporterTest(UsingModulesMixin, CoverageTest): acu = PythonFileReporter(aa) bcu = PythonFileReporter(aa.bb) ccu = PythonFileReporter(aa.bb.cc) - self.assertEqual(acu.relative_filename(), native("aa/__init__.py")) - self.assertEqual(bcu.relative_filename(), native("aa/bb/__init__.py")) - self.assertEqual(ccu.relative_filename(), native("aa/bb/cc/__init__.py")) - self.assertEqual(acu.source(), "# aa\n") - self.assertEqual(bcu.source(), "# bb\n") - self.assertEqual(ccu.source(), "") # yes, empty + assert acu.relative_filename() == native("aa/__init__.py") + assert bcu.relative_filename() == native("aa/bb/__init__.py") + assert ccu.relative_filename() == native("aa/bb/cc/__init__.py") + assert acu.source() == "# aa\n" + assert bcu.source() == "# bb\n" + assert ccu.source() == "" # yes, empty def test_module_files(self): import aa.afile @@ -69,12 +69,12 @@ class FileReporterTest(UsingModulesMixin, CoverageTest): acu = PythonFileReporter(aa.afile) bcu = PythonFileReporter(aa.bb.bfile) ccu = PythonFileReporter(aa.bb.cc.cfile) - self.assertEqual(acu.relative_filename(), native("aa/afile.py")) - self.assertEqual(bcu.relative_filename(), native("aa/bb/bfile.py")) - self.assertEqual(ccu.relative_filename(), native("aa/bb/cc/cfile.py")) - self.assertEqual(acu.source(), "# afile.py\n") - self.assertEqual(bcu.source(), "# bfile.py\n") - self.assertEqual(ccu.source(), "# cfile.py\n") + assert acu.relative_filename() == native("aa/afile.py") + assert bcu.relative_filename() == native("aa/bb/bfile.py") + assert ccu.relative_filename() == native("aa/bb/cc/cfile.py") + assert acu.source() == "# afile.py\n" + assert bcu.source() == "# bfile.py\n" + assert ccu.source() == "# cfile.py\n" def test_comparison(self): acu = FileReporter("aa/afile.py") @@ -100,5 +100,5 @@ class FileReporterTest(UsingModulesMixin, CoverageTest): ecu = PythonFileReporter(egg1) eecu = PythonFileReporter(egg1.egg1) - self.assertEqual(ecu.source(), u"") - self.assertIn(u"# My egg file!", eecu.source().splitlines()) + assert ecu.source() == u"" + assert u"# My egg file!" in eecu.source().splitlines() diff --git a/tests/test_files.py b/tests/test_files.py index 84e25f10..1e0ddcfb 100644 --- a/tests/test_files.py +++ b/tests/test_files.py @@ -30,10 +30,10 @@ class FilesTest(CoverageTest): def test_simple(self): self.make_file("hello.py") files.set_relative_directory() - self.assertEqual(files.relative_filename(u"hello.py"), u"hello.py") + assert files.relative_filename(u"hello.py") == u"hello.py" a = self.abs_path("hello.py") - self.assertNotEqual(a, "hello.py") - self.assertEqual(files.relative_filename(a), "hello.py") + assert a != "hello.py" + assert files.relative_filename(a) == "hello.py" def test_peer_directories(self): self.make_file("sub/proj1/file1.py") @@ -43,8 +43,8 @@ class FilesTest(CoverageTest): d = os.path.normpath("sub/proj1") self.chdir(d) files.set_relative_directory() - self.assertEqual(files.relative_filename(a1), "file1.py") - self.assertEqual(files.relative_filename(a2), a2) + assert files.relative_filename(a1) == "file1.py" + assert files.relative_filename(a2) == a2 def test_filepath_contains_absolute_prefix_twice(self): # https://github.com/nedbat/coveragepy/issues/194 @@ -55,7 +55,7 @@ class FilesTest(CoverageTest): d = abs_file(os.curdir) trick = os.path.splitdrive(d)[1].lstrip(os.path.sep) rel = os.path.join('sub', trick, 'file1.py') - self.assertEqual(files.relative_filename(abs_file(rel)), rel) + assert files.relative_filename(abs_file(rel)) == rel def test_canonical_filename_ensure_cache_hit(self): self.make_file("sub/proj1/file1.py") @@ -63,12 +63,11 @@ class FilesTest(CoverageTest): self.chdir(d) files.set_relative_directory() canonical_path = files.canonical_filename('sub/proj1/file1.py') - self.assertEqual(canonical_path, self.abs_path('file1.py')) + assert canonical_path == self.abs_path('file1.py') # After the filename has been converted, it should be in the cache. - self.assertIn('sub/proj1/file1.py', files.CANONICAL_FILENAME_CACHE) - self.assertEqual( - files.canonical_filename('sub/proj1/file1.py'), - self.abs_path('file1.py')) + assert 'sub/proj1/file1.py' in files.CANONICAL_FILENAME_CACHE + assert files.canonical_filename('sub/proj1/file1.py') == \ + self.abs_path('file1.py') @pytest.mark.parametrize("original, flat", [ @@ -149,10 +148,8 @@ class MatcherTest(CoverageTest): def assertMatches(self, matcher, filepath, matches): """The `matcher` should agree with `matches` about `filepath`.""" canonical = files.canonical_filename(filepath) - self.assertEqual( - matcher.match(canonical), matches, + assert matcher.match(canonical) == matches, \ "File %s should have matched as %s" % (filepath, matches) - ) def test_tree_matcher(self): matches_to_try = [ @@ -167,7 +164,7 @@ class MatcherTest(CoverageTest): files.canonical_filename("sub3/file4.py"), ] tm = TreeMatcher(trees) - self.assertEqual(tm.info(), trees) + assert tm.info() == trees for filepath, matches in matches_to_try: self.assertMatches(tm, filepath, matches) @@ -190,16 +187,12 @@ class MatcherTest(CoverageTest): ] modules = ['test', 'py.test', 'mymain'] mm = ModuleMatcher(modules) - self.assertEqual( - mm.info(), + assert mm.info() == \ modules - ) for modulename, matches in matches_to_try: - self.assertEqual( - mm.match(modulename), - matches, - modulename, - ) + assert mm.match(modulename) == \ + matches, \ + modulename def test_fnmatch_matcher(self): matches_to_try = [ @@ -210,7 +203,7 @@ class MatcherTest(CoverageTest): (self.make_file("sub3/file5.c"), False), ] fnm = FnmatchMatcher(["*.py", "*/sub2/*"]) - self.assertEqual(fnm.info(), ["*.py", "*/sub2/*"]) + assert fnm.info() == ["*.py", "*/sub2/*"] for filepath, matches in matches_to_try: self.assertMatches(fnm, filepath, matches) @@ -244,11 +237,11 @@ class PathAliasesTest(CoverageTest): aliases.pprint() print(inp) print(out) - self.assertEqual(aliases.map(inp), files.canonical_filename(out)) + assert aliases.map(inp) == files.canonical_filename(out) def assert_unchanged(self, aliases, inp): """Assert that `inp` mapped through `aliases` is unchanged.""" - self.assertEqual(aliases.map(inp), inp) + assert aliases.map(inp) == inp def test_noop(self): aliases = PathAliases() @@ -283,11 +276,11 @@ class PathAliasesTest(CoverageTest): def test_cant_have_wildcard_at_end(self): aliases = PathAliases() msg = "Pattern must not end with wildcards." - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): aliases.add("/ned/home/*", "fooey") - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): aliases.add("/ned/home/*/", "fooey") - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): aliases.add("/ned/home/*/*/", "fooey") def test_no_accidental_munging(self): @@ -418,4 +411,4 @@ class WindowsFileTest(CoverageTest): super(WindowsFileTest, self).setUp() def test_actual_path(self): - self.assertEqual(actual_path(r'c:\Windows'), actual_path(r'C:\wINDOWS')) + assert actual_path(r'c:\Windows') == actual_path(r'C:\wINDOWS') diff --git a/tests/test_html.py b/tests/test_html.py index 825b0afb..a25f76cb 100644 --- a/tests/test_html.py +++ b/tests/test_html.py @@ -26,6 +26,7 @@ from coverage.report import get_analysis_to_report from tests.coveragetest import CoverageTest, TESTS_DIR from tests.goldtest import gold_path from tests.goldtest import compare, contains, doesnt_contain, contains_any +import pytest class HtmlTestHelpers(CoverageTest): @@ -86,7 +87,7 @@ class HtmlTestHelpers(CoverageTest): """Extract the timestamp from `html`, and assert it is recent.""" timestamp_pat = r"created at (\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})" m = re.search(timestamp_pat, html) - self.assertTrue(m, "Didn't find a timestamp!") + assert m, "Didn't find a timestamp!" timestamp = datetime.datetime(*map(int, m.groups())) # The timestamp only records the minute, so the delta could be from # 12:00 to 12:01:59, or two minutes. @@ -177,7 +178,7 @@ class HtmlDeltaTest(HtmlTestHelpers, CoverageTest): # Because the source change was only a comment, the index is the same. index2 = self.get_html_index_content() - self.assertMultiLineEqual(index1, index2) + assert index1 == index2 def test_html_delta_from_coverage_change(self): # HTML generation can create only the files that have changed. @@ -220,7 +221,7 @@ class HtmlDeltaTest(HtmlTestHelpers, CoverageTest): assert "htmlcov/main_file_py.html" in self.files_written index2 = self.get_html_index_content() - self.assertMultiLineEqual(index1, index2) + assert index1 == index2 def test_html_delta_from_coverage_version_change(self): # HTML generation can create only the files that have changed. @@ -244,7 +245,7 @@ class HtmlDeltaTest(HtmlTestHelpers, CoverageTest): index2 = self.get_html_index_content() fixed_index2 = index2.replace("XYZZY", self.real_coverage_version) - self.assertMultiLineEqual(index1, fixed_index2) + assert index1 == fixed_index2 def test_file_becomes_100(self): self.create_initial_files() @@ -270,7 +271,7 @@ class HtmlDeltaTest(HtmlTestHelpers, CoverageTest): with open("htmlcov/status.json") as status_json: status_data = json.load(status_json) - self.assertEqual(status_data['format'], 2) + assert status_data['format'] == 2 status_data['format'] = 99 with open("htmlcov/status.json", "w") as status_json: json.dump(status_data, status_json) @@ -292,44 +293,36 @@ class HtmlTitleTest(HtmlTestHelpers, CoverageTest): self.create_initial_files() self.run_coverage() index = self.get_html_index_content() - self.assertIn("Coverage report", index) - self.assertIn("

Coverage report:", index) + assert "Coverage report" in index + assert "

Coverage report:" in index def test_title_set_in_config_file(self): self.create_initial_files() self.make_file(".coveragerc", "[html]\ntitle = Metrics & stuff!\n") self.run_coverage() index = self.get_html_index_content() - self.assertIn("Metrics & stuff!", index) - self.assertIn("

Metrics & stuff!:", index) + assert "Metrics & stuff!" in index + assert "

Metrics & stuff!:" in index def test_non_ascii_title_set_in_config_file(self): self.create_initial_files() self.make_file(".coveragerc", "[html]\ntitle = «ταБЬℓσ» numbers") self.run_coverage() index = self.get_html_index_content() - self.assertIn( - "«ταБЬℓσ»" - " numbers", index - ) - self.assertIn( - "<h1>«ταБЬℓσ»" - " numbers", index - ) + assert "<title>«ταБЬℓσ»" \ + " numbers" in index + assert "<h1>«ταБЬℓσ»" \ + " numbers" in index def test_title_set_in_args(self): self.create_initial_files() self.make_file(".coveragerc", "[html]\ntitle = Good title\n") self.run_coverage(htmlargs=dict(title="«ταБЬℓσ» & stüff!")) index = self.get_html_index_content() - self.assertIn( - "<title>«ταБЬℓσ»" - " & stüff!", index - ) - self.assertIn( - "

«ταБЬℓσ»" - " & stüff!:", index - ) + assert "«ταБЬℓσ»" \ + " & stüff!" in index + assert "

«ταБЬℓσ»" \ + " & stüff!:" in index class HtmlWithUnparsableFilesTest(HtmlTestHelpers, CoverageTest): @@ -342,7 +335,7 @@ class HtmlWithUnparsableFilesTest(HtmlTestHelpers, CoverageTest): self.start_import_stop(cov, "main") self.make_file("innocuous.py", "

This isn't python!

") msg = "Couldn't parse '.*innocuous.py' as Python source: .* at line 1" - with self.assertRaisesRegex(NotPython, msg): + with pytest.raises(NotPython, match=msg): cov.html_report() def test_dotpy_not_python_ignored(self): @@ -352,20 +345,15 @@ class HtmlWithUnparsableFilesTest(HtmlTestHelpers, CoverageTest): self.start_import_stop(cov, "main") self.make_file("innocuous.py", "

This isn't python!

") cov.html_report(ignore_errors=True) - self.assertEqual( - len(cov._warnings), - 1, - "Expected a warning to be thrown when an invalid python file is parsed") - self.assertIn( - "Couldn't parse Python file", - cov._warnings[0], + assert len(cov._warnings) == \ + 1, \ + "Expected a warning to be thrown when an invalid python file is parsed" + assert "Couldn't parse Python file" in \ + cov._warnings[0], \ "Warning message should be in 'invalid file' warning" - ) - self.assertIn( - "innocuous.py", - cov._warnings[0], + assert "innocuous.py" in \ + cov._warnings[0], \ "Filename should be in 'invalid file' warning" - ) self.assert_exists("htmlcov/index.html") # This would be better as a glob, if the HTML layout changes: self.assert_doesnt_exist("htmlcov/innocuous.html") @@ -380,7 +368,7 @@ class HtmlWithUnparsableFilesTest(HtmlTestHelpers, CoverageTest): # Before reporting, change it to be an HTML file. self.make_file("innocuous.html", "

This isn't python at all!

") output = self.run_command("coverage html") - self.assertEqual(output.strip(), "No data to report.") + assert output.strip() == "No data to report." def test_execed_liar_ignored(self): # Jinja2 sets __file__ to be a non-Python file, and then execs code. @@ -428,13 +416,13 @@ class HtmlWithUnparsableFilesTest(HtmlTestHelpers, CoverageTest): with open("sub/not_ascii.py", "rb") as f: undecodable = f.read() - self.assertIn(b"?\xcb!", undecodable) + assert b"?\xcb!" in undecodable cov.html_report() html_report = self.get_html_report_content("sub/not_ascii.py") expected = "# Isn't this great?�!" - self.assertIn(expected, html_report) + assert expected in html_report def test_formfeeds(self): # https://github.com/nedbat/coveragepy/issues/360 @@ -444,7 +432,7 @@ class HtmlWithUnparsableFilesTest(HtmlTestHelpers, CoverageTest): cov.html_report() formfeed_html = self.get_html_report_content("formfeed.py") - self.assertIn("line_two", formfeed_html) + assert "line_two" in formfeed_html class HtmlTest(HtmlTestHelpers, CoverageTest): @@ -462,7 +450,7 @@ class HtmlTest(HtmlTestHelpers, CoverageTest): missing_file = os.path.join(self.temp_dir, "sub", "another.py") missing_file = os.path.realpath(missing_file) msg = "(?i)No source for code: '%s'" % re.escape(missing_file) - with self.assertRaisesRegex(NoSource, msg): + with pytest.raises(NoSource, match=msg): cov.html_report() def test_extensionless_file_collides_with_extension(self): @@ -538,7 +526,7 @@ class HtmlTest(HtmlTestHelpers, CoverageTest): normal() """) res = self.run_coverage(covargs=dict(source="."), htmlargs=dict(skip_covered=True)) - self.assertEqual(res, 100.0) + assert res == 100.0 self.assert_doesnt_exist("htmlcov/main_file_py.html") def make_init_and_main(self): @@ -588,7 +576,7 @@ class HtmlStaticFileTest(CoverageTest): with open("htmlcov/jquery.min.js") as f: jquery = f.read() - self.assertEqual(jquery, "Not Really JQuery!") + assert jquery == "Not Really JQuery!" def test_copying_static_files_from_system_in_dir(self): # Make a new place for static files. @@ -611,7 +599,7 @@ class HtmlStaticFileTest(CoverageTest): the_file = os.path.basename(fpath) with open(os.path.join("htmlcov", the_file)) as f: contents = f.read() - self.assertEqual(contents, "Not real.") + assert contents == "Not real." def test_cant_find_static_files(self): # Make the path point to useless places. @@ -621,7 +609,7 @@ class HtmlStaticFileTest(CoverageTest): cov = coverage.Coverage() self.start_import_stop(cov, "main") msg = "Couldn't find static file u?'.*'" - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): cov.html_report() def filepath_to_regex(path): diff --git a/tests/test_misc.py b/tests/test_misc.py index 2f6fbe7c..85b3d8f8 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -24,36 +24,36 @@ class HasherTest(CoverageTest): h2.update("Goodbye!") h3 = Hasher() h3.update("Hello, world!") - self.assertNotEqual(h1.hexdigest(), h2.hexdigest()) - self.assertEqual(h1.hexdigest(), h3.hexdigest()) + assert h1.hexdigest() != h2.hexdigest() + assert h1.hexdigest() == h3.hexdigest() def test_bytes_hashing(self): h1 = Hasher() h1.update(b"Hello, world!") h2 = Hasher() h2.update(b"Goodbye!") - self.assertNotEqual(h1.hexdigest(), h2.hexdigest()) + assert h1.hexdigest() != h2.hexdigest() def test_unicode_hashing(self): h1 = Hasher() h1.update(u"Hello, world! \N{SNOWMAN}") h2 = Hasher() h2.update(u"Goodbye!") - self.assertNotEqual(h1.hexdigest(), h2.hexdigest()) + assert h1.hexdigest() != h2.hexdigest() def test_dict_hashing(self): h1 = Hasher() h1.update({'a': 17, 'b': 23}) h2 = Hasher() h2.update({'b': 23, 'a': 17}) - self.assertEqual(h1.hexdigest(), h2.hexdigest()) + assert h1.hexdigest() == h2.hexdigest() def test_dict_collision(self): h1 = Hasher() h1.update({'a': 17, 'b': {'c': 1, 'd': 2}}) h2 = Hasher() h2.update({'a': 17, 'b': {'c': 1}, 'd': 2}) - self.assertNotEqual(h1.hexdigest(), h2.hexdigest()) + assert h1.hexdigest() != h2.hexdigest() class RemoveFileTest(CoverageTest): @@ -72,7 +72,7 @@ class RemoveFileTest(CoverageTest): def test_actual_errors(self): # Errors can still happen. # ". is a directory" on Unix, or "Access denied" on Windows - with self.assertRaises(OSError): + with pytest.raises(OSError): file_be_gone(".") diff --git a/tests/test_numbits.py b/tests/test_numbits.py index 232d48d3..8216b628 100644 --- a/tests/test_numbits.py +++ b/tests/test_numbits.py @@ -47,7 +47,7 @@ class NumbitsOpTest(CoverageTest): numbits = nums_to_numbits(nums) good_numbits(numbits) nums2 = numbits_to_nums(numbits) - self.assertEqual(nums, set(nums2)) + assert nums == set(nums2) @given(line_number_sets, line_number_sets) @settings(default_settings) @@ -59,7 +59,7 @@ class NumbitsOpTest(CoverageTest): nbu = numbits_union(nb1, nb2) good_numbits(nbu) union = numbits_to_nums(nbu) - self.assertEqual(nums1 | nums2, set(union)) + assert nums1 | nums2 == set(union) @given(line_number_sets, line_number_sets) @settings(default_settings) @@ -71,7 +71,7 @@ class NumbitsOpTest(CoverageTest): nbi = numbits_intersection(nb1, nb2) good_numbits(nbi) intersection = numbits_to_nums(nbi) - self.assertEqual(nums1 & nums2, set(intersection)) + assert nums1 & nums2 == set(intersection) @given(line_number_sets, line_number_sets) @settings(default_settings) @@ -82,7 +82,7 @@ class NumbitsOpTest(CoverageTest): good_numbits(nb2) inter = numbits_any_intersection(nb1, nb2) expect = bool(nums1 & nums2) - self.assertEqual(expect, bool(inter)) + assert expect == bool(inter) @given(line_numbers, line_number_sets) @settings(default_settings) @@ -91,7 +91,7 @@ class NumbitsOpTest(CoverageTest): numbits = nums_to_numbits(nums) good_numbits(numbits) is_in = num_in_numbits(num, numbits) - self.assertEqual(num in nums, is_in) + assert (num in nums) == is_in class NumbitsSqliteFunctionTest(CoverageTest): @@ -122,11 +122,9 @@ class NumbitsSqliteFunctionTest(CoverageTest): ")" ) answer = numbits_to_nums(list(res)[0][0]) - self.assertEqual( - [7, 9, 14, 18, 21, 27, 28, 35, 36, 42, 45, 49, - 54, 56, 63, 70, 72, 77, 81, 84, 90, 91, 98, 99], + assert [7, 9, 14, 18, 21, 27, 28, 35, 36, 42, 45, 49, + 54, 56, 63, 70, 72, 77, 81, 84, 90, 91, 98, 99] == \ answer - ) def test_numbits_intersection(self): res = self.cursor.execute( @@ -136,7 +134,7 @@ class NumbitsSqliteFunctionTest(CoverageTest): ")" ) answer = numbits_to_nums(list(res)[0][0]) - self.assertEqual([63], answer) + assert [63] == answer def test_numbits_any_intersection(self): res = self.cursor.execute( @@ -144,20 +142,20 @@ class NumbitsSqliteFunctionTest(CoverageTest): (nums_to_numbits([1, 2, 3]), nums_to_numbits([3, 4, 5])) ) answer = [any_inter for (any_inter,) in res] - self.assertEqual([1], answer) + assert [1] == answer res = self.cursor.execute( "select numbits_any_intersection(?, ?)", (nums_to_numbits([1, 2, 3]), nums_to_numbits([7, 8, 9])) ) answer = [any_inter for (any_inter,) in res] - self.assertEqual([0], answer) + assert [0] == answer def test_num_in_numbits(self): res = self.cursor.execute("select id, num_in_numbits(12, numbits) from data order by id") answer = [is_in for (id, is_in) in res] - self.assertEqual([1, 1, 1, 1, 0, 1, 0, 0, 0, 0], answer) + assert [1, 1, 1, 1, 0, 1, 0, 0, 0, 0] == answer def test_numbits_to_nums(self): res = self.cursor.execute("select numbits_to_nums(?)", [nums_to_numbits([1, 2, 3])]) - self.assertEqual([1, 2, 3], json.loads(res.fetchone()[0])) + assert [1, 2, 3] == json.loads(res.fetchone()[0]) diff --git a/tests/test_oddball.py b/tests/test_oddball.py index 17f69647..46c22f9c 100644 --- a/tests/test_oddball.py +++ b/tests/test_oddball.py @@ -80,7 +80,7 @@ class RecursionTest(CoverageTest): def test_long_recursion(self): # We can't finish a very deep recursion, but we don't crash. - with self.assertRaises(RuntimeError): + with pytest.raises(RuntimeError): self.check_coverage("""\ def recur(n): if n == 0: @@ -125,16 +125,15 @@ class RecursionTest(CoverageTest): expected_missing += [9, 10, 11] _, statements, missing, _ = cov.analysis("recur.py") - self.assertEqual(statements, [1, 2, 3, 5, 7, 8, 9, 10, 11]) - self.assertEqual(expected_missing, missing) + assert statements == [1, 2, 3, 5, 7, 8, 9, 10, 11] + assert expected_missing == missing # Get a warning about the stackoverflow effect on the tracing function. if pytrace: # pragma: no metacov - self.assertEqual(cov._warnings, + assert cov._warnings == \ ["Trace function changed, measurement is likely wrong: None"] - ) else: - self.assertEqual(cov._warnings, []) + assert cov._warnings == [] class MemoryLeakTest(CoverageTest): @@ -224,9 +223,9 @@ class MemoryFumblingTest(CoverageTest): print("Final None refcount: %d" % (sys.getrefcount(None))) """) status, out = self.run_command_status("python main.py") - self.assertEqual(status, 0) - self.assertIn("Final None refcount", out) - self.assertNotIn("Fatal", out) + assert status == 0 + assert "Final None refcount" in out + assert "Fatal" not in out class PyexpatTest(CoverageTest): @@ -268,20 +267,18 @@ class PyexpatTest(CoverageTest): self.start_import_stop(cov, "outer") _, statements, missing, _ = cov.analysis("trydom.py") - self.assertEqual(statements, [1, 3, 8, 9, 10, 11, 13]) - self.assertEqual(missing, []) + assert statements == [1, 3, 8, 9, 10, 11, 13] + assert missing == [] _, statements, missing, _ = cov.analysis("outer.py") - self.assertEqual(statements, [101, 102]) - self.assertEqual(missing, []) + assert statements == [101, 102] + assert missing == [] # Make sure pyexpat isn't recorded as a source file. # https://github.com/nedbat/coveragepy/issues/419 files = cov.get_data().measured_files() - self.assertFalse( - any(f.endswith("pyexpat.c") for f in files), + assert not any(f.endswith("pyexpat.c") for f in files), \ "Pyexpat.c is in the measured files!: %r:" % (files,) - ) class ExceptionTest(CoverageTest): @@ -393,7 +390,7 @@ class ExceptionTest(CoverageTest): for lines in lines_expected.values(): lines[:] = [l for l in lines if l not in invisible] - self.assertEqual(clean_lines, lines_expected) + assert clean_lines == lines_expected class DoctestTest(CoverageTest): @@ -451,11 +448,11 @@ class GettraceTest(CoverageTest): cov = coverage.Coverage(source=["sample"]) self.start_import_stop(cov, "main") - self.assertEqual(self.stdout(), "10\n7\n3\n5\n9\n12\n") + assert self.stdout() == "10\n7\n3\n5\n9\n12\n" _, statements, missing, _ = cov.analysis("sample.py") - self.assertEqual(statements, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) - self.assertEqual(missing, []) + assert statements == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + assert missing == [] def test_setting_new_trace_function(self): # https://github.com/nedbat/coveragepy/issues/436 @@ -489,15 +486,13 @@ class GettraceTest(CoverageTest): out = self.stdout().replace(self.last_module_name, "coverage_test") - self.assertEqual( - out, + assert out == \ ( "call: coverage_test.py @ 10\n" "line: coverage_test.py @ 11\n" "line: coverage_test.py @ 12\n" "return: coverage_test.py @ 12\n" - ), - ) + ) @pytest.mark.expensive def test_atexit_gettrace(self): # pragma: no metacov @@ -523,13 +518,13 @@ class GettraceTest(CoverageTest): # This will show what the trace function is at the end of the program. """) status, out = self.run_command_status("python atexit_gettrace.py") - self.assertEqual(status, 0) + assert status == 0 if env.PYPY and env.PYPYVERSION >= (5, 4): # Newer PyPy clears the trace function before atexit runs. - self.assertEqual(out, "None\n") + assert out == "None\n" else: # Other Pythons leave the trace function in place. - self.assertEqual(out, "trace_function\n") + assert out == "trace_function\n" class ExecTest(CoverageTest): @@ -557,11 +552,11 @@ class ExecTest(CoverageTest): self.start_import_stop(cov, "main") _, statements, missing, _ = cov.analysis("main.py") - self.assertEqual(statements, [1, 2, 3, 4, 35]) - self.assertEqual(missing, []) + assert statements == [1, 2, 3, 4, 35] + assert missing == [] _, statements, missing, _ = cov.analysis("to_exec.py") - self.assertEqual(statements, [31]) - self.assertEqual(missing, []) + assert statements == [31] + assert missing == [] def test_unencodable_filename(self): # https://github.com/nedbat/coveragepy/issues/891 @@ -609,4 +604,4 @@ class MockingProtectionTest(CoverageTest): import py_compile py_compile.compile("bug416a.py") out = self.run_command("coverage run bug416.py") - self.assertEqual(out, "in test\nbug416a.py\n23\n17\n") + assert out == "in test\nbug416a.py\n23\n17\n" diff --git a/tests/test_parser.py b/tests/test_parser.py index 9d3f9f67..49b23f9b 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -11,6 +11,7 @@ from coverage.parser import PythonParser from tests.coveragetest import CoverageTest, xfail from tests.helpers import arcz_to_arcs +import pytest class PythonParserTest(CoverageTest): @@ -40,9 +41,9 @@ class PythonParserTest(CoverageTest): class Bar: pass """) - self.assertEqual(parser.exit_counts(), { + assert parser.exit_counts() == { 2:1, 3:1, 4:2, 5:1, 7:1, 9:1, 10:1 - }) + } def test_generator_exit_counts(self): # https://github.com/nedbat/coveragepy/issues/324 @@ -53,12 +54,12 @@ class PythonParserTest(CoverageTest): list(gen([1,2,3])) """) - self.assertEqual(parser.exit_counts(), { + assert parser.exit_counts() == { 1:1, # def -> list 2:2, # for -> yield; for -> exit 3:2, # yield -> for; genexp exit 5:1, # list -> exit - }) + } def test_try_except(self): parser = self.parse_source("""\ @@ -72,9 +73,9 @@ class PythonParserTest(CoverageTest): a = 8 b = 9 """) - self.assertEqual(parser.exit_counts(), { + assert parser.exit_counts() == { 1: 1, 2:1, 3:2, 4:1, 5:2, 6:1, 7:1, 8:1, 9:1 - }) + } def test_excluded_classes(self): parser = self.parse_source("""\ @@ -86,9 +87,9 @@ class PythonParserTest(CoverageTest): class Bar: pass """) - self.assertEqual(parser.exit_counts(), { + assert parser.exit_counts() == { 1:0, 2:1, 3:1 - }) + } def test_missing_branch_to_excluded_code(self): parser = self.parse_source("""\ @@ -98,7 +99,7 @@ class PythonParserTest(CoverageTest): a = 4 b = 5 """) - self.assertEqual(parser.exit_counts(), { 1:1, 2:1, 5:1 }) + assert parser.exit_counts() == { 1:1, 2:1, 5:1 } parser = self.parse_source("""\ def foo(): if fooey: @@ -107,7 +108,7 @@ class PythonParserTest(CoverageTest): a = 5 b = 6 """) - self.assertEqual(parser.exit_counts(), { 1:1, 2:2, 3:1, 5:1, 6:1 }) + assert parser.exit_counts() == { 1:1, 2:2, 3:1, 5:1, 6:1 } parser = self.parse_source("""\ def foo(): if fooey: @@ -116,14 +117,14 @@ class PythonParserTest(CoverageTest): a = 5 b = 6 """) - self.assertEqual(parser.exit_counts(), { 1:1, 2:1, 3:1, 6:1 }) + assert parser.exit_counts() == { 1:1, 2:1, 3:1, 6:1 } def test_indentation_error(self): msg = ( "Couldn't parse '' as Python source: " "'unindent does not match any outer indentation level' at line 3" ) - with self.assertRaisesRegex(NotPython, msg): + with pytest.raises(NotPython, match=msg): _ = self.parse_source("""\ 0 spaces 2 @@ -132,7 +133,7 @@ class PythonParserTest(CoverageTest): def test_token_error(self): msg = "Couldn't parse '' as Python source: 'EOF in multi-line string' at line 1" - with self.assertRaisesRegex(NotPython, msg): + with pytest.raises(NotPython, match=msg): _ = self.parse_source("""\ ''' """) @@ -174,8 +175,8 @@ class PythonParserTest(CoverageTest): raw_statements = {3, 4, 5, 6, 8, 9, 10, 13, 15, 16, 17, 20, 22, 23, 25, 26} if env.PYBEHAVIOR.trace_decorated_def: raw_statements.update([11, 19]) - self.assertEqual(parser.raw_statements, raw_statements) - self.assertEqual(parser.statements, {8}) + assert parser.raw_statements == raw_statements + assert parser.statements == {8} def test_class_decorator_pragmas(self): parser = self.parse_source("""\ @@ -188,8 +189,8 @@ class PythonParserTest(CoverageTest): def __init__(self): self.x = 8 """) - self.assertEqual(parser.raw_statements, {1, 2, 3, 5, 6, 7, 8}) - self.assertEqual(parser.statements, {1, 2, 3}) + assert parser.raw_statements == {1, 2, 3, 5, 6, 7, 8} + assert parser.statements == {1, 2, 3} def test_empty_decorated_function(self): parser = self.parse_source("""\ @@ -219,9 +220,9 @@ class PythonParserTest(CoverageTest): expected_arcs.update(set(arcz_to_arcs("-46 6-4"))) expected_exits.update({6: 1}) - self.assertEqual(expected_statements, parser.statements) - self.assertEqual(expected_arcs, parser.arcs()) - self.assertEqual(expected_exits, parser.exit_counts()) + assert expected_statements == parser.statements + assert expected_arcs == parser.arcs() + assert expected_exits == parser.exit_counts() class ParserMissingArcDescriptionTest(CoverageTest): @@ -252,31 +253,19 @@ class ParserMissingArcDescriptionTest(CoverageTest): thing(12) more_stuff(13) """) - self.assertEqual( - parser.missing_arc_description(1, 2), + assert parser.missing_arc_description(1, 2) == \ "line 1 didn't jump to line 2, because the condition on line 1 was never true" - ) - self.assertEqual( - parser.missing_arc_description(1, 3), + assert parser.missing_arc_description(1, 3) == \ "line 1 didn't jump to line 3, because the condition on line 1 was never false" - ) - self.assertEqual( - parser.missing_arc_description(6, -5), - "line 6 didn't return from function 'func5', " + assert parser.missing_arc_description(6, -5) == \ + "line 6 didn't return from function 'func5', " \ "because the loop on line 6 didn't complete" - ) - self.assertEqual( - parser.missing_arc_description(6, 7), + assert parser.missing_arc_description(6, 7) == \ "line 6 didn't jump to line 7, because the loop on line 6 never started" - ) - self.assertEqual( - parser.missing_arc_description(11, 12), + assert parser.missing_arc_description(11, 12) == \ "line 11 didn't jump to line 12, because the condition on line 11 was never true" - ) - self.assertEqual( - parser.missing_arc_description(11, 13), + assert parser.missing_arc_description(11, 13) == \ "line 11 didn't jump to line 13, because the condition on line 11 was never false" - ) def test_missing_arc_descriptions_for_small_callables(self): parser = self.parse_text(u"""\ @@ -288,22 +277,14 @@ class ParserMissingArcDescriptionTest(CoverageTest): ] x = 7 """) - self.assertEqual( - parser.missing_arc_description(2, -2), + assert parser.missing_arc_description(2, -2) == \ "line 2 didn't finish the lambda on line 2" - ) - self.assertEqual( - parser.missing_arc_description(3, -3), + assert parser.missing_arc_description(3, -3) == \ "line 3 didn't finish the generator expression on line 3" - ) - self.assertEqual( - parser.missing_arc_description(4, -4), + assert parser.missing_arc_description(4, -4) == \ "line 4 didn't finish the dictionary comprehension on line 4" - ) - self.assertEqual( - parser.missing_arc_description(5, -5), + assert parser.missing_arc_description(5, -5) == \ "line 5 didn't finish the set comprehension on line 5" - ) def test_missing_arc_descriptions_for_exceptions(self): parser = self.parse_text(u"""\ @@ -314,14 +295,10 @@ class ParserMissingArcDescriptionTest(CoverageTest): except ValueError: print("yikes") """) - self.assertEqual( - parser.missing_arc_description(3, 4), + assert parser.missing_arc_description(3, 4) == \ "line 3 didn't jump to line 4, because the exception caught by line 3 didn't happen" - ) - self.assertEqual( - parser.missing_arc_description(5, 6), + assert parser.missing_arc_description(5, 6) == \ "line 5 didn't jump to line 6, because the exception caught by line 5 didn't happen" - ) def test_missing_arc_descriptions_for_finally(self): parser = self.parse_text(u"""\ @@ -346,56 +323,36 @@ class ParserMissingArcDescriptionTest(CoverageTest): that_thing(19) """) if env.PYBEHAVIOR.finally_jumps_back: - self.assertEqual( - parser.missing_arc_description(18, 5), + assert parser.missing_arc_description(18, 5) == \ "line 18 didn't jump to line 5, because the break on line 5 wasn't executed" - ) - self.assertEqual( - parser.missing_arc_description(5, 19), + assert parser.missing_arc_description(5, 19) == \ "line 5 didn't jump to line 19, because the break on line 5 wasn't executed" - ) - self.assertEqual( - parser.missing_arc_description(18, 10), + assert parser.missing_arc_description(18, 10) == \ "line 18 didn't jump to line 10, because the continue on line 10 wasn't executed" - ) - self.assertEqual( - parser.missing_arc_description(10, 2), + assert parser.missing_arc_description(10, 2) == \ "line 10 didn't jump to line 2, because the continue on line 10 wasn't executed" - ) - self.assertEqual( - parser.missing_arc_description(18, 14), + assert parser.missing_arc_description(18, 14) == \ "line 18 didn't jump to line 14, because the return on line 14 wasn't executed" - ) - self.assertEqual( - parser.missing_arc_description(14, -1), - "line 14 didn't return from function 'function', " + assert parser.missing_arc_description(14, -1) == \ + "line 14 didn't return from function 'function', " \ "because the return on line 14 wasn't executed" - ) - self.assertEqual( - parser.missing_arc_description(18, -1), - "line 18 didn't except from function 'function', " + assert parser.missing_arc_description(18, -1) == \ + "line 18 didn't except from function 'function', " \ "because the raise on line 16 wasn't executed" - ) else: - self.assertEqual( - parser.missing_arc_description(18, 19), + assert parser.missing_arc_description(18, 19) == \ "line 18 didn't jump to line 19, because the break on line 5 wasn't executed" - ) - self.assertEqual( - parser.missing_arc_description(18, 2), - "line 18 didn't jump to line 2, " - "because the continue on line 10 wasn't executed" - " or " + assert parser.missing_arc_description(18, 2) == \ + "line 18 didn't jump to line 2, " \ + "because the continue on line 10 wasn't executed" \ + " or " \ "the continue on line 12 wasn't executed" - ) - self.assertEqual( - parser.missing_arc_description(18, -1), - "line 18 didn't except from function 'function', " - "because the raise on line 16 wasn't executed" - " or " - "line 18 didn't return from function 'function', " + assert parser.missing_arc_description(18, -1) == \ + "line 18 didn't except from function 'function', " \ + "because the raise on line 16 wasn't executed" \ + " or " \ + "line 18 didn't return from function 'function', " \ "because the return on line 14 wasn't executed" - ) def test_missing_arc_descriptions_bug460(self): parser = self.parse_text(u"""\ @@ -406,10 +363,8 @@ class ParserMissingArcDescriptionTest(CoverageTest): } x = 6 """) - self.assertEqual( - parser.missing_arc_description(2, -3), - "line 3 didn't finish the lambda on line 3", - ) + assert parser.missing_arc_description(2, -3) == \ + "line 3 didn't finish the lambda on line 3" class ParserFileTest(CoverageTest): @@ -440,18 +395,16 @@ class ParserFileTest(CoverageTest): fname = fname + ".py" self.make_file(fname, text, newline=newline) parser = self.parse_file(fname) - self.assertEqual( - parser.exit_counts(), - counts, + assert parser.exit_counts() == \ + counts, \ "Wrong for %r" % fname - ) def test_encoding(self): self.make_file("encoded.py", """\ coverage = "\xe7\xf6v\xear\xe3g\xe9" """) parser = self.parse_file("encoded.py") - self.assertEqual(parser.exit_counts(), {1: 1}) + assert parser.exit_counts() == {1: 1} def test_missing_line_ending(self): # Test that the set of statements is the same even if a final @@ -466,7 +419,7 @@ class ParserFileTest(CoverageTest): """) parser = self.parse_file("normal.py") - self.assertEqual(parser.statements, {1}) + assert parser.statements == {1} self.make_file("abrupt.py", """\ out, err = subprocess.Popen( @@ -476,7 +429,7 @@ class ParserFileTest(CoverageTest): # Double-check that some test helper wasn't being helpful. with open("abrupt.py") as f: - self.assertEqual(f.read()[-1], ")") + assert f.read()[-1] == ")" parser = self.parse_file("abrupt.py") - self.assertEqual(parser.statements, {1}) + assert parser.statements == {1} diff --git a/tests/test_phystokens.py b/tests/test_phystokens.py index 1256694a..5da12d9c 100644 --- a/tests/test_phystokens.py +++ b/tests/test_phystokens.py @@ -13,6 +13,7 @@ from coverage.phystokens import neuter_encoding_declaration, compile_unicode from coverage.python import get_python_source from tests.coveragetest import CoverageTest, TESTS_DIR +import pytest # A simple program and its token stream. @@ -67,23 +68,23 @@ class PhysTokensTest(CoverageTest): source = source.replace('\r\n', '\n') source = re.sub(r"(?m)[ \t]+$", "", source) tokenized = re.sub(r"(?m)[ \t]+$", "", tokenized) - self.assertMultiLineEqual(source, tokenized) + assert source == tokenized def check_file_tokenization(self, fname): """Use the contents of `fname` for `check_tokenization`.""" self.check_tokenization(get_python_source(fname)) def test_simple(self): - self.assertEqual(list(source_token_lines(SIMPLE)), SIMPLE_TOKENS) + assert list(source_token_lines(SIMPLE)) == SIMPLE_TOKENS self.check_tokenization(SIMPLE) def test_missing_final_newline(self): # We can tokenize source that is missing the final newline. - self.assertEqual(list(source_token_lines(SIMPLE.rstrip())), SIMPLE_TOKENS) + assert list(source_token_lines(SIMPLE.rstrip())) == SIMPLE_TOKENS def test_tab_indentation(self): # Mixed tabs and spaces... - self.assertEqual(list(source_token_lines(MIXED_WS)), MIXED_WS_TOKENS) + assert list(source_token_lines(MIXED_WS)) == MIXED_WS_TOKENS def test_bug_822(self): self.check_tokenization(BUG_822) @@ -128,11 +129,9 @@ class SourceEncodingTest(CoverageTest): def test_detect_source_encoding(self): for _, source, expected in ENCODING_DECLARATION_SOURCES: - self.assertEqual( - source_encoding(source), - expected, + assert source_encoding(source) == \ + expected, \ "Wrong encoding in %r" % source - ) def test_detect_source_encoding_not_in_comment(self): if env.PYPY3: # pragma: no metacov @@ -141,35 +140,35 @@ class SourceEncodingTest(CoverageTest): self.skipTest("PyPy3 is wrong about non-comment encoding. Skip it.") # Should not detect anything here source = b'def parse(src, encoding=None):\n pass' - self.assertEqual(source_encoding(source), DEF_ENCODING) + assert source_encoding(source) == DEF_ENCODING def test_dont_detect_source_encoding_on_third_line(self): # A coding declaration doesn't count on the third line. source = b"\n\n# coding=cp850\n\n" - self.assertEqual(source_encoding(source), DEF_ENCODING) + assert source_encoding(source) == DEF_ENCODING def test_detect_source_encoding_of_empty_file(self): # An important edge case. - self.assertEqual(source_encoding(b""), DEF_ENCODING) + assert source_encoding(b"") == DEF_ENCODING def test_bom(self): # A BOM means utf-8. source = b"\xEF\xBB\xBFtext = 'hello'\n" - self.assertEqual(source_encoding(source), 'utf-8-sig') + assert source_encoding(source) == 'utf-8-sig' def test_bom_with_encoding(self): source = b"\xEF\xBB\xBF# coding: utf-8\ntext = 'hello'\n" - self.assertEqual(source_encoding(source), 'utf-8-sig') + assert source_encoding(source) == 'utf-8-sig' def test_bom_is_wrong(self): # A BOM with an explicit non-utf8 encoding is an error. source = b"\xEF\xBB\xBF# coding: cp850\n" - with self.assertRaisesRegex(SyntaxError, "encoding problem: utf-8"): + with pytest.raises(SyntaxError, match="encoding problem: utf-8"): source_encoding(source) def test_unknown_encoding(self): source = b"# coding: klingon\n" - with self.assertRaisesRegex(SyntaxError, "unknown encoding: klingon"): + with pytest.raises(SyntaxError, match="unknown encoding: klingon"): source_encoding(source) @@ -186,21 +185,19 @@ class NeuterEncodingDeclarationTest(CoverageTest): # The neutered source should have the same number of lines. source_lines = source.splitlines() neutered_lines = neutered.splitlines() - self.assertEqual(len(source_lines), len(neutered_lines)) + assert len(source_lines) == len(neutered_lines) # Only one of the lines should be different. lines_different = sum( int(nline != sline) for nline, sline in zip(neutered_lines, source_lines) ) - self.assertEqual(lines_diff_expected, lines_different) + assert lines_diff_expected == lines_different # The neutered source will be detected as having no encoding # declaration. - self.assertEqual( - source_encoding(neutered), - DEF_ENCODING, + assert source_encoding(neutered) == \ + DEF_ENCODING, \ "Wrong encoding in %r" % neutered - ) def test_two_encoding_declarations(self): input_src = textwrap.dedent(u"""\ @@ -214,7 +211,7 @@ class NeuterEncodingDeclarationTest(CoverageTest): # -*- coding: utf-16 -*- """) output_src = neuter_encoding_declaration(input_src) - self.assertEqual(expected_src, output_src) + assert expected_src == output_src def test_one_encoding_declaration(self): input_src = textwrap.dedent(u"""\ @@ -228,7 +225,7 @@ class NeuterEncodingDeclarationTest(CoverageTest): # -*- coding: ascii -*- """) output_src = neuter_encoding_declaration(input_src) - self.assertEqual(expected_src, output_src) + assert expected_src == output_src class Bug529Test(CoverageTest): @@ -258,8 +255,8 @@ class Bug529Test(CoverageTest): unittest.main() ''') status, out = self.run_command_status("coverage run the_test.py") - self.assertEqual(status, 0) - self.assertIn("OK", out) + assert status == 0 + assert "OK" in out # If this test fails, the output will be super-confusing, because it # has a failing unit test contained within the failing unit test. @@ -276,7 +273,7 @@ class CompileUnicodeTest(CoverageTest): code = compile_unicode(source, "", "exec") globs = {} exec(code, globs) - self.assertEqual(globs['a'], 42) + assert globs['a'] == 42 def test_cp1252(self): uni = u"""# coding: cp1252\n# \u201C curly \u201D\n""" diff --git a/tests/test_plugins.py b/tests/test_plugins.py index 813d370e..3472522b 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -18,6 +18,7 @@ import coverage.plugin from tests.coveragetest import CoverageTest from tests.helpers import CheckUniqueFilenames +import pytest class FakeConfig(object): @@ -53,10 +54,10 @@ class LoadPluginsTest(CoverageTest): config = FakeConfig("plugin1", {}) plugins = Plugins.load_plugins([], config) - self.assertFalse(plugins) + assert not plugins plugins = Plugins.load_plugins(["plugin1"], config) - self.assertTrue(plugins) + assert plugins def test_importing_and_configuring(self): self.make_file("plugin1.py", """\ @@ -74,10 +75,10 @@ class LoadPluginsTest(CoverageTest): config = FakeConfig("plugin1", {'a': 'hello'}) plugins = list(Plugins.load_plugins(["plugin1"], config)) - self.assertEqual(len(plugins), 1) - self.assertEqual(plugins[0].this_is, "me") - self.assertEqual(plugins[0].options, {'a': 'hello'}) - self.assertEqual(config.asked_for, ['plugin1']) + assert len(plugins) == 1 + assert plugins[0].this_is == "me" + assert plugins[0].options == {'a': 'hello'} + assert config.asked_for == ['plugin1'] def test_importing_and_configuring_more_than_one(self): self.make_file("plugin1.py", """\ @@ -105,23 +106,23 @@ class LoadPluginsTest(CoverageTest): config = FakeConfig("plugin1", {'a': 'hello'}) plugins = list(Plugins.load_plugins(["plugin1", "plugin2"], config)) - self.assertEqual(len(plugins), 2) - self.assertEqual(plugins[0].this_is, "me") - self.assertEqual(plugins[0].options, {'a': 'hello'}) - self.assertEqual(plugins[1].options, {}) - self.assertEqual(config.asked_for, ['plugin1', 'plugin2']) + assert len(plugins) == 2 + assert plugins[0].this_is == "me" + assert plugins[0].options == {'a': 'hello'} + assert plugins[1].options == {} + assert config.asked_for == ['plugin1', 'plugin2'] # The order matters... config = FakeConfig("plugin1", {'a': 'second'}) plugins = list(Plugins.load_plugins(["plugin2", "plugin1"], config)) - self.assertEqual(len(plugins), 2) - self.assertEqual(plugins[0].options, {}) - self.assertEqual(plugins[1].this_is, "me") - self.assertEqual(plugins[1].options, {'a': 'second'}) + assert len(plugins) == 2 + assert plugins[0].options == {} + assert plugins[1].this_is == "me" + assert plugins[1].options == {'a': 'second'} def test_cant_import(self): - with self.assertRaisesRegex(ImportError, "No module named '?plugin_not_there'?"): + with pytest.raises(ImportError, match="No module named '?plugin_not_there'?"): _ = Plugins.load_plugins(["plugin_not_there"], None) def test_plugin_must_define_coverage_init(self): @@ -130,7 +131,7 @@ class LoadPluginsTest(CoverageTest): Nothing = 0 """) msg_pat = "Plugin module 'no_plugin' didn't define a coverage_init function" - with self.assertRaisesRegex(CoverageException, msg_pat): + with pytest.raises(CoverageException, match=msg_pat): list(Plugins.load_plugins(["no_plugin"], None)) @@ -156,11 +157,11 @@ class PluginTest(CoverageTest): cov.stop() # pragma: nested with open("evidence.out") as f: - self.assertEqual(f.read(), "we are here!") + assert f.read() == "we are here!" def test_missing_plugin_raises_import_error(self): # Prove that a missing plugin will raise an ImportError. - with self.assertRaisesRegex(ImportError, "No module named '?does_not_exist_woijwoicweo'?"): + with pytest.raises(ImportError, match="No module named '?does_not_exist_woijwoicweo'?"): cov = coverage.Coverage() cov.set_option("run:plugins", ["does_not_exist_woijwoicweo"]) cov.start() @@ -169,7 +170,7 @@ class PluginTest(CoverageTest): def test_bad_plugin_isnt_hidden(self): # Prove that a plugin with an error in it will raise the error. self.make_file("plugin_over_zero.py", "1/0") - with self.assertRaises(ZeroDivisionError): + with pytest.raises(ZeroDivisionError): cov = coverage.Coverage() cov.set_option("run:plugins", ["plugin_over_zero"]) cov.start() @@ -195,16 +196,16 @@ class PluginTest(CoverageTest): out_lines = [line.strip() for line in debug_out.getvalue().splitlines()] if env.C_TRACER: - self.assertIn('plugins.file_tracers: plugin_sys_info.Plugin', out_lines) + assert 'plugins.file_tracers: plugin_sys_info.Plugin' in out_lines else: - self.assertIn('plugins.file_tracers: plugin_sys_info.Plugin (disabled)', out_lines) - self.assertIn('plugins.configurers: -none-', out_lines) + assert 'plugins.file_tracers: plugin_sys_info.Plugin (disabled)' in out_lines + assert 'plugins.configurers: -none-' in out_lines expected_end = [ "-- sys: plugin_sys_info.Plugin -------------------------------", "hello: world", "-- end -------------------------------------------------------", ] - self.assertEqual(expected_end, out_lines[-len(expected_end):]) + assert expected_end == out_lines[-len(expected_end):] def test_plugin_with_no_sys_info(self): self.make_file("plugin_no_sys_info.py", """\ @@ -224,13 +225,13 @@ class PluginTest(CoverageTest): cov.stop() # pragma: nested out_lines = [line.strip() for line in debug_out.getvalue().splitlines()] - self.assertIn('plugins.file_tracers: -none-', out_lines) - self.assertIn('plugins.configurers: plugin_no_sys_info.Plugin', out_lines) + assert 'plugins.file_tracers: -none-' in out_lines + assert 'plugins.configurers: plugin_no_sys_info.Plugin' in out_lines expected_end = [ "-- sys: plugin_no_sys_info.Plugin ----------------------------", "-- end -------------------------------------------------------", ] - self.assertEqual(expected_end, out_lines[-len(expected_end):]) + assert expected_end == out_lines[-len(expected_end):] def test_local_files_are_importable(self): self.make_file("importing_plugin.py", """\ @@ -249,9 +250,9 @@ class PluginTest(CoverageTest): self.make_file("main_file.py", "print('MAIN')") out = self.run_command("coverage run main_file.py") - self.assertEqual(out, "MAIN\n") + assert out == "MAIN\n" out = self.run_command("coverage html") - self.assertEqual(out, "") + assert out == "" class PluginWarningOnPyTracer(CoverageTest): @@ -304,11 +305,11 @@ class GoodFileTracerTest(FileTracerTest): self.start_import_stop(cov, "simple") _, statements, missing, _ = cov.analysis("simple.py") - self.assertEqual(statements, [1, 2, 3]) - self.assertEqual(missing, []) + assert statements == [1, 2, 3] + assert missing == [] zzfile = os.path.abspath(os.path.join("/src", "try_ABC.zz")) _, statements, _, _ = cov.analysis(zzfile) - self.assertEqual(statements, [105, 106, 107, 205, 206, 207]) + assert statements == [105, 106, 107, 205, 206, 207] def make_render_and_caller(self): """Make the render.py and caller.py files we need.""" @@ -370,21 +371,21 @@ class GoodFileTracerTest(FileTracerTest): # have 7 lines in it. If render() was called with line number 4, # then the plugin will claim that lines 4 and 5 were executed. _, statements, missing, _ = cov.analysis("foo_7.html") - self.assertEqual(statements, [1, 2, 3, 4, 5, 6, 7]) - self.assertEqual(missing, [1, 2, 3, 6, 7]) - self.assertIn("foo_7.html", line_counts(cov.get_data())) + assert statements == [1, 2, 3, 4, 5, 6, 7] + assert missing == [1, 2, 3, 6, 7] + assert "foo_7.html" in line_counts(cov.get_data()) _, statements, missing, _ = cov.analysis("bar_4.html") - self.assertEqual(statements, [1, 2, 3, 4]) - self.assertEqual(missing, [1, 4]) - self.assertIn("bar_4.html", line_counts(cov.get_data())) + assert statements == [1, 2, 3, 4] + assert missing == [1, 4] + assert "bar_4.html" in line_counts(cov.get_data()) - self.assertNotIn("quux_5.html", line_counts(cov.get_data())) + assert "quux_5.html" not in line_counts(cov.get_data()) _, statements, missing, _ = cov.analysis("uni_3.html") - self.assertEqual(statements, [1, 2, 3]) - self.assertEqual(missing, [1]) - self.assertIn("uni_3.html", line_counts(cov.get_data())) + assert statements == [1, 2, 3] + assert missing == [1] + assert "uni_3.html" in line_counts(cov.get_data()) def test_plugin2_with_branch(self): self.make_render_and_caller() @@ -400,12 +401,12 @@ class GoodFileTracerTest(FileTracerTest): # have 7 lines in it. If render() was called with line number 4, # then the plugin will claim that lines 4 and 5 were executed. analysis = cov._analyze("foo_7.html") - self.assertEqual(analysis.statements, {1, 2, 3, 4, 5, 6, 7}) + assert analysis.statements == {1, 2, 3, 4, 5, 6, 7} # Plugins don't do branch coverage yet. - self.assertEqual(analysis.has_arcs(), True) - self.assertEqual(analysis.arc_possibilities(), []) + assert analysis.has_arcs() == True + assert analysis.arc_possibilities() == [] - self.assertEqual(analysis.missing, {1, 2, 3, 6, 7}) + assert analysis.missing == {1, 2, 3, 6, 7} def test_plugin2_with_text_report(self): self.make_render_and_caller() @@ -426,8 +427,8 @@ class GoodFileTracerTest(FileTracerTest): '--------------------------------------------------------', 'TOTAL 11 7 0 0 36%', ] - self.assertEqual(expected, report) - self.assertAlmostEqual(total, 36.36, places=2) + assert expected == report + assert round(abs(total-36.36), 2) == 0 def test_plugin2_with_html_report(self): self.make_render_and_caller() @@ -438,7 +439,7 @@ class GoodFileTracerTest(FileTracerTest): self.start_import_stop(cov, "caller") total = cov.html_report(include=["*.html"], omit=["uni*.html"]) - self.assertAlmostEqual(total, 36.36, places=2) + assert round(abs(total-36.36), 2) == 0 self.assert_exists("htmlcov/index.html") self.assert_exists("htmlcov/bar_4_html.html") @@ -453,7 +454,7 @@ class GoodFileTracerTest(FileTracerTest): self.start_import_stop(cov, "caller") total = cov.xml_report(include=["*.html"], omit=["uni*.html"]) - self.assertAlmostEqual(total, 36.36, places=2) + assert round(abs(total-36.36), 2) == 0 dom = ElementTree.parse("coverage.xml") classes = {} @@ -525,8 +526,8 @@ class GoodFileTracerTest(FileTracerTest): '-----------------------------------------------', 'TOTAL 6 3 50%', ] - self.assertEqual(expected, report) - self.assertEqual(total, 50) + assert expected == report + assert total == 50 def test_find_unexecuted(self): self.make_file("unexecuted_plugin.py", """\ @@ -567,17 +568,17 @@ class GoodFileTracerTest(FileTracerTest): # The file we executed claims to have run line 999. _, statements, missing, _ = cov.analysis("foo.py") - self.assertEqual(statements, [99, 999, 9999]) - self.assertEqual(missing, [99, 9999]) + assert statements == [99, 999, 9999] + assert missing == [99, 9999] # The completely missing file is in the results. _, statements, missing, _ = cov.analysis("chimera.py") - self.assertEqual(statements, [99, 999, 9999]) - self.assertEqual(missing, [99, 999, 9999]) + assert statements == [99, 999, 9999] + assert missing == [99, 999, 9999] # But completely new filenames are not in the results. - self.assertEqual(len(cov.get_data().measured_files()), 3) - with self.assertRaises(CoverageException): + assert len(cov.get_data().measured_files()) == 3 + with pytest.raises(CoverageException): cov.analysis("fictional.py") @@ -641,7 +642,7 @@ class BadFileTracerTest(FileTracerTest): if our_error: errors = stderr.count("# Oh noes!") # The exception we're causing should only appear once. - self.assertEqual(errors, 1) + assert errors == 1 # There should be a warning explaining what's happening, but only one. # The message can be in two forms: @@ -650,12 +651,12 @@ class BadFileTracerTest(FileTracerTest): # Disabling plug-in '...' due to an exception: msg = "Disabling plug-in '%s.%s' due to " % (module_name, plugin_name) warnings = stderr.count(msg) - self.assertEqual(warnings, 1) + assert warnings == 1 if excmsg: - self.assertIn(excmsg, stderr) + assert excmsg in stderr if excmsgs: - self.assertTrue(any(em in stderr for em in excmsgs), "expected one of %r" % excmsgs) + assert any(em in stderr for em in excmsgs), "expected one of %r" % excmsgs def test_file_tracer_has_no_file_tracer_method(self): self.make_file("bad_plugin.py", """\ @@ -703,7 +704,7 @@ class BadFileTracerTest(FileTracerTest): """) cov = self.run_plugin("bad_plugin") expected_msg = "Plugin 'bad_plugin.Plugin' needs to implement file_reporter()" - with self.assertRaisesRegex(NotImplementedError, expected_msg): + with pytest.raises(NotImplementedError, match=expected_msg): cov.report() def test_file_tracer_fails(self): @@ -942,8 +943,8 @@ class ConfigurerPluginTest(CoverageTest): cov.start() cov.stop() # pragma: nested excluded = cov.get_option("report:exclude_lines") - self.assertIn("pragma: custom", excluded) - self.assertIn("pragma: or whatever", excluded) + assert "pragma: custom" in excluded + assert "pragma: or whatever" in excluded class DynamicContextPluginTest(CoverageTest): @@ -1048,16 +1049,14 @@ class DynamicContextPluginTest(CoverageTest): # Labeled coverage is collected data = cov.get_data() filenames = self.get_measured_filenames(data) - self.assertEqual( - ['', 'doctest:HTML_TAG', 'test:HTML_TAG', 'test:RENDERERS'], - sorted(data.measured_contexts()), - ) + assert ['', 'doctest:HTML_TAG', 'test:HTML_TAG', 'test:RENDERERS'] == \ + sorted(data.measured_contexts()) data.set_query_context("doctest:HTML_TAG") - self.assertEqual([2], data.lines(filenames['rendering.py'])) + assert [2] == data.lines(filenames['rendering.py']) data.set_query_context("test:HTML_TAG") - self.assertEqual([2], data.lines(filenames['rendering.py'])) + assert [2] == data.lines(filenames['rendering.py']) data.set_query_context("test:RENDERERS") - self.assertEqual([2, 5, 8, 11], sorted(data.lines(filenames['rendering.py']))) + assert [2, 5, 8, 11] == sorted(data.lines(filenames['rendering.py'])) def test_static_context(self): self.make_plugin_capitalized_testnames('plugin_tests.py') @@ -1078,7 +1077,7 @@ class DynamicContextPluginTest(CoverageTest): 'mytests|test:HTML_TAG', 'mytests|test:RENDERERS', ] - self.assertEqual(expected, sorted(data.measured_contexts())) + assert expected == sorted(data.measured_contexts()) def test_plugin_with_test_function(self): self.make_plugin_capitalized_testnames('plugin_tests.py') @@ -1103,11 +1102,11 @@ class DynamicContextPluginTest(CoverageTest): 'testsuite.test_html_tag', 'testsuite.test_renderers', ] - self.assertEqual(expected, sorted(data.measured_contexts())) + assert expected == sorted(data.measured_contexts()) def assert_context_lines(context, lines): data.set_query_context(context) - self.assertEqual(lines, sorted(data.lines(filenames['rendering.py']))) + assert lines == sorted(data.lines(filenames['rendering.py'])) assert_context_lines("doctest:HTML_TAG", [2]) assert_context_lines("testsuite.test_html_tag", [2]) @@ -1141,11 +1140,11 @@ class DynamicContextPluginTest(CoverageTest): 'test:HTML_TAG', 'test:RENDERERS', ] - self.assertEqual(expected, sorted(data.measured_contexts())) + assert expected == sorted(data.measured_contexts()) def assert_context_lines(context, lines): data.set_query_context(context) - self.assertEqual(lines, sorted(data.lines(filenames['rendering.py']))) + assert lines == sorted(data.lines(filenames['rendering.py'])) assert_context_lines("test:HTML_TAG", [2]) assert_context_lines("test:RENDERERS", [2, 5, 8, 11]) diff --git a/tests/test_process.py b/tests/test_process.py index b44147a3..8362c1e1 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -52,7 +52,7 @@ class ProcessTest(CoverageTest): self.assert_doesnt_exist(".coverage") out = self.run_command("coverage run mycode.py") self.assert_exists(".coverage") - self.assertEqual(out, 'done\n') + assert out == 'done\n' def make_b_or_c_py(self): """Create b_or_c.py, used in a few of these tests.""" @@ -74,12 +74,12 @@ class ProcessTest(CoverageTest): def test_combine_parallel_data(self): self.make_b_or_c_py() out = self.run_command("coverage run -p b_or_c.py b") - self.assertEqual(out, 'done\n') + assert out == 'done\n' self.assert_doesnt_exist(".coverage") self.assert_file_count(".coverage.*", 1) out = self.run_command("coverage run -p b_or_c.py c") - self.assertEqual(out, 'done\n') + assert out == 'done\n' self.assert_doesnt_exist(".coverage") # After two -p runs, there should be two .coverage.machine.123 files. @@ -96,28 +96,28 @@ class ProcessTest(CoverageTest): # executed. data = coverage.CoverageData() data.read() - self.assertEqual(line_counts(data)['b_or_c.py'], 8) + assert line_counts(data)['b_or_c.py'] == 8 # Running combine again should fail, because there are no parallel data # files to combine. status, out = self.run_command_status("coverage combine") - self.assertEqual(status, 1) - self.assertEqual(out, "No data to combine\n") + assert status == 1 + assert out == "No data to combine\n" # And the originally combined data is still there. data = coverage.CoverageData() data.read() - self.assertEqual(line_counts(data)['b_or_c.py'], 8) + assert line_counts(data)['b_or_c.py'] == 8 def test_combine_parallel_data_with_a_corrupt_file(self): self.make_b_or_c_py() out = self.run_command("coverage run -p b_or_c.py b") - self.assertEqual(out, 'done\n') + assert out == 'done\n' self.assert_doesnt_exist(".coverage") self.assert_file_count(".coverage.*", 1) out = self.run_command("coverage run -p b_or_c.py c") - self.assertEqual(out, 'done\n') + assert out == 'done\n' self.assert_doesnt_exist(".coverage") # After two -p runs, there should be two .coverage.machine.123 files. @@ -134,7 +134,7 @@ class ProcessTest(CoverageTest): r"Coverage.py warning: Couldn't use data file '.*\.coverage\.bad': " r"file (is encrypted or )?is not a database" ) - self.assertRegex(out, warning_regex) + assert re.search(warning_regex, out) # After combining, those two should be the only data files. self.assert_file_count(".coverage.*", 1) @@ -143,13 +143,13 @@ class ProcessTest(CoverageTest): # executed. data = coverage.CoverageData() data.read() - self.assertEqual(line_counts(data)['b_or_c.py'], 8) + assert line_counts(data)['b_or_c.py'] == 8 def test_combine_no_usable_files(self): # https://github.com/nedbat/coveragepy/issues/629 self.make_b_or_c_py() out = self.run_command("coverage run b_or_c.py b") - self.assertEqual(out, 'done\n') + assert out == 'done\n' self.assert_exists(".coverage") self.assert_file_count(".coverage.*", 0) @@ -159,7 +159,7 @@ class ProcessTest(CoverageTest): # Combine the parallel coverage data files into .coverage, but nothing is readable. status, out = self.run_command_status("coverage combine") - self.assertEqual(status, 1) + assert status == 1 for n in "12": self.assert_exists(".coverage.bad{}".format(n)) @@ -168,8 +168,8 @@ class ProcessTest(CoverageTest): r"file (is encrypted or )?is not a database" .format(n) ) - self.assertRegex(out, warning_regex) - self.assertRegex(out, r"No usable data files") + assert re.search(warning_regex, out) + assert re.search(r"No usable data files", out) # After combining, we should have a main file and two parallel files. self.assert_exists(".coverage") @@ -179,13 +179,13 @@ class ProcessTest(CoverageTest): # executed (we only did b, not c). data = coverage.CoverageData() data.read() - self.assertEqual(line_counts(data)['b_or_c.py'], 6) + assert line_counts(data)['b_or_c.py'] == 6 def test_combine_parallel_data_in_two_steps(self): self.make_b_or_c_py() out = self.run_command("coverage run -p b_or_c.py b") - self.assertEqual(out, 'done\n') + assert out == 'done\n' self.assert_doesnt_exist(".coverage") self.assert_file_count(".coverage.*", 1) @@ -195,7 +195,7 @@ class ProcessTest(CoverageTest): self.assert_file_count(".coverage.*", 0) out = self.run_command("coverage run -p b_or_c.py c") - self.assertEqual(out, 'done\n') + assert out == 'done\n' self.assert_exists(".coverage") self.assert_file_count(".coverage.*", 1) @@ -210,13 +210,13 @@ class ProcessTest(CoverageTest): # executed. data = coverage.CoverageData() data.read() - self.assertEqual(line_counts(data)['b_or_c.py'], 8) + assert line_counts(data)['b_or_c.py'] == 8 def test_combine_parallel_data_no_append(self): self.make_b_or_c_py() out = self.run_command("coverage run -p b_or_c.py b") - self.assertEqual(out, 'done\n') + assert out == 'done\n' self.assert_doesnt_exist(".coverage") self.assert_file_count(".coverage.*", 1) @@ -226,7 +226,7 @@ class ProcessTest(CoverageTest): self.assert_file_count(".coverage.*", 0) out = self.run_command("coverage run -p b_or_c.py c") - self.assertEqual(out, 'done\n') + assert out == 'done\n' self.assert_exists(".coverage") self.assert_file_count(".coverage.*", 1) @@ -242,17 +242,17 @@ class ProcessTest(CoverageTest): # because we didn't keep the data from running b. data = coverage.CoverageData() data.read() - self.assertEqual(line_counts(data)['b_or_c.py'], 7) + assert line_counts(data)['b_or_c.py'] == 7 def test_combine_parallel_data_keep(self): self.make_b_or_c_py() out = self.run_command("coverage run -p b_or_c.py b") - self.assertEqual(out, 'done\n') + assert out == 'done\n' self.assert_doesnt_exist(".coverage") self.assert_file_count(".coverage.*", 1) out = self.run_command("coverage run -p b_or_c.py c") - self.assertEqual(out, 'done\n') + assert out == 'done\n' self.assert_doesnt_exist(".coverage") # After two -p runs, there should be two .coverage.machine.123 files. @@ -270,12 +270,12 @@ class ProcessTest(CoverageTest): self.make_b_or_c_py() out = self.run_command("coverage run b_or_c.py b") - self.assertEqual(out, 'done\n') + assert out == 'done\n' self.assert_exists(".coverage") self.assert_file_count(".coverage.*", 0) out = self.run_command("coverage run --append b_or_c.py c") - self.assertEqual(out, 'done\n') + assert out == 'done\n' self.assert_exists(".coverage") self.assert_file_count(".coverage.*", 0) @@ -283,7 +283,7 @@ class ProcessTest(CoverageTest): # executed. data = coverage.CoverageData() data.read() - self.assertEqual(line_counts(data)['b_or_c.py'], 8) + assert line_counts(data)['b_or_c.py'] == 8 def test_append_data_with_different_file(self): self.make_b_or_c_py() @@ -294,12 +294,12 @@ class ProcessTest(CoverageTest): """) out = self.run_command("coverage run b_or_c.py b") - self.assertEqual(out, 'done\n') + assert out == 'done\n' self.assert_doesnt_exist(".coverage") self.assert_exists(".mycovdata") out = self.run_command("coverage run --append b_or_c.py c") - self.assertEqual(out, 'done\n') + assert out == 'done\n' self.assert_doesnt_exist(".coverage") self.assert_exists(".mycovdata") @@ -307,13 +307,13 @@ class ProcessTest(CoverageTest): # executed. data = coverage.CoverageData(".mycovdata") data.read() - self.assertEqual(line_counts(data)['b_or_c.py'], 8) + assert line_counts(data)['b_or_c.py'] == 8 def test_append_can_create_a_data_file(self): self.make_b_or_c_py() out = self.run_command("coverage run --append b_or_c.py b") - self.assertEqual(out, 'done\n') + assert out == 'done\n' self.assert_exists(".coverage") self.assert_file_count(".coverage.*", 0) @@ -321,7 +321,7 @@ class ProcessTest(CoverageTest): # executed. data = coverage.CoverageData() data.read() - self.assertEqual(line_counts(data)['b_or_c.py'], 6) + assert line_counts(data)['b_or_c.py'] == 6 def test_combine_with_rc(self): self.make_b_or_c_py() @@ -333,11 +333,11 @@ class ProcessTest(CoverageTest): """) out = self.run_command("coverage run b_or_c.py b") - self.assertEqual(out, 'done\n') + assert out == 'done\n' self.assert_doesnt_exist(".coverage") out = self.run_command("coverage run b_or_c.py c") - self.assertEqual(out, 'done\n') + assert out == 'done\n' self.assert_doesnt_exist(".coverage") # After two runs, there should be two .coverage.machine.123 files. @@ -355,17 +355,17 @@ class ProcessTest(CoverageTest): # executed. data = coverage.CoverageData() data.read() - self.assertEqual(line_counts(data)['b_or_c.py'], 8) + assert line_counts(data)['b_or_c.py'] == 8 # Reporting should still work even with the .rc file out = self.run_command("coverage report") - self.assertMultiLineEqual(out, textwrap.dedent("""\ + assert out == textwrap.dedent("""\ Name Stmts Miss Cover ------------------------------- b_or_c.py 8 0 100% ------------------------------- TOTAL 8 0 100% - """)) + """) def test_combine_with_aliases(self): self.make_file("d1/x.py", """\ @@ -396,9 +396,9 @@ class ProcessTest(CoverageTest): """) out = self.run_command("coverage run " + os.path.normpath("d1/x.py")) - self.assertEqual(out, '1 2\n') + assert out == '1 2\n' out = self.run_command("coverage run " + os.path.normpath("d2/x.py")) - self.assertEqual(out, '4 5\n') + assert out == '4 5\n' self.assert_file_count(".coverage.*", 2) @@ -413,11 +413,11 @@ class ProcessTest(CoverageTest): data = coverage.CoverageData() data.read() summary = line_counts(data, fullpath=True) - self.assertEqual(len(summary), 1) + assert len(summary) == 1 actual = abs_file(list(summary.keys())[0]) expected = abs_file('src/x.py') - self.assertEqual(expected, actual) - self.assertEqual(list(summary.values())[0], 6) + assert expected == actual + assert list(summary.values())[0] == 6 def test_erase_parallel(self): self.make_file(".coveragerc", """\ @@ -445,8 +445,8 @@ class ProcessTest(CoverageTest): self.run_command("coverage run fleeting.py") os.remove("fleeting.py") out = self.run_command("coverage html -d htmlcov") - self.assertRegex(out, "No source for code: '.*fleeting.py'") - self.assertNotIn("Traceback", out) + assert re.search("No source for code: '.*fleeting.py'", out) + assert "Traceback" not in out # It happens that the code paths are different for *.py and other # files, so try again with no extension. @@ -457,16 +457,16 @@ class ProcessTest(CoverageTest): self.run_command("coverage run fleeting") os.remove("fleeting") status, out = self.run_command_status("coverage html -d htmlcov") - self.assertRegex(out, "No source for code: '.*fleeting'") - self.assertNotIn("Traceback", out) - self.assertEqual(status, 1) + assert re.search("No source for code: '.*fleeting'", out) + assert "Traceback" not in out + assert status == 1 def test_running_missing_file(self): status, out = self.run_command_status("coverage run xyzzy.py") - self.assertRegex(out, "No file to run: .*xyzzy.py") - self.assertNotIn("raceback", out) - self.assertNotIn("rror", out) - self.assertEqual(status, 1) + assert re.search("No file to run: .*xyzzy.py", out) + assert "raceback" not in out + assert "rror" not in out + assert status == 1 def test_code_throws(self): self.make_file("throw.py", """\ @@ -486,14 +486,14 @@ class ProcessTest(CoverageTest): if env.PYPY: # Pypy has an extra frame in the traceback for some reason out2 = re_lines(out2, "toplevel", match=False) - self.assertMultiLineEqual(out, out2) + assert out == out2 # But also make sure that the output is what we expect. path = python_reported_file('throw.py') msg = 'File "{}", line 5,? in f2'.format(re.escape(path)) - self.assertRegex(out, msg) - self.assertIn('raise Exception("hey!")', out) - self.assertEqual(status, 1) + assert re.search(msg, out) + assert 'raise Exception("hey!")' in out + assert status == 1 def test_code_exits(self): self.make_file("exit.py", """\ @@ -512,10 +512,10 @@ class ProcessTest(CoverageTest): # same output. No traceback. status, out = self.run_command_status("coverage run exit.py") status2, out2 = self.run_command_status("python exit.py") - self.assertMultiLineEqual(out, out2) - self.assertMultiLineEqual(out, "about to exit..\n") - self.assertEqual(status, status2) - self.assertEqual(status, 17) + assert out == out2 + assert out == "about to exit..\n" + assert status == status2 + assert status == 17 def test_code_exits_no_arg(self): self.make_file("exit_none.py", """\ @@ -528,10 +528,10 @@ class ProcessTest(CoverageTest): """) status, out = self.run_command_status("coverage run exit_none.py") status2, out2 = self.run_command_status("python exit_none.py") - self.assertMultiLineEqual(out, out2) - self.assertMultiLineEqual(out, "about to exit quietly..\n") - self.assertEqual(status, status2) - self.assertEqual(status, 0) + assert out == out2 + assert out == "about to exit quietly..\n" + assert status == status2 + assert status == 0 def test_fork(self): if not hasattr(os, 'fork'): @@ -555,7 +555,7 @@ class ProcessTest(CoverageTest): """) out = self.run_command("coverage run -p fork.py") - self.assertEqual(out, 'Child!\n') + assert out == 'Child!\n' self.assert_doesnt_exist(".coverage") # After running the forking program, there should be two @@ -566,7 +566,7 @@ class ProcessTest(CoverageTest): # the file name. data_files = glob.glob(".coverage.*") nums = set(name.rpartition(".")[-1] for name in data_files) - self.assertEqual(len(nums), 2, "Same random: %s" % (data_files,)) + assert len(nums) == 2, "Same random: %s" % (data_files,) # Combine the parallel coverage data files into .coverage . self.run_command("coverage combine") @@ -577,7 +577,7 @@ class ProcessTest(CoverageTest): data = coverage.CoverageData() data.read() - self.assertEqual(line_counts(data)['fork.py'], 9) + assert line_counts(data)['fork.py'] == 9 def test_warnings_during_reporting(self): # While fixing issue #224, the warnings were being printed far too @@ -598,7 +598,7 @@ class ProcessTest(CoverageTest): self.run_command("coverage run hello.py") out = self.run_command("coverage html") - self.assertEqual(out.count("Module xyzzy was never imported."), 0) + assert out.count("Module xyzzy was never imported.") == 0 def test_warns_if_never_run(self): # Note: the name of the function can't have "warning" in it, or the @@ -606,17 +606,15 @@ class ProcessTest(CoverageTest): # will fail. out = self.run_command("coverage run i_dont_exist.py") path = python_reported_file('i_dont_exist.py') - self.assertIn("No file to run: '{}'".format(path), out) - self.assertNotIn("warning", out) - self.assertNotIn("Exception", out) + assert "No file to run: '{}'".format(path) in out + assert "warning" not in out + assert "Exception" not in out out = self.run_command("coverage run -m no_such_module") - self.assertTrue( - ("No module named no_such_module" in out) or + assert ("No module named no_such_module" in out) or \ ("No module named 'no_such_module'" in out) - ) - self.assertNotIn("warning", out) - self.assertNotIn("Exception", out) + assert "warning" not in out + assert "Exception" not in out def test_warnings_trace_function_changed_with_threads(self): # https://github.com/nedbat/coveragepy/issues/164 @@ -637,8 +635,8 @@ class ProcessTest(CoverageTest): """) out = self.run_command("coverage run --timid bug164.py") - self.assertIn("Hello\n", out) - self.assertNotIn("warning", out) + assert "Hello\n" in out + assert "warning" not in out def test_warning_trace_function_changed(self): self.make_file("settrace.py", """\ @@ -648,10 +646,10 @@ class ProcessTest(CoverageTest): print("Goodbye") """) out = self.run_command("coverage run --timid settrace.py") - self.assertIn("Hello\n", out) - self.assertIn("Goodbye\n", out) + assert "Hello\n" in out + assert "Goodbye\n" in out - self.assertIn("Trace function changed", out) + assert "Trace function changed" in out def test_timid(self): # Test that the --timid command line argument properly swaps the tracer @@ -696,21 +694,21 @@ class ProcessTest(CoverageTest): # When running without coverage, no trace function py_out = self.run_command("python showtrace.py") - self.assertEqual(py_out, "None\n") + assert py_out == "None\n" cov_out = self.run_command("coverage run showtrace.py") if os.environ.get('COVERAGE_TEST_TRACER', 'c') == 'c': # If the C trace function is being tested, then regular running should have # the C function, which registers itself as f_trace. - self.assertEqual(cov_out, "CTracer\n") + assert cov_out == "CTracer\n" else: # If the Python trace function is being tested, then regular running will # also show the Python function. - self.assertEqual(cov_out, "PyTracer\n") + assert cov_out == "PyTracer\n" # When running timidly, the trace function is always Python. timid_out = self.run_command("coverage run --timid showtrace.py") - self.assertEqual(timid_out, "PyTracer\n") + assert timid_out == "PyTracer\n" def test_warn_preimported(self): self.make_file("hello.py", """\ @@ -728,13 +726,13 @@ class ProcessTest(CoverageTest): goodbye_path = os.path.abspath("goodbye.py") out = self.run_command("python hello.py") - self.assertIn("Goodbye!", out) + assert "Goodbye!" in out msg = ( "Coverage.py warning: " "Already imported a file that will be measured: {0} " "(already-imported)").format(goodbye_path) - self.assertIn(msg, out) + assert msg in out @pytest.mark.expensive def test_fullcoverage(self): # pragma: no metacov @@ -758,13 +756,13 @@ class ProcessTest(CoverageTest): self.set_environ("FOOEY", "BOO") self.set_environ("PYTHONPATH", fullcov) out = self.run_command("python -m coverage run -L getenv.py") - self.assertEqual(out, "FOOEY == BOO\n") + assert out == "FOOEY == BOO\n" data = coverage.CoverageData() data.read() # The actual number of executed lines in os.py when it's # imported is 120 or so. Just running os.getenv executes # about 5. - self.assertGreater(line_counts(data)['os.py'], 50) + assert line_counts(data)['os.py'] > 50 @xfail( env.PYPY3 and (env.PYPYVERSION >= (7, 1, 1)), @@ -788,7 +786,7 @@ class ProcessTest(CoverageTest): """) self.set_environ("LANG", "C") out = self.run_command("coverage run weird_file.py") - self.assertEqual(out, "1\n2\n") + assert out == "1\n2\n" def test_deprecation_warnings(self): # Test that coverage doesn't trigger deprecation warnings. @@ -805,7 +803,7 @@ class ProcessTest(CoverageTest): self.del_environ("COVERAGE_TESTING") out = self.run_command("python allok.py") - self.assertEqual(out, "No warnings!\n") + assert out == "No warnings!\n" def test_run_twice(self): # https://github.com/nedbat/coveragepy/issues/353 @@ -827,18 +825,16 @@ class ProcessTest(CoverageTest): inst.save() """) out = self.run_command("python run_twice.py") - self.assertEqual( - out, - "Run 1\n" - "Run 2\n" - "Coverage.py warning: Module foo was previously imported, but not measured " + assert out == \ + "Run 1\n" \ + "Run 2\n" \ + "Coverage.py warning: Module foo was previously imported, but not measured " \ "(module-not-measured)\n" - ) def test_module_name(self): # https://github.com/nedbat/coveragepy/issues/478 out = self.run_command("python -m coverage") - self.assertIn("Use 'coverage help' for help", out) + assert "Use 'coverage help' for help" in out TRY_EXECFILE = os.path.join(os.path.dirname(__file__), "modules/process_test/try_execfile.py") @@ -854,14 +850,14 @@ class EnvironmentTest(CoverageTest): """ # First, is this even credible try_execfile.py output? - self.assertIn('"DATA": "xyzzy"', actual) + assert '"DATA": "xyzzy"' in actual if env.JYTHON: # pragma: only jython # Argv0 is different for Jython, remove that from the comparison. expected = re_lines(expected, r'\s+"argv0":', match=False) actual = re_lines(actual, r'\s+"argv0":', match=False) - self.assertMultiLineEqual(expected, actual) + assert expected == actual def test_coverage_run_is_like_python(self): with open(TRY_EXECFILE) as f: @@ -958,8 +954,8 @@ class EnvironmentTest(CoverageTest): self.assert_tryexecfile_output(expected, actual) st, out = self.run_command_status("coverage report") - self.assertEqual(st, 0) - self.assertEqual(self.line_count(out), 6, out) + assert st == 0 + assert self.line_count(out) == 6, out def test_coverage_run_script_imports_doubledashsource(self): # This file imports try_execfile, which compiles it to .pyc, so the @@ -977,8 +973,8 @@ class EnvironmentTest(CoverageTest): self.assert_tryexecfile_output(expected, actual) st, out = self.run_command_status("coverage report") - self.assertEqual(st, 0) - self.assertEqual(self.line_count(out), 6, out) + assert st == 0 + assert self.line_count(out) == 6, out def test_coverage_run_dashm_is_like_python_dashm_off_path(self): # https://github.com/nedbat/coveragepy/issues/242 @@ -996,7 +992,7 @@ class EnvironmentTest(CoverageTest): self.make_file("package/__main__.py", "print('main')") expected = self.run_command("python -m package") actual = self.run_command("coverage run -m package") - self.assertMultiLineEqual(expected, actual) + assert expected == actual def test_coverage_zip_is_like_python(self): # Test running coverage from a zip file itself. Some environments @@ -1037,10 +1033,10 @@ class EnvironmentTest(CoverageTest): """) # If this test fails, it will be with "can't import thing". out = self.run_command("python run_coverage.py run how_is_it.py") - self.assertIn("hello-xyzzy", out) + assert "hello-xyzzy" in out out = self.run_command("python -m run_coverage run how_is_it.py") - self.assertIn("hello-xyzzy", out) + assert "hello-xyzzy" in out def test_bug_862(self): if env.WINDOWS: @@ -1057,7 +1053,7 @@ class EnvironmentTest(CoverageTest): self.make_file("foo.py", "print('inside foo')") self.make_file("bar.py", "import foo") out = self.run_command("somewhere/bin/fake-coverage run bar.py") - self.assertEqual("inside foo\n", out) + assert "inside foo\n" == out def test_bug_909(self): # https://github.com/nedbat/coveragepy/issues/909 @@ -1108,17 +1104,17 @@ class ExcepthookTest(CoverageTest): cov_st, cov_out = self.run_command_status("coverage run excepthook.py") py_st, py_out = self.run_command_status("python excepthook.py") if not env.JYTHON: - self.assertEqual(cov_st, py_st) - self.assertEqual(cov_st, 1) + assert cov_st == py_st + assert cov_st == 1 - self.assertIn("in excepthook", py_out) - self.assertEqual(cov_out, py_out) + assert "in excepthook" in py_out + assert cov_out == py_out # Read the coverage file and see that excepthook.py has 7 lines # executed. data = coverage.CoverageData() data.read() - self.assertEqual(line_counts(data)['excepthook.py'], 7) + assert line_counts(data)['excepthook.py'] == 7 def test_excepthook_exit(self): if not env.CPYTHON: @@ -1136,11 +1132,11 @@ class ExcepthookTest(CoverageTest): """) cov_st, cov_out = self.run_command_status("coverage run excepthook_exit.py") py_st, py_out = self.run_command_status("python excepthook_exit.py") - self.assertEqual(cov_st, py_st) - self.assertEqual(cov_st, 0) + assert cov_st == py_st + assert cov_st == 0 - self.assertIn("in excepthook", py_out) - self.assertEqual(cov_out, py_out) + assert "in excepthook" in py_out + assert cov_out == py_out def test_excepthook_throw(self): if env.PYPY: @@ -1162,11 +1158,11 @@ class ExcepthookTest(CoverageTest): cov_st, cov_out = self.run_command_status("coverage run excepthook_throw.py") py_st, py_out = self.run_command_status("python excepthook_throw.py") if not env.JYTHON: - self.assertEqual(cov_st, py_st) - self.assertEqual(cov_st, 1) + assert cov_st == py_st + assert cov_st == 1 - self.assertIn("in excepthook", py_out) - self.assertEqual(cov_out, py_out) + assert "in excepthook" in py_out + assert cov_out == py_out class AliasedCommandTest(CoverageTest): @@ -1183,20 +1179,20 @@ class AliasedCommandTest(CoverageTest): # "coverage2" works on py2 cmd = "coverage%d" % sys.version_info[0] out = self.run_command(cmd) - self.assertIn("Code coverage for Python", out) + assert "Code coverage for Python" in out def test_wrong_alias_doesnt_work(self): # "coverage3" doesn't work on py2 assert sys.version_info[0] in [2, 3] # Let us know when Python 4 is out... badcmd = "coverage%d" % (5 - sys.version_info[0]) out = self.run_command(badcmd) - self.assertNotIn("Code coverage for Python", out) + assert "Code coverage for Python" not in out def test_specific_alias_works(self): # "coverage-2.7" works on py2.7 cmd = "coverage-%d.%d" % sys.version_info[:2] out = self.run_command(cmd) - self.assertIn("Code coverage for Python", out) + assert "Code coverage for Python" in out def test_aliases_used_in_messages(self): cmds = [ @@ -1206,8 +1202,8 @@ class AliasedCommandTest(CoverageTest): ] for cmd in cmds: out = self.run_command("%s foobar" % cmd) - self.assertIn("Unknown command: 'foobar'", out) - self.assertIn("Use '%s help' for help" % cmd, out) + assert "Unknown command: 'foobar'" in out + assert "Use '%s help' for help" % cmd in out class PydocTest(CoverageTest): @@ -1221,11 +1217,11 @@ class PydocTest(CoverageTest): out = self.run_command("python -m pydoc " + name) # It should say "Help on..", and not have a traceback self.assert_starts_with(out, "Help on ") - self.assertNotIn("Traceback", out) + assert "Traceback" not in out # All of the lines in the docstring should be there somewhere. for line in thing.__doc__.splitlines(): - self.assertIn(line.strip(), out) + assert line.strip() in out def test_pydoc_coverage(self): self.assert_pydoc_ok("coverage", coverage) @@ -1250,29 +1246,25 @@ class FailUnderTest(CoverageTest): e = 7 """) st, _ = self.run_command_status("coverage run --source=. forty_two_plus.py") - self.assertEqual(st, 0) + assert st == 0 def test_report_43_is_ok(self): st, out = self.run_command_status("coverage report --fail-under=43") - self.assertEqual(st, 0) - self.assertEqual(self.last_line_squeezed(out), "TOTAL 7 4 43%") + assert st == 0 + assert self.last_line_squeezed(out) == "TOTAL 7 4 43%" def test_report_43_is_not_ok(self): st, out = self.run_command_status("coverage report --fail-under=44") - self.assertEqual(st, 2) - self.assertEqual( - self.last_line_squeezed(out), + assert st == 2 + assert self.last_line_squeezed(out) == \ "Coverage failure: total of 43 is less than fail-under=44" - ) def test_report_42p86_is_not_ok(self): self.make_file(".coveragerc", "[report]\nprecision = 2") st, out = self.run_command_status("coverage report --fail-under=42.88") - self.assertEqual(st, 2) - self.assertEqual( - self.last_line_squeezed(out), + assert st == 2 + assert self.last_line_squeezed(out) == \ "Coverage failure: total of 42.86 is less than fail-under=42.88" - ) class FailUnderNoFilesTest(CoverageTest): @@ -1280,8 +1272,8 @@ class FailUnderNoFilesTest(CoverageTest): def test_report(self): self.make_file(".coveragerc", "[report]\nfail_under = 99\n") st, out = self.run_command_status("coverage report") - self.assertIn('No data to report.', out) - self.assertEqual(st, 1) + assert 'No data to report.' in out + assert st == 1 class FailUnderEmptyFilesTest(CoverageTest): @@ -1290,9 +1282,9 @@ class FailUnderEmptyFilesTest(CoverageTest): self.make_file(".coveragerc", "[report]\nfail_under = 99\n") self.make_file("empty.py", "") st, _ = self.run_command_status("coverage run empty.py") - self.assertEqual(st, 0) + assert st == 0 st, _ = self.run_command_status("coverage report") - self.assertEqual(st, 2) + assert st == 2 class UnicodeFilePathsTest(CoverageTest): @@ -1307,23 +1299,23 @@ class UnicodeFilePathsTest(CoverageTest): # Make a file with a non-ascii character in the filename. self.make_file(u"h\xe2t.py", "print('accented')") out = self.run_command(u"coverage run --source=. h\xe2t.py") - self.assertEqual(out, "accented\n") + assert out == "accented\n" # The HTML report uses ascii-encoded HTML entities. out = self.run_command("coverage html") - self.assertEqual(out, "") + assert out == "" self.assert_exists(u"htmlcov/h\xe2t_py.html") with open("htmlcov/index.html") as indexf: index = indexf.read() - self.assertIn('hât.py', index) + assert 'hât.py' in index # The XML report is always UTF8-encoded. out = self.run_command("coverage xml") - self.assertEqual(out, "") + assert out == "" with open("coverage.xml", "rb") as xmlf: xml = xmlf.read() - self.assertIn(u' filename="h\xe2t.py"'.encode('utf8'), xml) - self.assertIn(u' name="h\xe2t.py"'.encode('utf8'), xml) + assert u' filename="h\xe2t.py"'.encode('utf8') in xml + assert u' name="h\xe2t.py"'.encode('utf8') in xml report_expected = ( u"Name Stmts Miss Cover\n" @@ -1337,29 +1329,29 @@ class UnicodeFilePathsTest(CoverageTest): report_expected = report_expected.encode(output_encoding()) out = self.run_command("coverage report") - self.assertEqual(out, report_expected) + assert out == report_expected def test_accented_directory(self): # Make a file with a non-ascii character in the directory name. self.make_file(u"\xe2/accented.py", "print('accented')") out = self.run_command(u"coverage run --source=. \xe2/accented.py") - self.assertEqual(out, "accented\n") + assert out == "accented\n" # The HTML report uses ascii-encoded HTML entities. out = self.run_command("coverage html") - self.assertEqual(out, "") + assert out == "" self.assert_exists(u"htmlcov/\xe2_accented_py.html") with open("htmlcov/index.html") as indexf: index = indexf.read() - self.assertIn('â%saccented.py' % os.sep, index) + assert 'â%saccented.py' % os.sep in index # The XML report is always UTF8-encoded. out = self.run_command("coverage xml") - self.assertEqual(out, "") + assert out == "" with open("coverage.xml", "rb") as xmlf: xml = xmlf.read() - self.assertIn(b' filename="\xc3\xa2/accented.py"', xml) - self.assertIn(b' name="accented.py"', xml) + assert b' filename="\xc3\xa2/accented.py"' in xml + assert b' name="accented.py"' in xml dom = ElementTree.parse("coverage.xml") elts = dom.findall(u".//package[@name='â']") @@ -1383,7 +1375,7 @@ class UnicodeFilePathsTest(CoverageTest): report_expected = report_expected.encode(output_encoding()) out = self.run_command("coverage report") - self.assertEqual(out, report_expected) + assert out == report_expected class YankedDirectoryTest(CoverageTest): @@ -1408,18 +1400,18 @@ class YankedDirectoryTest(CoverageTest): def test_removing_directory(self): self.make_file("bug806.py", self.BUG_806) out = self.run_command("coverage run bug806.py noerror") - self.assertEqual(out, "noerror\n") + assert out == "noerror\n" def test_removing_directory_with_error(self): self.make_file("bug806.py", self.BUG_806) out = self.run_command("coverage run bug806.py") path = python_reported_file('bug806.py') - self.assertEqual(out, textwrap.dedent("""\ + assert out == textwrap.dedent("""\ Traceback (most recent call last): File "{}", line 8, in print(sys.argv[1]) IndexError: list index out of range - """.format(path))) + """.format(path)) def possible_pth_dirs(): @@ -1476,7 +1468,7 @@ class ProcessCoverageMixin(object): super(ProcessCoverageMixin, self).setUp() # Create the .pth file. - self.assertTrue(PTH_DIR) + assert PTH_DIR pth_contents = "import coverage; coverage.process_startup()\n" pth_path = os.path.join(PTH_DIR, "subcover_{}.pth".format(WORKER)) with open(pth_path, "w") as pth: @@ -1524,13 +1516,13 @@ class ProcessStartupTest(ProcessCoverageMixin, CoverageTest): import main # pylint: disable=unused-import with open("out.txt") as f: - self.assertEqual(f.read(), "Hello, world!\n") + assert f.read() == "Hello, world!\n" # Read the data from .coverage self.assert_exists(".mycovdata") data = coverage.CoverageData(".mycovdata") data.read() - self.assertEqual(line_counts(data)['sub.py'], 3) + assert line_counts(data)['sub.py'] == 3 def test_subprocess_with_pth_files_and_parallel(self): # pragma: no metacov # https://github.com/nedbat/coveragepy/issues/492 @@ -1546,7 +1538,7 @@ class ProcessStartupTest(ProcessCoverageMixin, CoverageTest): self.run_command("coverage run main.py") with open("out.txt") as f: - self.assertEqual(f.read(), "Hello, world!\n") + assert f.read() == "Hello, world!\n" self.run_command("coverage combine") @@ -1554,13 +1546,13 @@ class ProcessStartupTest(ProcessCoverageMixin, CoverageTest): self.assert_exists(".coverage") data = coverage.CoverageData() data.read() - self.assertEqual(line_counts(data)['sub.py'], 3) + assert line_counts(data)['sub.py'] == 3 # assert that there are *no* extra data files left over after a combine data_files = glob.glob(os.getcwd() + '/.coverage*') - self.assertEqual(len(data_files), 1, - "Expected only .coverage after combine, looks like there are " - "extra data files that were not cleaned up: %r" % data_files) + assert len(data_files) == 1, \ + "Expected only .coverage after combine, looks like there are " \ + "extra data files that were not cleaned up: %r" % data_files class ProcessStartupWithSourceTest(ProcessCoverageMixin, CoverageTest): @@ -1638,7 +1630,7 @@ class ProcessStartupWithSourceTest(ProcessCoverageMixin, CoverageTest): self.run_command(cmd) with open("out.txt") as f: - self.assertEqual(f.read(), "Hello, world!") + assert f.read() == "Hello, world!" # Read the data from .coverage self.assert_exists(".coverage") @@ -1646,8 +1638,8 @@ class ProcessStartupWithSourceTest(ProcessCoverageMixin, CoverageTest): data.read() summary = line_counts(data) print(summary) - self.assertEqual(summary[source + '.py'], 3) - self.assertEqual(len(summary), 1) + assert summary[source + '.py'] == 3 + assert len(summary) == 1 def test_dashm_main(self): self.assert_pth_and_source_work_together('-m', '', 'main') diff --git a/tests/test_python.py b/tests/test_python.py index 441ef499..0175f5af 100644 --- a/tests/test_python.py +++ b/tests/test_python.py @@ -28,7 +28,7 @@ class GetZipBytesTest(CoverageTest): filename = filename.replace("/", os.sep) zip_data = get_zip_bytes(filename) zip_text = zip_data.decode(encoding) - self.assertIn('All OK', zip_text) + assert 'All OK' in zip_text # Run the code to see that we really got it encoded properly. __import__("encoded_"+encoding) diff --git a/tests/test_results.py b/tests/test_results.py index 377c150b..0453424b 100644 --- a/tests/test_results.py +++ b/tests/test_results.py @@ -18,30 +18,30 @@ class NumbersTest(CoverageTest): def test_basic(self): n1 = Numbers(n_files=1, n_statements=200, n_missing=20) - self.assertEqual(n1.n_statements, 200) - self.assertEqual(n1.n_executed, 180) - self.assertEqual(n1.n_missing, 20) - self.assertEqual(n1.pc_covered, 90) + assert n1.n_statements == 200 + assert n1.n_executed == 180 + assert n1.n_missing == 20 + assert n1.pc_covered == 90 def test_addition(self): n1 = Numbers(n_files=1, n_statements=200, n_missing=20) n2 = Numbers(n_files=1, n_statements=10, n_missing=8) n3 = n1 + n2 - self.assertEqual(n3.n_files, 2) - self.assertEqual(n3.n_statements, 210) - self.assertEqual(n3.n_executed, 182) - self.assertEqual(n3.n_missing, 28) - self.assertAlmostEqual(n3.pc_covered, 86.666666666) + assert n3.n_files == 2 + assert n3.n_statements == 210 + assert n3.n_executed == 182 + assert n3.n_missing == 28 + assert round(abs(n3.pc_covered-86.666666666), 7) == 0 def test_sum(self): n1 = Numbers(n_files=1, n_statements=200, n_missing=20) n2 = Numbers(n_files=1, n_statements=10, n_missing=8) n3 = sum([n1, n2]) - self.assertEqual(n3.n_files, 2) - self.assertEqual(n3.n_statements, 210) - self.assertEqual(n3.n_executed, 182) - self.assertEqual(n3.n_missing, 28) - self.assertAlmostEqual(n3.pc_covered, 86.666666666) + assert n3.n_files == 2 + assert n3.n_statements == 210 + assert n3.n_executed == 182 + assert n3.n_missing == 28 + assert round(abs(n3.pc_covered-86.666666666), 7) == 0 def test_pc_covered_str(self): # Numbers._precision is a global, which is bad. @@ -50,10 +50,10 @@ class NumbersTest(CoverageTest): n1 = Numbers(n_files=1, n_statements=1000, n_missing=1) n999 = Numbers(n_files=1, n_statements=1000, n_missing=999) n1000 = Numbers(n_files=1, n_statements=1000, n_missing=1000) - self.assertEqual(n0.pc_covered_str, "100") - self.assertEqual(n1.pc_covered_str, "99") - self.assertEqual(n999.pc_covered_str, "1") - self.assertEqual(n1000.pc_covered_str, "0") + assert n0.pc_covered_str == "100" + assert n1.pc_covered_str == "99" + assert n999.pc_covered_str == "1" + assert n1000.pc_covered_str == "0" def test_pc_covered_str_precision(self): # Numbers._precision is a global, which is bad. @@ -62,21 +62,21 @@ class NumbersTest(CoverageTest): n1 = Numbers(n_files=1, n_statements=10000, n_missing=1) n9999 = Numbers(n_files=1, n_statements=10000, n_missing=9999) n10000 = Numbers(n_files=1, n_statements=10000, n_missing=10000) - self.assertEqual(n0.pc_covered_str, "100.0") - self.assertEqual(n1.pc_covered_str, "99.9") - self.assertEqual(n9999.pc_covered_str, "0.1") - self.assertEqual(n10000.pc_covered_str, "0.0") + assert n0.pc_covered_str == "100.0" + assert n1.pc_covered_str == "99.9" + assert n9999.pc_covered_str == "0.1" + assert n10000.pc_covered_str == "0.0" Numbers.set_precision(0) def test_covered_ratio(self): n = Numbers(n_files=1, n_statements=200, n_missing=47) - self.assertEqual(n.ratio_covered, (153, 200)) + assert n.ratio_covered == (153, 200) n = Numbers( n_files=1, n_statements=200, n_missing=47, n_branches=10, n_missing_branches=3, n_partial_branches=1000, ) - self.assertEqual(n.ratio_covered, (160, 210)) + assert n.ratio_covered == (160, 210) @pytest.mark.parametrize("total, fail_under, precision, result", [ diff --git a/tests/test_setup.py b/tests/test_setup.py index 9ab10391..febc383e 100644 --- a/tests/test_setup.py +++ b/tests/test_setup.py @@ -24,12 +24,12 @@ class SetupPyTest(CoverageTest): status, output = self.run_command_status( "python setup.py --description --version --url --author" ) - self.assertEqual(status, 0) + assert status == 0 out = output.splitlines() - self.assertIn("measurement", out[0]) - self.assertEqual(coverage.__version__, out[1]) - self.assertIn("github.com/nedbat/coveragepy", out[2]) - self.assertIn("Ned Batchelder", out[3]) + assert "measurement" in out[0] + assert coverage.__version__ == out[1] + assert "github.com/nedbat/coveragepy" in out[2] + assert "Ned Batchelder" in out[3] def test_more_metadata(self): # Let's be sure we pick up our own setup.py @@ -38,12 +38,12 @@ class SetupPyTest(CoverageTest): from setup import setup_args classifiers = setup_args['classifiers'] - self.assertGreater(len(classifiers), 7) + assert len(classifiers) > 7 self.assert_starts_with(classifiers[-1], "Development Status ::") - self.assertIn("Programming Language :: Python :: %d" % sys.version_info[:1], classifiers) - self.assertIn("Programming Language :: Python :: %d.%d" % sys.version_info[:2], classifiers) + assert "Programming Language :: Python :: %d" % sys.version_info[:1] in classifiers + assert "Programming Language :: Python :: %d.%d" % sys.version_info[:2] in classifiers long_description = setup_args['long_description'].splitlines() - self.assertGreater(len(long_description), 7) - self.assertNotEqual(long_description[0].strip(), "") - self.assertNotEqual(long_description[-1].strip(), "") + assert len(long_description) > 7 + assert long_description[0].strip() != "" + assert long_description[-1].strip() != "" diff --git a/tests/test_summary.py b/tests/test_summary.py index feaa0fe0..f2c75317 100644 --- a/tests/test_summary.py +++ b/tests/test_summary.py @@ -19,6 +19,7 @@ from coverage.misc import CoverageException, output_encoding from coverage.summary import SummaryReporter from tests.coveragetest import CoverageTest, TESTS_DIR, UsingModulesMixin +import pytest class SummaryTest(UsingModulesMixin, CoverageTest): @@ -44,7 +45,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest): def test_report(self): self.make_mycode() out = self.run_command("coverage run mycode.py") - self.assertEqual(out, 'done\n') + assert out == 'done\n' report = self.report_from_command("coverage report") # Name Stmts Miss Cover @@ -55,11 +56,11 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # ------------------------------------------------------------------ # TOTAL 8 0 100% - self.assertNotIn("/coverage/__init__/", report) - self.assertIn("/tests/modules/covmod1.py ", report) - self.assertIn("/tests/zipmods.zip/covmodzip1.py ", report) - self.assertIn("mycode.py ", report) - self.assertEqual(self.last_line_squeezed(report), "TOTAL 8 0 100%") + assert "/coverage/__init__/" not in report + assert "/tests/modules/covmod1.py " in report + assert "/tests/zipmods.zip/covmodzip1.py " in report + assert "mycode.py " in report + assert self.last_line_squeezed(report) == "TOTAL 8 0 100%" def test_report_just_one(self): # Try reporting just one module @@ -73,12 +74,12 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # ------------------------------- # TOTAL 4 0 100% - self.assertEqual(self.line_count(report), 5) - self.assertNotIn("/coverage/", report) - self.assertNotIn("/tests/modules/covmod1.py ", report) - self.assertNotIn("/tests/zipmods.zip/covmodzip1.py ", report) - self.assertIn("mycode.py ", report) - self.assertEqual(self.last_line_squeezed(report), "TOTAL 4 0 100%") + assert self.line_count(report) == 5 + assert "/coverage/" not in report + assert "/tests/modules/covmod1.py " not in report + assert "/tests/zipmods.zip/covmodzip1.py " not in report + assert "mycode.py " in report + assert self.last_line_squeezed(report) == "TOTAL 4 0 100%" def test_report_wildcard(self): # Try reporting using wildcards to get the modules. @@ -92,12 +93,12 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # ------------------------------- # TOTAL 4 0 100% - self.assertEqual(self.line_count(report), 5) - self.assertNotIn("/coverage/", report) - self.assertNotIn("/tests/modules/covmod1.py ", report) - self.assertNotIn("/tests/zipmods.zip/covmodzip1.py ", report) - self.assertIn("mycode.py ", report) - self.assertEqual(self.last_line_squeezed(report), "TOTAL 4 0 100%") + assert self.line_count(report) == 5 + assert "/coverage/" not in report + assert "/tests/modules/covmod1.py " not in report + assert "/tests/zipmods.zip/covmodzip1.py " not in report + assert "mycode.py " in report + assert self.last_line_squeezed(report) == "TOTAL 4 0 100%" def test_report_omitting(self): # Try reporting while omitting some modules @@ -112,12 +113,12 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # ------------------------------- # TOTAL 4 0 100% - self.assertEqual(self.line_count(report), 5) - self.assertNotIn("/coverage/", report) - self.assertNotIn("/tests/modules/covmod1.py ", report) - self.assertNotIn("/tests/zipmods.zip/covmodzip1.py ", report) - self.assertIn("mycode.py ", report) - self.assertEqual(self.last_line_squeezed(report), "TOTAL 4 0 100%") + assert self.line_count(report) == 5 + assert "/coverage/" not in report + assert "/tests/modules/covmod1.py " not in report + assert "/tests/zipmods.zip/covmodzip1.py " not in report + assert "mycode.py " in report + assert self.last_line_squeezed(report) == "TOTAL 4 0 100%" def test_report_including(self): # Try reporting while including some modules @@ -131,12 +132,12 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # ------------------------------- # TOTAL 4 0 100% - self.assertEqual(self.line_count(report), 5) - self.assertNotIn("/coverage/", report) - self.assertNotIn("/tests/modules/covmod1.py ", report) - self.assertNotIn("/tests/zipmods.zip/covmodzip1.py ", report) - self.assertIn("mycode.py ", report) - self.assertEqual(self.last_line_squeezed(report), "TOTAL 4 0 100%") + assert self.line_count(report) == 5 + assert "/coverage/" not in report + assert "/tests/modules/covmod1.py " not in report + assert "/tests/zipmods.zip/covmodzip1.py " not in report + assert "mycode.py " in report + assert self.last_line_squeezed(report) == "TOTAL 4 0 100%" def test_run_source_vs_report_include(self): # https://github.com/nedbat/coveragepy/issues/621 @@ -170,8 +171,8 @@ class SummaryTest(UsingModulesMixin, CoverageTest): covdata = CoverageData() covdata.read() files = [os.path.basename(p) for p in covdata.measured_files()] - self.assertIn("covmod1.py", files) - self.assertNotIn("covmodzip1.py", files) + assert "covmod1.py" in files + assert "covmodzip1.py" not in files def test_report_branches(self): self.make_file("mybranch.py", """\ @@ -182,7 +183,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest): branch(1) """) out = self.run_command("coverage run --source=. --branch mybranch.py") - self.assertEqual(out, 'x\n') + assert out == 'x\n' report = self.report_from_command("coverage report") # Name Stmts Miss Branch BrPart Cover @@ -191,9 +192,9 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # ----------------------------------------------- # TOTAL 5 0 2 1 86% - self.assertEqual(self.line_count(report), 5) - self.assertIn("mybranch.py ", report) - self.assertEqual(self.last_line_squeezed(report), "TOTAL 5 0 2 1 86%") + assert self.line_count(report) == 5 + assert "mybranch.py " in report + assert self.last_line_squeezed(report) == "TOTAL 5 0 2 1 86%" def test_report_show_missing(self): self.make_file("mymissing.py", """\ @@ -213,7 +214,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest): missing(0, 1) """) out = self.run_command("coverage run --source=. mymissing.py") - self.assertEqual(out, 'y\nz\n') + assert out == 'y\nz\n' report = self.report_from_command("coverage report --show-missing") # Name Stmts Miss Cover Missing @@ -222,10 +223,10 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # -------------------------------------------- # TOTAL 14 3 79% 3-4, 10 - self.assertEqual(self.line_count(report), 5) + assert self.line_count(report) == 5 squeezed = self.squeezed_lines(report) - self.assertEqual(squeezed[2], "mymissing.py 14 3 79% 3-4, 10") - self.assertEqual(squeezed[4], "TOTAL 14 3 79%") + assert squeezed[2] == "mymissing.py 14 3 79% 3-4, 10" + assert squeezed[4] == "TOTAL 14 3 79%" def test_report_show_missing_branches(self): self.make_file("mybranch.py", """\ @@ -238,7 +239,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest): """) self.omit_site_packages() out = self.run_command("coverage run --branch mybranch.py") - self.assertEqual(out, 'x\ny\n') + assert out == 'x\ny\n' report = self.report_from_command("coverage report --show-missing") # Name Stmts Miss Branch BrPart Cover Missing @@ -247,10 +248,10 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # ---------------------------------------------------------- # TOTAL 6 0 4 2 80% - self.assertEqual(self.line_count(report), 5) + assert self.line_count(report) == 5 squeezed = self.squeezed_lines(report) - self.assertEqual(squeezed[2], "mybranch.py 6 0 4 2 80% 2->4, 4->exit") - self.assertEqual(squeezed[4], "TOTAL 6 0 4 2 80%") + assert squeezed[2] == "mybranch.py 6 0 4 2 80% 2->4, 4->exit" + assert squeezed[4] == "TOTAL 6 0 4 2 80%" def test_report_show_missing_branches_and_lines(self): self.make_file("main.py", """\ @@ -270,7 +271,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest): """) self.omit_site_packages() out = self.run_command("coverage run --branch main.py") - self.assertEqual(out, 'x\ny\n') + assert out == 'x\ny\n' report = self.report_from_command("coverage report --show-missing") report_lines = report.splitlines() @@ -282,7 +283,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest): '---------------------------------------------------------', 'TOTAL 11 2 8 3 63%', ] - self.assertEqual(expected, report_lines) + assert expected == report_lines def test_report_skip_covered_no_branches(self): self.make_file("main.py", """ @@ -298,7 +299,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest): """) self.omit_site_packages() out = self.run_command("coverage run main.py") - self.assertEqual(out, "z\n") + assert out == "z\n" report = self.report_from_command("coverage report --skip-covered --fail-under=70") # Name Stmts Miss Cover @@ -309,12 +310,12 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # # 1 file skipped due to complete coverage. - self.assertEqual(self.line_count(report), 7, report) + assert self.line_count(report) == 7, report squeezed = self.squeezed_lines(report) - self.assertEqual(squeezed[2], "not_covered.py 2 1 50%") - self.assertEqual(squeezed[4], "TOTAL 6 1 83%") - self.assertEqual(squeezed[6], "1 file skipped due to complete coverage.") - self.assertEqual(self.last_command_status, 0) + assert squeezed[2] == "not_covered.py 2 1 50%" + assert squeezed[4] == "TOTAL 6 1 83%" + assert squeezed[6] == "1 file skipped due to complete coverage." + assert self.last_command_status == 0 def test_report_skip_covered_branches(self): self.make_file("main.py", """ @@ -339,7 +340,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest): """) self.omit_site_packages() out = self.run_command("coverage run --branch main.py") - self.assertEqual(out, "n\nz\n") + assert out == "n\nz\n" report = self.report_from_command("coverage report --skip-covered") # Name Stmts Miss Branch BrPart Cover @@ -350,11 +351,11 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # # 2 files skipped due to complete coverage. - self.assertEqual(self.line_count(report), 7, report) + assert self.line_count(report) == 7, report squeezed = self.squeezed_lines(report) - self.assertEqual(squeezed[2], "not_covered.py 4 0 2 1 83%") - self.assertEqual(squeezed[4], "TOTAL 13 0 4 1 94%") - self.assertEqual(squeezed[6], "2 files skipped due to complete coverage.") + assert squeezed[2] == "not_covered.py 4 0 2 1 83%" + assert squeezed[4] == "TOTAL 13 0 4 1 94%" + assert squeezed[6] == "2 files skipped due to complete coverage." def test_report_skip_covered_branches_with_totals(self): self.make_file("main.py", """ @@ -379,7 +380,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest): """) self.omit_site_packages() out = self.run_command("coverage run --branch main.py") - self.assertEqual(out, "n\nz\n") + assert out == "n\nz\n" report = self.report_from_command("coverage report --skip-covered") # Name Stmts Miss Branch BrPart Cover @@ -391,12 +392,12 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # # 1 file skipped due to complete coverage. - self.assertEqual(self.line_count(report), 8, report) + assert self.line_count(report) == 8, report squeezed = self.squeezed_lines(report) - self.assertEqual(squeezed[2], "also_not_run.py 2 1 0 0 50%") - self.assertEqual(squeezed[3], "not_covered.py 4 0 2 1 83%") - self.assertEqual(squeezed[5], "TOTAL 13 1 4 1 88%") - self.assertEqual(squeezed[7], "1 file skipped due to complete coverage.") + assert squeezed[2] == "also_not_run.py 2 1 0 0 50%" + assert squeezed[3] == "not_covered.py 4 0 2 1 83%" + assert squeezed[5] == "TOTAL 13 1 4 1 88%" + assert squeezed[7] == "1 file skipped due to complete coverage." def test_report_skip_covered_all_files_covered(self): self.make_file("main.py", """ @@ -405,7 +406,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest): foo() """) out = self.run_command("coverage run --source=. --branch main.py") - self.assertEqual(out, "") + assert out == "" report = self.report_from_command("coverage report --skip-covered") # Name Stmts Miss Branch BrPart Cover @@ -415,9 +416,9 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # # 1 file skipped due to complete coverage. - self.assertEqual(self.line_count(report), 6, report) + assert self.line_count(report) == 6, report squeezed = self.squeezed_lines(report) - self.assertEqual(squeezed[5], "1 file skipped due to complete coverage.") + assert squeezed[5] == "1 file skipped due to complete coverage." def test_report_skip_covered_longfilename(self): self.make_file("long_______________filename.py", """ @@ -426,7 +427,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest): foo() """) out = self.run_command("coverage run --source=. --branch long_______________filename.py") - self.assertEqual(out, "") + assert out == "" report = self.report_from_command("coverage report --skip-covered") # Name Stmts Miss Branch BrPart Cover @@ -436,20 +437,20 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # # 1 file skipped due to complete coverage. - self.assertEqual(self.line_count(report), 6, report) + assert self.line_count(report) == 6, report lines = self.report_lines(report) - self.assertEqual(lines[0], "Name Stmts Miss Branch BrPart Cover") + assert lines[0] == "Name Stmts Miss Branch BrPart Cover" squeezed = self.squeezed_lines(report) - self.assertEqual(squeezed[5], "1 file skipped due to complete coverage.") + assert squeezed[5] == "1 file skipped due to complete coverage." def test_report_skip_covered_no_data(self): report = self.report_from_command("coverage report --skip-covered") # No data to report. - self.assertEqual(self.line_count(report), 1, report) + assert self.line_count(report) == 1, report squeezed = self.squeezed_lines(report) - self.assertEqual(squeezed[0], "No data to report.") + assert squeezed[0] == "No data to report." def test_report_skip_empty(self): self.make_file("main.py", """ @@ -462,7 +463,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest): self.make_file("submodule/__init__.py", "") self.omit_site_packages() out = self.run_command("coverage run main.py") - self.assertEqual(out, "z\n") + assert out == "z\n" report = self.report_from_command("coverage report --skip-empty") # Name Stmts Miss Cover @@ -473,18 +474,18 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # # 1 empty file skipped. - self.assertEqual(self.line_count(report), 7, report) + assert self.line_count(report) == 7, report squeezed = self.squeezed_lines(report) - self.assertEqual(squeezed[2], "main.py 4 0 100%") - self.assertEqual(squeezed[4], "TOTAL 4 0 100%") - self.assertEqual(squeezed[6], "1 empty file skipped.") - self.assertEqual(self.last_command_status, 0) + assert squeezed[2] == "main.py 4 0 100%" + assert squeezed[4] == "TOTAL 4 0 100%" + assert squeezed[6] == "1 empty file skipped." + assert self.last_command_status == 0 def test_report_skip_empty_no_data(self): self.make_file("__init__.py", "") self.omit_site_packages() out = self.run_command("coverage run __init__.py") - self.assertEqual(out, "") + assert out == "" report = self.report_from_command("coverage report --skip-empty") # Name Stmts Miss Cover @@ -492,10 +493,10 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # # 1 empty file skipped. - self.assertEqual(self.line_count(report), 6, report) + assert self.line_count(report) == 6, report squeezed = self.squeezed_lines(report) - self.assertEqual(squeezed[3], "TOTAL 0 0 100%") - self.assertEqual(squeezed[5], "1 empty file skipped.") + assert squeezed[3] == "TOTAL 0 0 100%" + assert squeezed[5] == "1 empty file skipped." def test_report_precision(self): self.make_file(".coveragerc", """\ @@ -524,7 +525,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest): foo() """) out = self.run_command("coverage run --branch main.py") - self.assertEqual(out, "n\nz\n") + assert out == "n\nz\n" report = self.report_from_command("coverage report") # Name Stmts Miss Branch BrPart Cover @@ -535,11 +536,11 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # ------------------------------------------------------ # TOTAL 13 0 4 1 94.118% - self.assertEqual(self.line_count(report), 7, report) + assert self.line_count(report) == 7, report squeezed = self.squeezed_lines(report) - self.assertEqual(squeezed[2], "covered.py 3 0 0 0 100.000%") - self.assertEqual(squeezed[4], "not_covered.py 4 0 2 1 83.333%") - self.assertEqual(squeezed[6], "TOTAL 13 0 4 1 94.118%") + assert squeezed[2] == "covered.py 3 0 0 0 100.000%" + assert squeezed[4] == "not_covered.py 4 0 2 1 83.333%" + assert squeezed[6] == "TOTAL 13 0 4 1 94.118%" def test_dotpy_not_python(self): # We run a .py file, and when reporting, we can't parse it as Python. @@ -560,10 +561,8 @@ class SummaryTest(UsingModulesMixin, CoverageTest): errmsg = re.sub(r"parse '.*mycode.py", "parse 'mycode.py", errmsg) # The actual error message varies version to version errmsg = re.sub(r": '.*' at", ": 'error' at", errmsg) - self.assertEqual( - "Couldn't parse 'mycode.py' as Python source: 'error' at line 1", - errmsg, - ) + assert "Couldn't parse 'mycode.py' as Python source: 'error' at line 1" == \ + errmsg def test_accenteddotpy_not_python(self): if env.JYTHON: @@ -590,7 +589,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest): expected = u"Couldn't parse 'accented\xe2.py' as Python source: 'error' at line 1" if env.PY2: expected = expected.encode(output_encoding()) - self.assertEqual(expected, errmsg) + assert expected == errmsg def test_dotpy_not_python_ignored(self): # We run a .py file, and when reporting, we can't parse it as Python, @@ -606,9 +605,9 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # ---------------------------- # No data to report. - self.assertEqual(self.line_count(report), 4) - self.assertIn('No data to report.', report) - self.assertIn('(couldnt-parse)', report) + assert self.line_count(report) == 4 + assert 'No data to report.' in report + assert '(couldnt-parse)' in report def test_dothtml_not_python(self): # We run a .html file, and when reporting, we can't parse it as @@ -625,8 +624,8 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # ---------------------------- # No data to report. - self.assertEqual(self.line_count(report), 3) - self.assertIn('No data to report.', report) + assert self.line_count(report) == 3 + assert 'No data to report.' in report def test_report_no_extension(self): self.make_file("xxx", """\ @@ -640,9 +639,9 @@ class SummaryTest(UsingModulesMixin, CoverageTest): print("xxx: %r %r %r %r" % (a, b, c, d)) """) out = self.run_command("coverage run --source=. xxx") - self.assertEqual(out, "xxx: 3 4 0 7\n") + assert out == "xxx: 3 4 0 7\n" report = self.report_from_command("coverage report") - self.assertEqual(self.last_line_squeezed(report), "TOTAL 7 1 86%") + assert self.last_line_squeezed(report) == "TOTAL 7 1 86%" def test_report_with_chdir(self): self.make_file("chdir.py", """\ @@ -654,9 +653,9 @@ class SummaryTest(UsingModulesMixin, CoverageTest): """) self.make_file("subdir/something", "hello") out = self.run_command("coverage run --source=. chdir.py") - self.assertEqual(out, "Line One\nLine Two\nhello\n") + assert out == "Line One\nLine Two\nhello\n" report = self.report_from_command("coverage report") - self.assertEqual(self.last_line_squeezed(report), "TOTAL 5 0 100%") + assert self.last_line_squeezed(report) == "TOTAL 5 0 100%" def get_report(self, cov): """Get the report from `cov`, and canonicalize it.""" @@ -683,7 +682,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest): import main # pragma: nested # pylint: disable=unused-import cov.stop() # pragma: nested report = self.get_report(cov).splitlines() - self.assertIn("mybranch.py 5 5 2 0 0%", report) + assert "mybranch.py 5 5 2 0 0%" in report def run_TheCode_and_report_it(self): """A helper for the next few tests.""" @@ -699,16 +698,16 @@ class SummaryTest(UsingModulesMixin, CoverageTest): report = self.run_TheCode_and_report_it() - self.assertIn("TheCode", report) - self.assertNotIn("thecode", report) + assert "TheCode" in report + assert "thecode" not in report def test_bug_203_mixed_case_listed_twice(self): self.make_file("TheCode.py", "a = 1\n") report = self.run_TheCode_and_report_it() - self.assertIn("TheCode", report) - self.assertNotIn("thecode", report) + assert "TheCode" in report + assert "thecode" not in report def test_pyw_files(self): if not env.WINDOWS: @@ -728,10 +727,10 @@ class SummaryTest(UsingModulesMixin, CoverageTest): cov.stop() # pragma: nested report = self.get_report(cov) - self.assertNotIn("NoSource", report) + assert "NoSource" not in report report = report.splitlines() - self.assertIn("start.pyw 2 0 100%", report) - self.assertIn("mod.pyw 1 0 100%", report) + assert "start.pyw 2 0 100%" in report + assert "mod.pyw 1 0 100%" in report def test_tracing_pyc_file(self): # Create two Python files. @@ -748,7 +747,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest): cov.stop() # pragma: nested report = self.get_report(cov).splitlines() - self.assertIn("mod.py 1 0 100%", report) + assert "mod.py 1 0 100%" in report def test_missing_py_file_during_run(self): # PyPy2 doesn't run bare .pyc files. @@ -768,7 +767,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # the source location though. if env.PY3 and not env.JYTHON: pycs = glob.glob("__pycache__/mod.*.pyc") - self.assertEqual(len(pycs), 1) + assert len(pycs) == 1 os.rename(pycs[0], "mod.pyc") # Run the program. @@ -780,7 +779,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # Put back the missing Python file. self.make_file("mod.py", "a = 1\n") report = self.get_report(cov).splitlines() - self.assertIn("mod.py 1 0 100%", report) + assert "mod.py 1 0 100%" in report class SummaryTest2(UsingModulesMixin, CoverageTest): @@ -804,8 +803,8 @@ class SummaryTest2(UsingModulesMixin, CoverageTest): report = repout.getvalue().replace('\\', '/') report = re.sub(r"\s+", " ", report) - self.assertIn("tests/modules/pkg1/__init__.py 1 0 0 0 100%", report) - self.assertIn("tests/modules/pkg2/__init__.py 0 0 0 0 100%", report) + assert "tests/modules/pkg1/__init__.py 1 0 0 0 100%" in report + assert "tests/modules/pkg2/__init__.py 0 0 0 0 100%" in report class ReportingReturnValueTest(CoverageTest): @@ -830,17 +829,17 @@ class ReportingReturnValueTest(CoverageTest): def test_report(self): cov = self.run_coverage() val = cov.report(include="*/doit.py") - self.assertAlmostEqual(val, 85.7, 1) + assert round(abs(val-85.7), 1) == 0 def test_html(self): cov = self.run_coverage() val = cov.html_report(include="*/doit.py") - self.assertAlmostEqual(val, 85.7, 1) + assert round(abs(val-85.7), 1) == 0 def test_xml(self): cov = self.run_coverage() val = cov.xml_report(include="*/doit.py") - self.assertAlmostEqual(val, 85.7, 1) + assert round(abs(val-85.7), 1) == 0 class TestSummaryReporterConfiguration(CoverageTest): @@ -896,37 +895,35 @@ class TestSummaryReporterConfiguration(CoverageTest): # TOTAL 586 386 34% lines = report.splitlines()[2:-2] - self.assertEqual(len(lines), 3) + assert len(lines) == 3 nums = [list(map(int, l.replace('%', '').split()[1:])) for l in lines] # [ # [339, 155, 54], # [ 13, 3, 77], # [234, 228, 3] # ] - self.assertTrue(nums[1][0] < nums[2][0] < nums[0][0]) - self.assertTrue(nums[1][1] < nums[0][1] < nums[2][1]) - self.assertTrue(nums[2][2] < nums[0][2] < nums[1][2]) + assert nums[1][0] < nums[2][0] < nums[0][0] + assert nums[1][1] < nums[0][1] < nums[2][1] + assert nums[2][2] < nums[0][2] < nums[1][2] def test_defaults(self): """Run the report with no configuration options.""" report = self.get_summary_text() - self.assertNotIn('Missing', report) - self.assertNotIn('Branch', report) + assert 'Missing' not in report + assert 'Branch' not in report def test_print_missing(self): """Run the report printing the missing lines.""" report = self.get_summary_text(('report:show_missing', True)) - self.assertIn('Missing', report) - self.assertNotIn('Branch', report) + assert 'Missing' in report + assert 'Branch' not in report def assert_ordering(self, text, *words): """Assert that the `words` appear in order in `text`.""" indexes = list(map(text.find, words)) assert -1 not in indexes - self.assertEqual( - indexes, sorted(indexes), + assert indexes == sorted(indexes), \ "The words %r don't appear in order in %r" % (words, text) - ) def test_sort_report_by_stmts(self): # Sort the text report by the Stmts column. @@ -946,5 +943,5 @@ class TestSummaryReporterConfiguration(CoverageTest): def test_sort_report_by_invalid_option(self): # Sort the text report by a nonsense column. msg = "Invalid sorting option: 'Xyzzy'" - with self.assertRaisesRegex(CoverageException, msg): + with pytest.raises(CoverageException, match=msg): self.get_summary_text(('report:sort', 'Xyzzy')) diff --git a/tests/test_templite.py b/tests/test_templite.py index 321db830..2879f99d 100644 --- a/tests/test_templite.py +++ b/tests/test_templite.py @@ -9,6 +9,7 @@ import re from coverage.templite import Templite, TempliteSyntaxError, TempliteValueError from tests.coveragetest import CoverageTest +import pytest # pylint: disable=possibly-unused-variable @@ -39,7 +40,7 @@ class TempliteTest(CoverageTest): # If result is None, then an exception should have prevented us getting # to here. assert result is not None - self.assertEqual(actual, result) + assert actual == result def assertSynErr(self, msg): """Assert that a `TempliteSyntaxError` will happen. @@ -48,15 +49,13 @@ class TempliteTest(CoverageTest): """ pat = "^" + re.escape(msg) + "$" - return self.assertRaisesRegex(TempliteSyntaxError, pat) + return pytest.raises(TempliteSyntaxError, match=pat) def test_passthrough(self): # Strings without variables are passed through unchanged. - self.assertEqual(Templite("Hello").render(), "Hello") - self.assertEqual( - Templite("Hello, 20% fun time!").render(), + assert Templite("Hello").render() == "Hello" + assert Templite("Hello, 20% fun time!").render() == \ "Hello, 20% fun time!" - ) def test_variables(self): # Variables use {{var}} syntax. @@ -64,7 +63,7 @@ class TempliteTest(CoverageTest): def test_undefined_variables(self): # Using undefined names is an error. - with self.assertRaisesRegex(Exception, "'name'"): + with pytest.raises(Exception, match="'name'"): self.try_render("Hi, {{name}}!") def test_pipes(self): @@ -87,8 +86,8 @@ class TempliteTest(CoverageTest): } template = Templite("This is {{name|upper}}{{punct}}", globs) - self.assertEqual(template.render({'name':'Ned'}), "This is NED!") - self.assertEqual(template.render({'name':'Ben'}), "This is BEN!") + assert template.render({'name':'Ned'}) == "This is NED!" + assert template.render({'name':'Ben'}) == "This is BEN!" def test_attribute(self): # Variables' attributes can be accessed with dots. @@ -298,7 +297,7 @@ class TempliteTest(CoverageTest): def test_exception_during_evaluation(self): # TypeError: Couldn't evaluate {{ foo.bar.baz }}: regex = "^Couldn't evaluate None.bar$" - with self.assertRaisesRegex(TempliteValueError, regex): + with pytest.raises(TempliteValueError, match=regex): self.try_render( "Hey {{foo.bar.baz}} there", {'foo': None}, "Hey ??? there" ) diff --git a/tests/test_testing.py b/tests/test_testing.py index 34ea3263..fd5a38da 100644 --- a/tests/test_testing.py +++ b/tests/test_testing.py @@ -30,16 +30,14 @@ def test_xdist_sys_path_nuttiness_is_fixed(): assert os.environ.get('PYTHONPATH') is None -class TestingTest(TestCase): - """Tests of helper methods on `backunittest.TestCase`.""" - - def test_assert_count_equal(self): - self.assertCountEqual(set(), set()) - self.assertCountEqual({1,2,3}, {3,1,2}) - with self.assertRaises(AssertionError): - self.assertCountEqual({1,2,3}, set()) - with self.assertRaises(AssertionError): - self.assertCountEqual({1,2,3}, {4,5,6}) +"""Tests of helper methods on `backunittest.TestCase`.""" +deftest_assert_count_equal(self): + self.assertCountEqual(set(), set()) + self.assertCountEqual({1,2,3}, {3,1,2}) + with pytest.raises(AssertionError): + self.assertCountEqual({1,2,3}, set()) + withpytest.raises(AssertionError): + self.assertCountEqual({1,2,3}, {4,5,6}) class CoverageTestTest(CoverageTest): @@ -50,10 +48,10 @@ class CoverageTestTest(CoverageTest): self.assert_exists("whoville.txt") self.assert_doesnt_exist("shadow.txt") msg = "False is not true : File 'whoville.txt' shouldn't exist" - with self.assertRaisesRegex(AssertionError, msg): + with pytest.raises(AssertionError, match=msg): self.assert_doesnt_exist("whoville.txt") msg = "False is not true : File 'shadow.txt' should exist" - with self.assertRaisesRegex(AssertionError, msg): + with pytest.raises(AssertionError, match=msg): self.assert_exists("shadow.txt") def test_file_count(self): @@ -68,24 +66,24 @@ class CoverageTestTest(CoverageTest): "3 != 13 : There should be 13 files matching 'a*.txt', but there are these: " "['abcde.txt', 'afile.txt', 'axczz.txt']" ) - with self.assertRaisesRegex(AssertionError, msg): + with pytest.raises(AssertionError, match=msg): self.assert_file_count("a*.txt", 13) msg = re.escape( "2 != 12 : There should be 12 files matching '*c*.txt', but there are these: " "['abcde.txt', 'axczz.txt']" ) - with self.assertRaisesRegex(AssertionError, msg): + with pytest.raises(AssertionError, match=msg): self.assert_file_count("*c*.txt", 12) msg = re.escape( "1 != 11 : There should be 11 files matching 'afile.*', but there are these: " "['afile.txt']" ) - with self.assertRaisesRegex(AssertionError, msg): + with pytest.raises(AssertionError, match=msg): self.assert_file_count("afile.*", 11) msg = re.escape( "0 != 10 : There should be 10 files matching '*.q', but there are these: []" ) - with self.assertRaisesRegex(AssertionError, msg): + with pytest.raises(AssertionError, match=msg): self.assert_file_count("*.q", 10) def test_assert_startwith(self): @@ -93,10 +91,10 @@ class CoverageTestTest(CoverageTest): self.assert_starts_with("xyz\nabc", "xy") self.assert_starts_with("xyzzy", ("x", "z")) msg = re.escape("'xyz' doesn't start with 'a'") - with self.assertRaisesRegex(AssertionError, msg): + with pytest.raises(AssertionError, match=msg): self.assert_starts_with("xyz", "a") msg = re.escape("'xyz\\nabc' doesn't start with 'a'") - with self.assertRaisesRegex(AssertionError, msg): + with pytest.raises(AssertionError, match=msg): self.assert_starts_with("xyz\nabc", "a") def test_assert_recent_datetime(self): @@ -107,17 +105,17 @@ class CoverageTestTest(CoverageTest): # Default delta is 10 seconds. self.assert_recent_datetime(now_delta(0)) self.assert_recent_datetime(now_delta(-9)) - with self.assertRaises(AssertionError): + with pytest.raises(AssertionError): self.assert_recent_datetime(now_delta(-11)) - with self.assertRaises(AssertionError): + with pytest.raises(AssertionError): self.assert_recent_datetime(now_delta(1)) # Delta is settable. self.assert_recent_datetime(now_delta(0), seconds=120) self.assert_recent_datetime(now_delta(-100), seconds=120) - with self.assertRaises(AssertionError): + with pytest.raises(AssertionError): self.assert_recent_datetime(now_delta(-1000), seconds=120) - with self.assertRaises(AssertionError): + with pytest.raises(AssertionError): self.assert_recent_datetime(now_delta(1), seconds=120) def test_assert_warnings(self): @@ -143,13 +141,13 @@ class CoverageTestTest(CoverageTest): # But if there are a bunch of expected warnings, they have to all happen. warn_regex = r"Didn't find warning 'You' in \['Hello there!'\]" - with self.assertRaisesRegex(AssertionError, warn_regex): + with pytest.raises(AssertionError, match=warn_regex): with self.assert_warnings(cov, ["Hello.*!", "You"]): cov._warn("Hello there!") # Make a different warning than expected, it should raise an assertion. warn_regex = r"Didn't find warning 'Not me' in \['Hello there!'\]" - with self.assertRaisesRegex(AssertionError, warn_regex): + with pytest.raises(AssertionError, match=warn_regex): with self.assert_warnings(cov, ["Not me"]): cov._warn("Hello there!") @@ -159,13 +157,13 @@ class CoverageTestTest(CoverageTest): # But it should fail if the unexpected warning does appear. warn_regex = r"Found warning 'Bye' in \['Hi', 'Bye'\]" - with self.assertRaisesRegex(AssertionError, warn_regex): + with pytest.raises(AssertionError, match=warn_regex): with self.assert_warnings(cov, ["Hi"], not_warnings=["Bye"]): cov._warn("Hi") cov._warn("Bye") # assert_warnings shouldn't hide a real exception. - with self.assertRaisesRegex(ZeroDivisionError, "oops"): + with pytest.raises(ZeroDivisionError, match="oops"): with self.assert_warnings(cov, ["Hello there!"]): raise ZeroDivisionError("oops") @@ -178,7 +176,7 @@ class CoverageTestTest(CoverageTest): # If you said there would be no warnings, and there were, fail! warn_regex = r"Unexpected warnings: \['Watch out!'\]" - with self.assertRaisesRegex(AssertionError, warn_regex): + with pytest.raises(AssertionError, match=warn_regex): with self.assert_warnings(cov, []): cov._warn("Watch out!") @@ -192,21 +190,21 @@ class CoverageTestTest(CoverageTest): print(os.environ['COV_FOOBAR']) """) out = self.run_command("python showme.py").splitlines() - self.assertEqual(actual_path(out[0]), actual_path(sys.executable)) - self.assertEqual(out[1], os.__file__) - self.assertEqual(out[2], 'XYZZY') + assert actual_path(out[0]) == actual_path(sys.executable) + assert out[1] == os.__file__ + assert out[2] == 'XYZZY' # Try it with a "coverage debug sys" command. out = self.run_command("coverage debug sys") executable = re_line(out, "executable:") executable = executable.split(":", 1)[1].strip() - self.assertTrue(_same_python_executable(executable, sys.executable)) + assert _same_python_executable(executable, sys.executable) # "environment: COV_FOOBAR = XYZZY" or "COV_FOOBAR = XYZZY" environ = re_line(out, "COV_FOOBAR") _, _, environ = environ.rpartition(":") - self.assertEqual(environ.strip(), "COV_FOOBAR = XYZZY") + assert environ.strip() == "COV_FOOBAR = XYZZY" def test_run_command_stdout_stderr(self): # run_command should give us both stdout and stderr. @@ -216,8 +214,8 @@ class CoverageTestTest(CoverageTest): print("StdOut") """) out = self.run_command("python outputs.py") - self.assertIn("StdOut\n", out) - self.assertIn("StdErr\n", out) + assert "StdOut\n" in out + assert "StdErr\n" in out class CheckUniqueFilenamesTest(CoverageTest): @@ -243,7 +241,7 @@ class CheckUniqueFilenamesTest(CoverageTest): assert stub.method("file2", 1723, b="what") == (23, "file2", 1723, "what") # A duplicate file name trips an assertion. - with self.assertRaises(AssertionError): + with pytest.raises(AssertionError): stub.method("file1") diff --git a/tests/test_version.py b/tests/test_version.py index 11b180d5..ce2e88e6 100644 --- a/tests/test_version.py +++ b/tests/test_version.py @@ -16,24 +16,20 @@ class VersionTest(CoverageTest): def test_version_info(self): # Make sure we didn't screw up the version_info tuple. - self.assertIsInstance(coverage.version_info, tuple) - self.assertEqual([type(d) for d in coverage.version_info], [int, int, int, str, int]) - self.assertIn(coverage.version_info[3], ['alpha', 'beta', 'candidate', 'final']) + assert isinstance(coverage.version_info, tuple) + assert [type(d) for d in coverage.version_info] == [int, int, int, str, int] + assert coverage.version_info[3] in ['alpha', 'beta', 'candidate', 'final'] def test_make_version(self): - self.assertEqual(_make_version(4, 0, 0, 'alpha', 0), "4.0a0") - self.assertEqual(_make_version(4, 0, 0, 'alpha', 1), "4.0a1") - self.assertEqual(_make_version(4, 0, 0, 'final', 0), "4.0") - self.assertEqual(_make_version(4, 1, 2, 'beta', 3), "4.1.2b3") - self.assertEqual(_make_version(4, 1, 2, 'final', 0), "4.1.2") - self.assertEqual(_make_version(5, 10, 2, 'candidate', 7), "5.10.2rc7") + assert _make_version(4, 0, 0, 'alpha', 0) == "4.0a0" + assert _make_version(4, 0, 0, 'alpha', 1) == "4.0a1" + assert _make_version(4, 0, 0, 'final', 0) == "4.0" + assert _make_version(4, 1, 2, 'beta', 3) == "4.1.2b3" + assert _make_version(4, 1, 2, 'final', 0) == "4.1.2" + assert _make_version(5, 10, 2, 'candidate', 7) == "5.10.2rc7" def test_make_url(self): - self.assertEqual( - _make_url(4, 0, 0, 'final', 0), + assert _make_url(4, 0, 0, 'final', 0) == \ "https://coverage.readthedocs.io" - ) - self.assertEqual( - _make_url(4, 1, 2, 'beta', 3), + assert _make_url(4, 1, 2, 'beta', 3) == \ "https://coverage.readthedocs.io/en/coverage-4.1.2b3" - ) diff --git a/tests/test_xml.py b/tests/test_xml.py index e3be7a54..033c374e 100644 --- a/tests/test_xml.py +++ b/tests/test_xml.py @@ -17,6 +17,7 @@ from coverage.files import abs_file from tests.coveragetest import CoverageTest from tests.goldtest import compare, gold_path +import pytest class XmlTestHelpers(CoverageTest): @@ -87,11 +88,11 @@ class XmlTestHelpersTest(XmlTestHelpers, CoverageTest): self.assert_source(dom, "something") self.assert_source(dom, "another") - with self.assertRaises(AssertionError): + with pytest.raises(AssertionError): self.assert_source(dom, "hello") - with self.assertRaises(AssertionError): + with pytest.raises(AssertionError): self.assert_source(dom, "foo") - with self.assertRaises(AssertionError): + with pytest.raises(AssertionError): self.assert_source(dom, "thing") @@ -274,10 +275,8 @@ class XmlPackageStructureTest(XmlTestHelpers, CoverageTest): def assert_package_and_class_tags(self, cov, result): """Check the XML package and class tags from `cov` match `result`.""" - self.assertEqual( - unbackslash(list(self.package_and_class_tags(cov))), - unbackslash(result), - ) + assert unbackslash(list(self.package_and_class_tags(cov))) == \ + unbackslash(result) def test_package_names(self): self.make_tree(width=1, depth=3) -- cgit v1.2.1 From 6e93714d655c87e62cd03a4ff3e1739245b684b9 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Sun, 31 Jan 2021 07:41:50 -0500 Subject: test: fix unittest2pytest brokenness unittest2pytest created syntax errors, reported here: https://github.com/pytest-dev/unittest2pytest/issues/51 This commit fixes them back. --- tests/test_backward.py | 21 ++++++++++++--------- tests/test_testing.py | 17 +++++++++-------- 2 files changed, 21 insertions(+), 17 deletions(-) (limited to 'tests') diff --git a/tests/test_backward.py b/tests/test_backward.py index 01cc8dac..767a7ac8 100644 --- a/tests/test_backward.py +++ b/tests/test_backward.py @@ -5,14 +5,17 @@ from coverage.backunittest import TestCase from coverage.backward import iitems, binary_bytes, bytes_to_ints -"""Tests of things from backward.py.""" -deftest_iitems(self): - d = {'a': 1, 'b': 2, 'c': 3} - items = [('a', 1), ('b', 2), ('c', 3)] - self.assertCountEqual(list(iitems(d)), items) + +class BackwardTest(TestCase): + """Tests of things from backward.py.""" + + def test_iitems(self): + d = {'a': 1, 'b': 2, 'c': 3} + items = [('a', 1), ('b', 2), ('c', 3)] + self.assertCountEqual(list(iitems(d)), items) def test_binary_bytes(self): - byte_values = [0, 255, 17, 23, 42, 57] - bb = binary_bytes(byte_values) - assert len(bb) == len(byte_values) - assert byte_values == list(bytes_to_ints(bb)) + byte_values = [0, 255, 17, 23, 42, 57] + bb = binary_bytes(byte_values) + assert len(bb) == len(byte_values) + assert byte_values == list(bytes_to_ints(bb)) diff --git a/tests/test_testing.py b/tests/test_testing.py index fd5a38da..52560a5f 100644 --- a/tests/test_testing.py +++ b/tests/test_testing.py @@ -30,14 +30,15 @@ def test_xdist_sys_path_nuttiness_is_fixed(): assert os.environ.get('PYTHONPATH') is None -"""Tests of helper methods on `backunittest.TestCase`.""" -deftest_assert_count_equal(self): - self.assertCountEqual(set(), set()) - self.assertCountEqual({1,2,3}, {3,1,2}) - with pytest.raises(AssertionError): - self.assertCountEqual({1,2,3}, set()) - withpytest.raises(AssertionError): - self.assertCountEqual({1,2,3}, {4,5,6}) +class TestingTest(TestCase): + """Tests of helper methods on `backunittest.TestCase`.""" + + def test_assert_count_equal(self): + self.assertCountEqual(set(), set()) + with pytest.raises(AssertionError): + self.assertCountEqual({1,2,3}, set()) + with pytest.raises(AssertionError): + self.assertCountEqual({1,2,3}, {4,5,6}) class CoverageTestTest(CoverageTest): -- cgit v1.2.1 From 716b31214126c4a06d8262a62153e5d1fa45fa54 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Sun, 31 Jan 2021 08:16:50 -0500 Subject: test: adapt to pytest assertion messages Bare "assert" statements don't produce the same assertion message as self.assertEqual did: they don't include the two values compared. For some of our own asserts, add back the detailed message. For some checks of asserts, it's fine that the values are missing because the longer messsage includes the information. --- tests/coveragetest.py | 8 ++++---- tests/test_testing.py | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'tests') diff --git a/tests/coveragetest.py b/tests/coveragetest.py index ed3f1839..2e6f1323 100644 --- a/tests/coveragetest.py +++ b/tests/coveragetest.py @@ -198,7 +198,7 @@ class CoverageTest( if isinstance(lines[0], int): # lines is just a list of numbers, it must match the statements # found in the code. - assert statements == lines + assert statements == lines, "{!r} != {!r}".format(statements, lines) else: # lines is a list of possible line number lists, one of them # must match. @@ -210,7 +210,7 @@ class CoverageTest( missing_formatted = analysis.missing_formatted() if isinstance(missing, string_class): - assert missing_formatted == missing + assert missing_formatted == missing, "{!r} != {!r}".format(missing_formatted, missing) else: for missing_list in missing: if missing_formatted == missing_list: @@ -244,7 +244,7 @@ class CoverageTest( frep = StringIO() cov.report(mod, file=frep, show_missing=True) rep = " ".join(frep.getvalue().split("\n")[2].split()[1:]) - assert report == rep + assert report == rep, "{!r} != {!r}".format(report, rep) return cov @@ -351,7 +351,7 @@ class CoverageTest( """ ret_actual = command_line(args) - assert ret_actual == ret + assert ret_actual == ret, "{!r} != {!r}".format(ret_actual, ret) # Some distros rename the coverage command, and need a way to indicate # their new command name to the tests. This is here for them to override, diff --git a/tests/test_testing.py b/tests/test_testing.py index 52560a5f..21e09dcc 100644 --- a/tests/test_testing.py +++ b/tests/test_testing.py @@ -48,10 +48,10 @@ class CoverageTestTest(CoverageTest): self.make_file("whoville.txt", "We are here!") self.assert_exists("whoville.txt") self.assert_doesnt_exist("shadow.txt") - msg = "False is not true : File 'whoville.txt' shouldn't exist" + msg = "File 'whoville.txt' shouldn't exist" with pytest.raises(AssertionError, match=msg): self.assert_doesnt_exist("whoville.txt") - msg = "False is not true : File 'shadow.txt' should exist" + msg = "File 'shadow.txt' should exist" with pytest.raises(AssertionError, match=msg): self.assert_exists("shadow.txt") @@ -64,25 +64,25 @@ class CoverageTestTest(CoverageTest): self.assert_file_count("afile.*", 1) self.assert_file_count("*.q", 0) msg = re.escape( - "3 != 13 : There should be 13 files matching 'a*.txt', but there are these: " + "There should be 13 files matching 'a*.txt', but there are these: " "['abcde.txt', 'afile.txt', 'axczz.txt']" ) with pytest.raises(AssertionError, match=msg): self.assert_file_count("a*.txt", 13) msg = re.escape( - "2 != 12 : There should be 12 files matching '*c*.txt', but there are these: " + "There should be 12 files matching '*c*.txt', but there are these: " "['abcde.txt', 'axczz.txt']" ) with pytest.raises(AssertionError, match=msg): self.assert_file_count("*c*.txt", 12) msg = re.escape( - "1 != 11 : There should be 11 files matching 'afile.*', but there are these: " + "There should be 11 files matching 'afile.*', but there are these: " "['afile.txt']" ) with pytest.raises(AssertionError, match=msg): self.assert_file_count("afile.*", 11) msg = re.escape( - "0 != 10 : There should be 10 files matching '*.q', but there are these: []" + "There should be 10 files matching '*.q', but there are these: []" ) with pytest.raises(AssertionError, match=msg): self.assert_file_count("*.q", 10) -- cgit v1.2.1 From 4bad09744d80c6123e77252d5db09a31db25297b Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Sun, 31 Jan 2021 08:34:00 -0500 Subject: refactor: mark an internal method --- tests/coveragetest.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/coveragetest.py b/tests/coveragetest.py index 2e6f1323..b0c99d2e 100644 --- a/tests/coveragetest.py +++ b/tests/coveragetest.py @@ -134,7 +134,7 @@ class CoverageTest( self.last_module_name = 'coverage_test_' + str(random.random())[2:] return self.last_module_name - def assert_equal_arcs(self, a1, a2, msg=None): + def _assert_equal_arcs(self, a1, a2, msg=None): """Assert that the arc lists `a1` and `a2` are equal.""" # Make them into multi-line strings so we can see what's going wrong. s1 = arcs_to_arcz_repr(a1) @@ -225,17 +225,17 @@ class CoverageTest( # print("Executed:") # print(" actual:", sorted(set(analysis.arcs_executed()))) with self.delayed_assertions(): - self.assert_equal_arcs( + self._assert_equal_arcs( arcs, analysis.arc_possibilities(), "Possible arcs differ: minus is expected, plus is actual" ) - self.assert_equal_arcs( + self._assert_equal_arcs( arcs_missing, analysis.arcs_missing(), "Missing arcs differ: minus is expected, plus is actual" ) - self.assert_equal_arcs( + self._assert_equal_arcs( arcs_unpredicted, analysis.arcs_unpredicted(), "Unpredicted arcs differ: minus is expected, plus is actual" ) -- cgit v1.2.1 From 65b5830a4d13d65c3bb314dd4894d565a16ceb9b Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Sun, 31 Jan 2021 09:12:43 -0500 Subject: style: singleton comparisons should use is I guess the original line was wrong, but it would have been nice for unittest2pytest to fix it for me: https://github.com/pytest-dev/unittest2pytest/issues/52 --- tests/test_api.py | 6 +++--- tests/test_arcs.py | 2 +- tests/test_config.py | 16 ++++++++-------- tests/test_context.py | 2 +- tests/test_data.py | 2 +- tests/test_execfile.py | 2 +- tests/test_plugins.py | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) (limited to 'tests') diff --git a/tests/test_api.py b/tests/test_api.py index 95559986..be7cc83e 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -116,7 +116,7 @@ class ApiTest(CoverageTest): # Measure without the stdlib. cov1 = coverage.Coverage() - assert cov1.config.cover_pylib == False + assert cov1.config.cover_pylib is False self.start_import_stop(cov1, "mymain") # some statements were marked executed in mymain.py @@ -1108,9 +1108,9 @@ class ImmutableConfigTest(CoverageTest): self.make_file("simple.py", "a = 1") cov = coverage.Coverage() self.start_import_stop(cov, "simple") - assert cov.get_option("report:show_missing") == False + assert cov.get_option("report:show_missing") is False cov.report(show_missing=True) - assert cov.get_option("report:show_missing") == False + assert cov.get_option("report:show_missing") is False class RelativePathTest(CoverageTest): diff --git a/tests/test_arcs.py b/tests/test_arcs.py index 79280e2d..c4d34d30 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -94,7 +94,7 @@ class SimpleArcTest(CoverageTest): if x % 2: return True return False a = fn(1) - assert a == True + assert a is True """, arcz=".1 14 45 5. .2 2. 23 3.", arcz_missing="23 3.") diff --git a/tests/test_config.py b/tests/test_config.py index 0a742f3d..f1df4d72 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -232,7 +232,7 @@ class ConfigTest(CoverageTest): self.set_environ("OKAY", "yes") cov = coverage.Coverage() assert cov.config.data_file == "hello-world.fooey" - assert cov.config.branch == True + assert cov.config.branch is True assert cov.config.exclude_list == \ ["the_$one", "anotherZZZ", "xZZZy", "xy", "huh${X}what"] @@ -256,7 +256,7 @@ class ConfigTest(CoverageTest): self.set_environ("THING", "ZZZ") cov = coverage.Coverage() assert cov.config.data_file == "hello-world.fooey" - assert cov.config.branch == True + assert cov.config.branch is True assert cov.config.exclude_list == \ ["the_$one", "anotherZZZ", "xZZZy", "xy", "huh${X}what"] @@ -582,8 +582,8 @@ class ConfigFileTest(UsingModulesMixin, CoverageTest): 'names': 'Jane/John/Jenny', } assert cov.config.get_plugin_options("plugins.another") == {} - assert cov.config.json_show_contexts == True - assert cov.config.json_pretty_print == True + assert cov.config.json_show_contexts is True + assert cov.config.json_pretty_print is True def test_config_file_settings(self): self.make_file(".coveragerc", self.LOTSA_SETTINGS.format(section="")) @@ -629,8 +629,8 @@ class ConfigFileTest(UsingModulesMixin, CoverageTest): """) cov = coverage.Coverage() assert cov.config.run_include == ["foo"] - assert cov.config.run_omit == None - assert cov.config.branch == False + assert cov.config.run_omit is None + assert cov.config.branch is False def test_setupcfg_only_if_not_coveragerc(self): self.check_other_not_read_if_coveragerc("setup.cfg") @@ -646,8 +646,8 @@ class ConfigFileTest(UsingModulesMixin, CoverageTest): branch = true """) cov = coverage.Coverage() - assert cov.config.run_omit == None - assert cov.config.branch == False + assert cov.config.run_omit is None + assert cov.config.branch is False def test_setupcfg_only_if_prefixed(self): self.check_other_config_need_prefixes("setup.cfg") diff --git a/tests/test_context.py b/tests/test_context.py index be478760..418849d5 100644 --- a/tests/test_context.py +++ b/tests/test_context.py @@ -285,4 +285,4 @@ class QualnameTest(CoverageTest): def test_bug_829(self): # A class with a name like a function shouldn't confuse qualname_from_frame. class test_something(object): # pylint: disable=unused-variable - assert get_qualname() == None + assert get_qualname() is None diff --git a/tests/test_data.py b/tests/test_data.py index d1ed04e1..9eb6ecee 100644 --- a/tests/test_data.py +++ b/tests/test_data.py @@ -416,7 +416,7 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): # Asking about an unmeasured file shouldn't make it seem measured. covdata = CoverageData() self.assert_measured_files(covdata, []) - assert covdata.arcs("missing.py") == None + assert covdata.arcs("missing.py") is None self.assert_measured_files(covdata, []) def test_add_to_hash_with_lines(self): diff --git a/tests/test_execfile.py b/tests/test_execfile.py index b740d2df..c758f711 100644 --- a/tests/test_execfile.py +++ b/tests/test_execfile.py @@ -51,7 +51,7 @@ class RunFileTest(CoverageTest): assert mod_globs['argv1-n'] == ["arg1", "arg2"] # __builtins__ should have the right values, like open(). - assert mod_globs['__builtins__.has_open'] == True + assert mod_globs['__builtins__.has_open'] is True def test_no_extra_file(self): # Make sure that running a file doesn't create an extra compiled file. diff --git a/tests/test_plugins.py b/tests/test_plugins.py index 3472522b..e706ef36 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -403,7 +403,7 @@ class GoodFileTracerTest(FileTracerTest): analysis = cov._analyze("foo_7.html") assert analysis.statements == {1, 2, 3, 4, 5, 6, 7} # Plugins don't do branch coverage yet. - assert analysis.has_arcs() == True + assert analysis.has_arcs() is True assert analysis.arc_possibilities() == [] assert analysis.missing == {1, 2, 3, 6, 7} -- cgit v1.2.1 From 2faae252d853572cf7403528075461569ac137d1 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Sun, 31 Jan 2021 09:18:40 -0500 Subject: style: correct placement of auto-added pytest imports --- tests/test_api.py | 2 +- tests/test_concurrency.py | 2 +- tests/test_config.py | 2 +- tests/test_coverage.py | 3 ++- tests/test_data.py | 2 +- tests/test_debug.py | 2 +- tests/test_execfile.py | 3 ++- tests/test_html.py | 2 +- tests/test_parser.py | 3 ++- tests/test_phystokens.py | 3 ++- tests/test_plugins.py | 3 ++- tests/test_summary.py | 3 ++- tests/test_templite.py | 3 ++- tests/test_xml.py | 2 +- 14 files changed, 21 insertions(+), 14 deletions(-) (limited to 'tests') diff --git a/tests/test_api.py b/tests/test_api.py index be7cc83e..7d75022e 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -12,6 +12,7 @@ import shutil import sys import textwrap +import pytest from unittest_mixins import change_dir import coverage @@ -22,7 +23,6 @@ from coverage.files import abs_file, relative_filename from coverage.misc import CoverageException from tests.coveragetest import CoverageTest, CoverageTestMethodsMixin, TESTS_DIR, UsingModulesMixin -import pytest class ApiTest(CoverageTest): diff --git a/tests/test_concurrency.py b/tests/test_concurrency.py index cc9622d1..fd7aa851 100644 --- a/tests/test_concurrency.py +++ b/tests/test_concurrency.py @@ -6,6 +6,7 @@ import glob import os import random +import re import sys import threading import time @@ -20,7 +21,6 @@ from coverage.files import abs_file from tests.coveragetest import CoverageTest from tests.helpers import remove_files -import re # These libraries aren't always available, we'll skip tests if they aren't. diff --git a/tests/test_config.py b/tests/test_config.py index f1df4d72..3d090668 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -7,13 +7,13 @@ from collections import OrderedDict import mock +import pytest import coverage from coverage.misc import CoverageException from tests.coveragetest import CoverageTest, UsingModulesMixin from tests.helpers import without_module -import pytest class ConfigTest(CoverageTest): diff --git a/tests/test_coverage.py b/tests/test_coverage.py index 6529aa72..52b405e8 100644 --- a/tests/test_coverage.py +++ b/tests/test_coverage.py @@ -4,12 +4,13 @@ """Tests for coverage.py.""" +import pytest + import coverage from coverage import env from coverage.misc import CoverageException from tests.coveragetest import CoverageTest -import pytest class TestCoverageTest(CoverageTest): diff --git a/tests/test_data.py b/tests/test_data.py index 9eb6ecee..4eda1873 100644 --- a/tests/test_data.py +++ b/tests/test_data.py @@ -11,6 +11,7 @@ import sqlite3 import threading import mock +import pytest from coverage.data import CoverageData, combine_parallel_data from coverage.data import add_data_to_hash, line_counts @@ -19,7 +20,6 @@ from coverage.files import PathAliases, canonical_filename from coverage.misc import CoverageException from tests.coveragetest import CoverageTest -import pytest LINES_1 = { diff --git a/tests/test_debug.py b/tests/test_debug.py index 629665f9..42d7945e 100644 --- a/tests/test_debug.py +++ b/tests/test_debug.py @@ -4,6 +4,7 @@ """Tests of coverage/debug.py""" import os +import re import pytest @@ -15,7 +16,6 @@ from coverage.env import C_TRACER from tests.coveragetest import CoverageTest from tests.helpers import re_line, re_lines -import re class InfoFormatterTest(CoverageTest): diff --git a/tests/test_execfile.py b/tests/test_execfile.py index c758f711..77527478 100644 --- a/tests/test_execfile.py +++ b/tests/test_execfile.py @@ -11,6 +11,8 @@ import os.path import re import sys +import pytest + from coverage import env from coverage.backward import binary_bytes from coverage.execfile import run_python_file, run_python_module @@ -18,7 +20,6 @@ from coverage.files import python_reported_file from coverage.misc import NoCode, NoSource from tests.coveragetest import CoverageTest, TESTS_DIR, UsingModulesMixin -import pytest TRY_EXECFILE = os.path.join(TESTS_DIR, "modules/process_test/try_execfile.py") diff --git a/tests/test_html.py b/tests/test_html.py index a25f76cb..59cda0d4 100644 --- a/tests/test_html.py +++ b/tests/test_html.py @@ -13,6 +13,7 @@ import re import sys import mock +import pytest from unittest_mixins import change_dir import coverage @@ -26,7 +27,6 @@ from coverage.report import get_analysis_to_report from tests.coveragetest import CoverageTest, TESTS_DIR from tests.goldtest import gold_path from tests.goldtest import compare, contains, doesnt_contain, contains_any -import pytest class HtmlTestHelpers(CoverageTest): diff --git a/tests/test_parser.py b/tests/test_parser.py index 49b23f9b..14950c3d 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -5,13 +5,14 @@ import textwrap +import pytest + from coverage import env from coverage.misc import NotPython from coverage.parser import PythonParser from tests.coveragetest import CoverageTest, xfail from tests.helpers import arcz_to_arcs -import pytest class PythonParserTest(CoverageTest): diff --git a/tests/test_phystokens.py b/tests/test_phystokens.py index 5da12d9c..26a72d28 100644 --- a/tests/test_phystokens.py +++ b/tests/test_phystokens.py @@ -7,13 +7,14 @@ import os.path import re import textwrap +import pytest + from coverage import env from coverage.phystokens import source_token_lines, source_encoding from coverage.phystokens import neuter_encoding_declaration, compile_unicode from coverage.python import get_python_source from tests.coveragetest import CoverageTest, TESTS_DIR -import pytest # A simple program and its token stream. diff --git a/tests/test_plugins.py b/tests/test_plugins.py index e706ef36..12ce7c1e 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -7,6 +7,8 @@ import inspect import os.path from xml.etree import ElementTree +import pytest + import coverage from coverage import env from coverage.backward import StringIO, import_local_file @@ -18,7 +20,6 @@ import coverage.plugin from tests.coveragetest import CoverageTest from tests.helpers import CheckUniqueFilenames -import pytest class FakeConfig(object): diff --git a/tests/test_summary.py b/tests/test_summary.py index f2c75317..1d74af9c 100644 --- a/tests/test_summary.py +++ b/tests/test_summary.py @@ -10,6 +10,8 @@ import os.path import py_compile import re +import pytest + import coverage from coverage import env from coverage.backward import StringIO @@ -19,7 +21,6 @@ from coverage.misc import CoverageException, output_encoding from coverage.summary import SummaryReporter from tests.coveragetest import CoverageTest, TESTS_DIR, UsingModulesMixin -import pytest class SummaryTest(UsingModulesMixin, CoverageTest): diff --git a/tests/test_templite.py b/tests/test_templite.py index 2879f99d..8d808554 100644 --- a/tests/test_templite.py +++ b/tests/test_templite.py @@ -6,10 +6,11 @@ import re +import pytest + from coverage.templite import Templite, TempliteSyntaxError, TempliteValueError from tests.coveragetest import CoverageTest -import pytest # pylint: disable=possibly-unused-variable diff --git a/tests/test_xml.py b/tests/test_xml.py index 033c374e..15f07698 100644 --- a/tests/test_xml.py +++ b/tests/test_xml.py @@ -9,6 +9,7 @@ import os.path import re from xml.etree import ElementTree +import pytest from unittest_mixins import change_dir import coverage @@ -17,7 +18,6 @@ from coverage.files import abs_file from tests.coveragetest import CoverageTest from tests.goldtest import compare, gold_path -import pytest class XmlTestHelpers(CoverageTest): -- cgit v1.2.1 From d02be78c3a0ee3022be56c623bb9bdcad1e9acd4 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Sun, 31 Jan 2021 10:10:47 -0500 Subject: style: fix long lines and avoid backslashes --- tests/coveragetest.py | 3 +- tests/test_api.py | 14 ++--- tests/test_arcs.py | 8 +-- tests/test_cmdline.py | 7 +-- tests/test_config.py | 9 +-- tests/test_data.py | 16 +++--- tests/test_debug.py | 10 ++-- tests/test_execfile.py | 3 +- tests/test_files.py | 14 ++--- tests/test_html.py | 30 +++++----- tests/test_numbits.py | 8 ++- tests/test_oddball.py | 22 ++++---- tests/test_parser.py | 142 ++++++++++++++++++++++++++++------------------- tests/test_phystokens.py | 8 +-- tests/test_plugins.py | 4 +- tests/test_process.py | 28 ++++++---- tests/test_summary.py | 7 +-- tests/test_templite.py | 3 +- tests/test_version.py | 7 +-- tests/test_xml.py | 3 +- 20 files changed, 179 insertions(+), 167 deletions(-) (limited to 'tests') diff --git a/tests/coveragetest.py b/tests/coveragetest.py index b0c99d2e..f7a5f6f8 100644 --- a/tests/coveragetest.py +++ b/tests/coveragetest.py @@ -210,7 +210,8 @@ class CoverageTest( missing_formatted = analysis.missing_formatted() if isinstance(missing, string_class): - assert missing_formatted == missing, "{!r} != {!r}".format(missing_formatted, missing) + msg = "{!r} != {!r}".format(missing_formatted, missing) + assert missing_formatted == missing, msg else: for missing_list in missing: if missing_formatted == missing_list: diff --git a/tests/test_api.py b/tests/test_api.py index 7d75022e..bce431f3 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -548,8 +548,7 @@ class ApiTest(CoverageTest): assert "Hello\n" in out err = self.stderr() - assert "Coverage.py warning: Module sys has no Python source. (module-not-python)" in \ - err + assert "Coverage.py warning: Module sys has no Python source. (module-not-python)" in err assert "module-not-imported" not in err assert "no-data-collected" not in err @@ -634,8 +633,7 @@ class ApiTest(CoverageTest): # Labeled data is collected data = cov.get_data() - assert [u'', u'multiply_six', u'multiply_zero'] == \ - sorted(data.measured_contexts()) + assert [u'', u'multiply_six', u'multiply_zero'] == sorted(data.measured_contexts()) filenames = self.get_measured_filenames(data) suite_filename = filenames['testsuite.py'] @@ -673,8 +671,8 @@ class ApiTest(CoverageTest): # Labeled data is collected data = cov.get_data() - assert [u'mysuite', u'mysuite|multiply_six', u'mysuite|multiply_zero'] == \ - sorted(data.measured_contexts()) + expected = [u'mysuite', u'mysuite|multiply_six', u'mysuite|multiply_zero'] + assert expected == sorted(data.measured_contexts()) filenames = self.get_measured_filenames(data) suite_filename = filenames['testsuite.py'] @@ -691,8 +689,8 @@ class ApiTest(CoverageTest): # Switch twice, but only get one warning. cov.switch_context("test1") # pragma: nested cov.switch_context("test2") # pragma: nested - assert self.stderr() == \ - "Coverage.py warning: Conflicting dynamic contexts (dynamic-conflict)\n" + expected = "Coverage.py warning: Conflicting dynamic contexts (dynamic-conflict)\n" + assert expected == self.stderr() cov.stop() # pragma: nested def test_switch_context_unstarted(self): diff --git a/tests/test_arcs.py b/tests/test_arcs.py index c4d34d30..2f49ecfb 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -1410,10 +1410,10 @@ class MiscArcTest(CoverageTest): filename = self.last_module_name + ".py" fr = cov._get_file_reporter(filename) arcs_executed = cov._analyze(filename).arcs_executed() - assert fr.missing_arc_description(3, -3, arcs_executed) == \ - "line 3 didn't finish the generator expression on line 3" - assert fr.missing_arc_description(4, -4, arcs_executed) == \ - "line 4 didn't run the generator expression on line 4" + expected = "line 3 didn't finish the generator expression on line 3" + assert expected == fr.missing_arc_description(3, -3, arcs_executed) + expected = "line 4 didn't run the generator expression on line 4" + assert expected == fr.missing_arc_description(4, -4, arcs_executed) class DecoratorArcTest(CoverageTest): diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py index 2c24c598..a0744452 100644 --- a/tests/test_cmdline.py +++ b/tests/test_cmdline.py @@ -544,10 +544,9 @@ class CmdLineTest(BaseCmdLineTest): # runs, since they won't make it to the subprocesses. You need to use a # config file. self.command_line("run --concurrency=multiprocessing --branch foo.py", ret=ERR) - assert "Options affecting multiprocessing must only be specified in a configuration file." in \ - self.stderr() - assert "Remove --branch from the command line." in \ - self.stderr() + msg = "Options affecting multiprocessing must only be specified in a configuration file." + assert msg in self.stderr() + assert "Remove --branch from the command line." in self.stderr() def test_run_debug(self): self.cmd_executes("run --debug=opt1 foo.py", """\ diff --git a/tests/test_config.py b/tests/test_config.py index 3d090668..04503f30 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -88,8 +88,7 @@ class ConfigTest(CoverageTest): assert cov.config.precision == 3 assert cov.config.html_title == u"tabblo & «ταБЬℓσ»" assert round(abs(cov.config.fail_under-90.5), 7) == 0 - assert cov.config.get_plugin_options("plugins.a_plugin") == \ - {u"hello": u"world"} + assert cov.config.get_plugin_options("plugins.a_plugin") == {u"hello": u"world"} # Test that our class doesn't reject integers when loading floats self.make_file("pyproject.toml", """\ @@ -233,8 +232,7 @@ class ConfigTest(CoverageTest): cov = coverage.Coverage() assert cov.config.data_file == "hello-world.fooey" assert cov.config.branch is True - assert cov.config.exclude_list == \ - ["the_$one", "anotherZZZ", "xZZZy", "xy", "huh${X}what"] + assert cov.config.exclude_list == ["the_$one", "anotherZZZ", "xZZZy", "xy", "huh${X}what"] def test_environment_vars_in_toml_config(self): # Config files can have $envvars in them. @@ -257,8 +255,7 @@ class ConfigTest(CoverageTest): cov = coverage.Coverage() assert cov.config.data_file == "hello-world.fooey" assert cov.config.branch is True - assert cov.config.exclude_list == \ - ["the_$one", "anotherZZZ", "xZZZy", "xy", "huh${X}what"] + assert cov.config.exclude_list == ["the_$one", "anotherZZZ", "xZZZy", "xy", "huh${X}what"] def test_tilde_in_config(self): # Config entries that are file paths can be tilde-expanded. diff --git a/tests/test_data.py b/tests/test_data.py index 4eda1873..789bdd5a 100644 --- a/tests/test_data.py +++ b/tests/test_data.py @@ -209,8 +209,7 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): covdata = CoverageData() covdata.set_context('test_a') covdata.add_lines(LINES_1) - assert covdata.contexts_by_lineno('a.py') == \ - {1: ['test_a'], 2: ['test_a']} + assert covdata.contexts_by_lineno('a.py') == {1: ['test_a'], 2: ['test_a']} def test_no_duplicate_lines(self): covdata = CoverageData() @@ -251,8 +250,8 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): covdata = CoverageData() covdata.set_context('test_x') covdata.add_arcs(ARCS_3) - assert covdata.contexts_by_lineno('x.py') == \ - {-1: ['test_x'], 1: ['test_x'], 2: ['test_x'], 3: ['test_x']} + expected = {-1: ['test_x'], 1: ['test_x'], 2: ['test_x'], 3: ['test_x']} + assert expected == covdata.contexts_by_lineno('x.py') def test_contexts_by_lineno_with_unknown_file(self): covdata = CoverageData() @@ -587,9 +586,12 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest): covdata2.read() self.assert_line_counts(covdata2, SUMMARY_1) - assert re.search(r"^Erasing data file '.*\.coverage'\n" \ - r"Creating data file '.*\.coverage'\n" \ - r"Opening data file '.*\.coverage'\n$", debug.get_output()) + assert re.search( + r"^Erasing data file '.*\.coverage'\n" + r"Creating data file '.*\.coverage'\n" + r"Opening data file '.*\.coverage'\n$", + debug.get_output() + ) def test_debug_output_without_debug_option(self): # With a debug object, but not the dataio option, we don't get debug diff --git a/tests/test_debug.py b/tests/test_debug.py index 42d7945e..16669407 100644 --- a/tests/test_debug.py +++ b/tests/test_debug.py @@ -176,9 +176,8 @@ class DebugTraceTest(CoverageTest): """.split() for label in labels: label_pat = r"^\s*%s: " % label - assert len(re_lines(out_lines, label_pat).splitlines()) == \ - 1, \ - "Incorrect lines for %r" % label + msg = "Incorrect lines for %r" % label + assert 1 == len(re_lines(out_lines, label_pat).splitlines()), msg def test_debug_sys(self): out_lines = self.f1_debug_output(["sys"]) @@ -190,9 +189,8 @@ class DebugTraceTest(CoverageTest): """.split() for label in labels: label_pat = r"^\s*%s: " % label - assert len(re_lines(out_lines, label_pat).splitlines()) == \ - 1, \ - "Incorrect lines for %r" % label + msg = "Incorrect lines for %r" % label + assert 1 == len(re_lines(out_lines, label_pat).splitlines()), msg def test_debug_sys_ctracer(self): out_lines = self.f1_debug_output(["sys"]) diff --git a/tests/test_execfile.py b/tests/test_execfile.py index 77527478..db78d0f6 100644 --- a/tests/test_execfile.py +++ b/tests/test_execfile.py @@ -39,8 +39,7 @@ class RunFileTest(CoverageTest): assert dunder_file == "try_execfile.py" # It should have its correct module data. - assert mod_globs['__doc__'].splitlines()[0] == \ - "Test file for run_python_file." + assert mod_globs['__doc__'].splitlines()[0] == "Test file for run_python_file." assert mod_globs['DATA'] == "xyzzy" assert mod_globs['FN_VAL'] == "my_fn('fooey')" diff --git a/tests/test_files.py b/tests/test_files.py index 1e0ddcfb..6a9556ec 100644 --- a/tests/test_files.py +++ b/tests/test_files.py @@ -66,8 +66,7 @@ class FilesTest(CoverageTest): assert canonical_path == self.abs_path('file1.py') # After the filename has been converted, it should be in the cache. assert 'sub/proj1/file1.py' in files.CANONICAL_FILENAME_CACHE - assert files.canonical_filename('sub/proj1/file1.py') == \ - self.abs_path('file1.py') + assert files.canonical_filename('sub/proj1/file1.py') == self.abs_path('file1.py') @pytest.mark.parametrize("original, flat", [ @@ -148,8 +147,8 @@ class MatcherTest(CoverageTest): def assertMatches(self, matcher, filepath, matches): """The `matcher` should agree with `matches` about `filepath`.""" canonical = files.canonical_filename(filepath) - assert matcher.match(canonical) == matches, \ - "File %s should have matched as %s" % (filepath, matches) + msg = "File %s should have matched as %s" % (filepath, matches) + assert matches == matcher.match(canonical), msg def test_tree_matcher(self): matches_to_try = [ @@ -187,12 +186,9 @@ class MatcherTest(CoverageTest): ] modules = ['test', 'py.test', 'mymain'] mm = ModuleMatcher(modules) - assert mm.info() == \ - modules + assert mm.info() == modules for modulename, matches in matches_to_try: - assert mm.match(modulename) == \ - matches, \ - modulename + assert mm.match(modulename) == matches, modulename def test_fnmatch_matcher(self): matches_to_try = [ diff --git a/tests/test_html.py b/tests/test_html.py index 59cda0d4..ee2eb575 100644 --- a/tests/test_html.py +++ b/tests/test_html.py @@ -309,20 +309,20 @@ class HtmlTitleTest(HtmlTestHelpers, CoverageTest): self.make_file(".coveragerc", "[html]\ntitle = «ταБЬℓσ» numbers") self.run_coverage() index = self.get_html_index_content() - assert "«ταБЬℓσ»" \ - " numbers" in index - assert "<h1>«ταБЬℓσ»" \ - " numbers" in index + assert "<title>«ταБЬℓσ» numbers" in index + assert "<h1>«ταБЬℓσ» numbers" in index def test_title_set_in_args(self): self.create_initial_files() self.make_file(".coveragerc", "[html]\ntitle = Good title\n") self.run_coverage(htmlargs=dict(title="«ταБЬℓσ» & stüff!")) index = self.get_html_index_content() - assert "<title>«ταБЬℓσ»" \ - " & stüff!" in index - assert "

«ταБЬℓσ»" \ - " & stüff!:" in index + expected = ( + "«ταБЬℓσ» " + + "& stüff!" + ) + assert expected in index + assert "

«ταБЬℓσ» & stüff!:" in index class HtmlWithUnparsableFilesTest(HtmlTestHelpers, CoverageTest): @@ -345,15 +345,11 @@ class HtmlWithUnparsableFilesTest(HtmlTestHelpers, CoverageTest): self.start_import_stop(cov, "main") self.make_file("innocuous.py", "

This isn't python!

") cov.html_report(ignore_errors=True) - assert len(cov._warnings) == \ - 1, \ - "Expected a warning to be thrown when an invalid python file is parsed" - assert "Couldn't parse Python file" in \ - cov._warnings[0], \ - "Warning message should be in 'invalid file' warning" - assert "innocuous.py" in \ - cov._warnings[0], \ - "Filename should be in 'invalid file' warning" + msg = "Expected a warning to be thrown when an invalid python file is parsed" + assert 1 == len(cov._warnings), msg + msg = "Warning message should be in 'invalid file' warning" + assert "Couldn't parse Python file" in cov._warnings[0], msg + assert "innocuous.py" in cov._warnings[0], "Filename should be in 'invalid file' warning" self.assert_exists("htmlcov/index.html") # This would be better as a glob, if the HTML layout changes: self.assert_doesnt_exist("htmlcov/innocuous.html") diff --git a/tests/test_numbits.py b/tests/test_numbits.py index 8216b628..fc27a093 100644 --- a/tests/test_numbits.py +++ b/tests/test_numbits.py @@ -121,10 +121,12 @@ class NumbitsSqliteFunctionTest(CoverageTest): "(select numbits from data where id = 9)" ")" ) + expected = [ + 7, 9, 14, 18, 21, 27, 28, 35, 36, 42, 45, 49, + 54, 56, 63, 70, 72, 77, 81, 84, 90, 91, 98, 99, + ] answer = numbits_to_nums(list(res)[0][0]) - assert [7, 9, 14, 18, 21, 27, 28, 35, 36, 42, 45, 49, - 54, 56, 63, 70, 72, 77, 81, 84, 90, 91, 98, 99] == \ - answer + assert expected == answer def test_numbits_intersection(self): res = self.cursor.execute( diff --git a/tests/test_oddball.py b/tests/test_oddball.py index 46c22f9c..afbf232a 100644 --- a/tests/test_oddball.py +++ b/tests/test_oddball.py @@ -130,8 +130,7 @@ class RecursionTest(CoverageTest): # Get a warning about the stackoverflow effect on the tracing function. if pytrace: # pragma: no metacov - assert cov._warnings == \ - ["Trace function changed, measurement is likely wrong: None"] + assert cov._warnings == ["Trace function changed, measurement is likely wrong: None"] else: assert cov._warnings == [] @@ -277,8 +276,8 @@ class PyexpatTest(CoverageTest): # Make sure pyexpat isn't recorded as a source file. # https://github.com/nedbat/coveragepy/issues/419 files = cov.get_data().measured_files() - assert not any(f.endswith("pyexpat.c") for f in files), \ - "Pyexpat.c is in the measured files!: %r:" % (files,) + msg = "Pyexpat.c is in the measured files!: %r:" % (files,) + assert not any(f.endswith("pyexpat.c") for f in files), msg class ExceptionTest(CoverageTest): @@ -485,14 +484,13 @@ class GettraceTest(CoverageTest): ) out = self.stdout().replace(self.last_module_name, "coverage_test") - - assert out == \ - ( - "call: coverage_test.py @ 10\n" - "line: coverage_test.py @ 11\n" - "line: coverage_test.py @ 12\n" - "return: coverage_test.py @ 12\n" - ) + expected = ( + "call: coverage_test.py @ 10\n" + "line: coverage_test.py @ 11\n" + "line: coverage_test.py @ 12\n" + "return: coverage_test.py @ 12\n" + ) + assert expected == out @pytest.mark.expensive def test_atexit_gettrace(self): # pragma: no metacov diff --git a/tests/test_parser.py b/tests/test_parser.py index 14950c3d..6edb6d1a 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -254,19 +254,24 @@ class ParserMissingArcDescriptionTest(CoverageTest): thing(12) more_stuff(13) """) - assert parser.missing_arc_description(1, 2) == \ - "line 1 didn't jump to line 2, because the condition on line 1 was never true" - assert parser.missing_arc_description(1, 3) == \ - "line 1 didn't jump to line 3, because the condition on line 1 was never false" - assert parser.missing_arc_description(6, -5) == \ - "line 6 didn't return from function 'func5', " \ - "because the loop on line 6 didn't complete" - assert parser.missing_arc_description(6, 7) == \ - "line 6 didn't jump to line 7, because the loop on line 6 never started" - assert parser.missing_arc_description(11, 12) == \ - "line 11 didn't jump to line 12, because the condition on line 11 was never true" - assert parser.missing_arc_description(11, 13) == \ - "line 11 didn't jump to line 13, because the condition on line 11 was never false" + expected = "line 1 didn't jump to line 2, because the condition on line 1 was never true" + assert expected == parser.missing_arc_description(1, 2) + expected = "line 1 didn't jump to line 3, because the condition on line 1 was never false" + assert expected == parser.missing_arc_description(1, 3) + expected = ( + "line 6 didn't return from function 'func5', " + + "because the loop on line 6 didn't complete" + ) + assert expected == parser.missing_arc_description(6, -5) + expected = "line 6 didn't jump to line 7, because the loop on line 6 never started" + assert expected == parser.missing_arc_description(6, 7) + expected = "line 11 didn't jump to line 12, because the condition on line 11 was never true" + assert expected == parser.missing_arc_description(11, 12) + expected = ( + "line 11 didn't jump to line 13, " + + "because the condition on line 11 was never false" + ) + assert expected == parser.missing_arc_description(11, 13) def test_missing_arc_descriptions_for_small_callables(self): parser = self.parse_text(u"""\ @@ -278,14 +283,14 @@ class ParserMissingArcDescriptionTest(CoverageTest): ] x = 7 """) - assert parser.missing_arc_description(2, -2) == \ - "line 2 didn't finish the lambda on line 2" - assert parser.missing_arc_description(3, -3) == \ - "line 3 didn't finish the generator expression on line 3" - assert parser.missing_arc_description(4, -4) == \ - "line 4 didn't finish the dictionary comprehension on line 4" - assert parser.missing_arc_description(5, -5) == \ - "line 5 didn't finish the set comprehension on line 5" + expected = "line 2 didn't finish the lambda on line 2" + assert expected == parser.missing_arc_description(2, -2) + expected = "line 3 didn't finish the generator expression on line 3" + assert expected == parser.missing_arc_description(3, -3) + expected = "line 4 didn't finish the dictionary comprehension on line 4" + assert expected == parser.missing_arc_description(4, -4) + expected = "line 5 didn't finish the set comprehension on line 5" + assert expected == parser.missing_arc_description(5, -5) def test_missing_arc_descriptions_for_exceptions(self): parser = self.parse_text(u"""\ @@ -296,10 +301,16 @@ class ParserMissingArcDescriptionTest(CoverageTest): except ValueError: print("yikes") """) - assert parser.missing_arc_description(3, 4) == \ - "line 3 didn't jump to line 4, because the exception caught by line 3 didn't happen" - assert parser.missing_arc_description(5, 6) == \ - "line 5 didn't jump to line 6, because the exception caught by line 5 didn't happen" + expected = ( + "line 3 didn't jump to line 4, " + + "because the exception caught by line 3 didn't happen" + ) + assert expected == parser.missing_arc_description(3, 4) + expected = ( + "line 5 didn't jump to line 6, " + + "because the exception caught by line 5 didn't happen" + ) + assert expected == parser.missing_arc_description(5, 6) def test_missing_arc_descriptions_for_finally(self): parser = self.parse_text(u"""\ @@ -324,36 +335,56 @@ class ParserMissingArcDescriptionTest(CoverageTest): that_thing(19) """) if env.PYBEHAVIOR.finally_jumps_back: - assert parser.missing_arc_description(18, 5) == \ - "line 18 didn't jump to line 5, because the break on line 5 wasn't executed" - assert parser.missing_arc_description(5, 19) == \ - "line 5 didn't jump to line 19, because the break on line 5 wasn't executed" - assert parser.missing_arc_description(18, 10) == \ - "line 18 didn't jump to line 10, because the continue on line 10 wasn't executed" - assert parser.missing_arc_description(10, 2) == \ - "line 10 didn't jump to line 2, because the continue on line 10 wasn't executed" - assert parser.missing_arc_description(18, 14) == \ - "line 18 didn't jump to line 14, because the return on line 14 wasn't executed" - assert parser.missing_arc_description(14, -1) == \ - "line 14 didn't return from function 'function', " \ - "because the return on line 14 wasn't executed" - assert parser.missing_arc_description(18, -1) == \ - "line 18 didn't except from function 'function', " \ - "because the raise on line 16 wasn't executed" + expected = "line 18 didn't jump to line 5, because the break on line 5 wasn't executed" + assert expected == parser.missing_arc_description(18, 5) + expected = "line 5 didn't jump to line 19, because the break on line 5 wasn't executed" + assert expected == parser.missing_arc_description(5, 19) + expected = ( + "line 18 didn't jump to line 10, " + + "because the continue on line 10 wasn't executed" + ) + assert expected == parser.missing_arc_description(18, 10) + expected = ( + "line 10 didn't jump to line 2, " + + "because the continue on line 10 wasn't executed" + ) + assert expected == parser.missing_arc_description(10, 2) + expected = ( + "line 18 didn't jump to line 14, " + + "because the return on line 14 wasn't executed" + ) + assert expected == parser.missing_arc_description(18, 14) + expected = ( + "line 14 didn't return from function 'function', " + + "because the return on line 14 wasn't executed" + ) + assert expected == parser.missing_arc_description(14, -1) + expected = ( + "line 18 didn't except from function 'function', " + + "because the raise on line 16 wasn't executed" + ) + assert expected == parser.missing_arc_description(18, -1) else: - assert parser.missing_arc_description(18, 19) == \ - "line 18 didn't jump to line 19, because the break on line 5 wasn't executed" - assert parser.missing_arc_description(18, 2) == \ - "line 18 didn't jump to line 2, " \ - "because the continue on line 10 wasn't executed" \ - " or " \ + expected = ( + "line 18 didn't jump to line 19, " + + "because the break on line 5 wasn't executed" + ) + assert expected == parser.missing_arc_description(18, 19) + expected = ( + "line 18 didn't jump to line 2, " + + "because the continue on line 10 wasn't executed" + + " or " + "the continue on line 12 wasn't executed" - assert parser.missing_arc_description(18, -1) == \ - "line 18 didn't except from function 'function', " \ - "because the raise on line 16 wasn't executed" \ - " or " \ - "line 18 didn't return from function 'function', " \ + ) + assert expected == parser.missing_arc_description(18, 2) + expected = ( + "line 18 didn't except from function 'function', " + + "because the raise on line 16 wasn't executed" + + " or " + + "line 18 didn't return from function 'function', " + "because the return on line 14 wasn't executed" + ) + assert expected == parser.missing_arc_description(18, -1) def test_missing_arc_descriptions_bug460(self): parser = self.parse_text(u"""\ @@ -364,8 +395,7 @@ class ParserMissingArcDescriptionTest(CoverageTest): } x = 6 """) - assert parser.missing_arc_description(2, -3) == \ - "line 3 didn't finish the lambda on line 3" + assert parser.missing_arc_description(2, -3) == "line 3 didn't finish the lambda on line 3" class ParserFileTest(CoverageTest): @@ -396,9 +426,7 @@ class ParserFileTest(CoverageTest): fname = fname + ".py" self.make_file(fname, text, newline=newline) parser = self.parse_file(fname) - assert parser.exit_counts() == \ - counts, \ - "Wrong for %r" % fname + assert parser.exit_counts() == counts, "Wrong for %r" % fname def test_encoding(self): self.make_file("encoded.py", """\ diff --git a/tests/test_phystokens.py b/tests/test_phystokens.py index 26a72d28..c7375cb5 100644 --- a/tests/test_phystokens.py +++ b/tests/test_phystokens.py @@ -130,9 +130,7 @@ class SourceEncodingTest(CoverageTest): def test_detect_source_encoding(self): for _, source, expected in ENCODING_DECLARATION_SOURCES: - assert source_encoding(source) == \ - expected, \ - "Wrong encoding in %r" % source + assert source_encoding(source) == expected, "Wrong encoding in %r" % source def test_detect_source_encoding_not_in_comment(self): if env.PYPY3: # pragma: no metacov @@ -196,9 +194,7 @@ class NeuterEncodingDeclarationTest(CoverageTest): # The neutered source will be detected as having no encoding # declaration. - assert source_encoding(neutered) == \ - DEF_ENCODING, \ - "Wrong encoding in %r" % neutered + assert source_encoding(neutered) == DEF_ENCODING, "Wrong encoding in %r" % neutered def test_two_encoding_declarations(self): input_src = textwrap.dedent(u"""\ diff --git a/tests/test_plugins.py b/tests/test_plugins.py index 12ce7c1e..f53de4fb 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -1050,8 +1050,8 @@ class DynamicContextPluginTest(CoverageTest): # Labeled coverage is collected data = cov.get_data() filenames = self.get_measured_filenames(data) - assert ['', 'doctest:HTML_TAG', 'test:HTML_TAG', 'test:RENDERERS'] == \ - sorted(data.measured_contexts()) + expected = ['', 'doctest:HTML_TAG', 'test:HTML_TAG', 'test:RENDERERS'] + assert expected == sorted(data.measured_contexts()) data.set_query_context("doctest:HTML_TAG") assert [2] == data.lines(filenames['rendering.py']) data.set_query_context("test:HTML_TAG") diff --git a/tests/test_process.py b/tests/test_process.py index 8362c1e1..536199db 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -611,8 +611,10 @@ class ProcessTest(CoverageTest): assert "Exception" not in out out = self.run_command("coverage run -m no_such_module") - assert ("No module named no_such_module" in out) or \ + assert ( + ("No module named no_such_module" in out) or ("No module named 'no_such_module'" in out) + ) assert "warning" not in out assert "Exception" not in out @@ -825,11 +827,13 @@ class ProcessTest(CoverageTest): inst.save() """) out = self.run_command("python run_twice.py") - assert out == \ - "Run 1\n" \ - "Run 2\n" \ - "Coverage.py warning: Module foo was previously imported, but not measured " \ + expected = ( + "Run 1\n" + + "Run 2\n" + + "Coverage.py warning: Module foo was previously imported, but not measured " + "(module-not-measured)\n" + ) + assert expected == out def test_module_name(self): # https://github.com/nedbat/coveragepy/issues/478 @@ -1256,15 +1260,15 @@ class FailUnderTest(CoverageTest): def test_report_43_is_not_ok(self): st, out = self.run_command_status("coverage report --fail-under=44") assert st == 2 - assert self.last_line_squeezed(out) == \ - "Coverage failure: total of 43 is less than fail-under=44" + expected = "Coverage failure: total of 43 is less than fail-under=44" + assert expected == self.last_line_squeezed(out) def test_report_42p86_is_not_ok(self): self.make_file(".coveragerc", "[report]\nprecision = 2") st, out = self.run_command_status("coverage report --fail-under=42.88") assert st == 2 - assert self.last_line_squeezed(out) == \ - "Coverage failure: total of 42.86 is less than fail-under=42.88" + expected = "Coverage failure: total of 42.86 is less than fail-under=42.88" + assert expected == self.last_line_squeezed(out) class FailUnderNoFilesTest(CoverageTest): @@ -1550,9 +1554,11 @@ class ProcessStartupTest(ProcessCoverageMixin, CoverageTest): # assert that there are *no* extra data files left over after a combine data_files = glob.glob(os.getcwd() + '/.coverage*') - assert len(data_files) == 1, \ - "Expected only .coverage after combine, looks like there are " \ + msg = ( + "Expected only .coverage after combine, looks like there are " + "extra data files that were not cleaned up: %r" % data_files + ) + assert len(data_files) == 1, msg class ProcessStartupWithSourceTest(ProcessCoverageMixin, CoverageTest): diff --git a/tests/test_summary.py b/tests/test_summary.py index 1d74af9c..e3694000 100644 --- a/tests/test_summary.py +++ b/tests/test_summary.py @@ -562,8 +562,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest): errmsg = re.sub(r"parse '.*mycode.py", "parse 'mycode.py", errmsg) # The actual error message varies version to version errmsg = re.sub(r": '.*' at", ": 'error' at", errmsg) - assert "Couldn't parse 'mycode.py' as Python source: 'error' at line 1" == \ - errmsg + assert errmsg == "Couldn't parse 'mycode.py' as Python source: 'error' at line 1" def test_accenteddotpy_not_python(self): if env.JYTHON: @@ -923,8 +922,8 @@ class TestSummaryReporterConfiguration(CoverageTest): """Assert that the `words` appear in order in `text`.""" indexes = list(map(text.find, words)) assert -1 not in indexes - assert indexes == sorted(indexes), \ - "The words %r don't appear in order in %r" % (words, text) + msg = "The words %r don't appear in order in %r" % (words, text) + assert indexes == sorted(indexes), msg def test_sort_report_by_stmts(self): # Sort the text report by the Stmts column. diff --git a/tests/test_templite.py b/tests/test_templite.py index 8d808554..770e97f9 100644 --- a/tests/test_templite.py +++ b/tests/test_templite.py @@ -55,8 +55,7 @@ class TempliteTest(CoverageTest): def test_passthrough(self): # Strings without variables are passed through unchanged. assert Templite("Hello").render() == "Hello" - assert Templite("Hello, 20% fun time!").render() == \ - "Hello, 20% fun time!" + assert Templite("Hello, 20% fun time!").render() == "Hello, 20% fun time!" def test_variables(self): # Variables use {{var}} syntax. diff --git a/tests/test_version.py b/tests/test_version.py index ce2e88e6..00d65624 100644 --- a/tests/test_version.py +++ b/tests/test_version.py @@ -29,7 +29,6 @@ class VersionTest(CoverageTest): assert _make_version(5, 10, 2, 'candidate', 7) == "5.10.2rc7" def test_make_url(self): - assert _make_url(4, 0, 0, 'final', 0) == \ - "https://coverage.readthedocs.io" - assert _make_url(4, 1, 2, 'beta', 3) == \ - "https://coverage.readthedocs.io/en/coverage-4.1.2b3" + assert _make_url(4, 0, 0, 'final', 0) == "https://coverage.readthedocs.io" + expected = "https://coverage.readthedocs.io/en/coverage-4.1.2b3" + assert _make_url(4, 1, 2, 'beta', 3) == expected diff --git a/tests/test_xml.py b/tests/test_xml.py index 15f07698..13e015d6 100644 --- a/tests/test_xml.py +++ b/tests/test_xml.py @@ -275,8 +275,7 @@ class XmlPackageStructureTest(XmlTestHelpers, CoverageTest): def assert_package_and_class_tags(self, cov, result): """Check the XML package and class tags from `cov` match `result`.""" - assert unbackslash(list(self.package_and_class_tags(cov))) == \ - unbackslash(result) + assert unbackslash(list(self.package_and_class_tags(cov))) == unbackslash(result) def test_package_names(self): self.make_tree(width=1, depth=3) -- cgit v1.2.1 From f18dd6884665f915868d199917075682f7e2e151 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Sun, 31 Jan 2021 11:13:54 -0500 Subject: test: configure pytest assertion rewriting in coveragetest.py --- tests/conftest.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tests') diff --git a/tests/conftest.py b/tests/conftest.py index 10761cdd..c2e0a893 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -16,6 +16,10 @@ import pytest from coverage import env +# Pytest will rewrite assertions in test modules, but not elsewhere. +# This tells pytest to also rewrite assertions in coveragetest.py. +pytest.register_assert_rewrite("tests.coveragetest") + # Pytest can take additional options: # $set_env.py: PYTEST_ADDOPTS - Extra arguments to pytest. -- cgit v1.2.1 From bf29fdcf295b32e88a7407c244a5c703f0499ca9 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Sun, 31 Jan 2021 11:31:43 -0500 Subject: test: keep multi-assert arc diffs working We don't have a way to do multi-assert in the pytest we're running, so cobble it together ourselves. --- tests/coveragetest.py | 46 +++++++++++++++++++++++----------------------- tests/test_arcs.py | 4 ---- 2 files changed, 23 insertions(+), 27 deletions(-) (limited to 'tests') diff --git a/tests/coveragetest.py b/tests/coveragetest.py index f7a5f6f8..c4a46da9 100644 --- a/tests/coveragetest.py +++ b/tests/coveragetest.py @@ -5,6 +5,7 @@ import contextlib import datetime +import difflib import functools import glob import os @@ -16,10 +17,7 @@ import sys import types import pytest -from unittest_mixins import ( - EnvironmentAwareMixin, StdStreamCapturingMixin, TempDirMixin, - DelayedAssertionMixin, -) +from unittest_mixins import EnvironmentAwareMixin, StdStreamCapturingMixin, TempDirMixin import coverage from coverage import env @@ -67,7 +65,6 @@ class CoverageTest( EnvironmentAwareMixin, StdStreamCapturingMixin, TempDirMixin, - DelayedAssertionMixin, CoverageTestMethodsMixin, TestCase, ): @@ -134,12 +131,22 @@ class CoverageTest( self.last_module_name = 'coverage_test_' + str(random.random())[2:] return self.last_module_name - def _assert_equal_arcs(self, a1, a2, msg=None): - """Assert that the arc lists `a1` and `a2` are equal.""" + def _check_arcs(self, a1, a2, arc_type): + """Check that the arc lists `a1` and `a2` are equal. + + If they are equal, return empty string. If they are unequal, return + a string explaining what is different. + """ # Make them into multi-line strings so we can see what's going wrong. s1 = arcs_to_arcz_repr(a1) s2 = arcs_to_arcz_repr(a2) - assert s1 == s2, msg + if s1 != s2: + lines1 = s1.splitlines(keepends=True) + lines2 = s2.splitlines(keepends=True) + diff = "".join(difflib.ndiff(lines1, lines2)) + return "\n" + arc_type + " arcs differ: minus is expected, plus is actual\n" + diff + else: + return "" def check_coverage( self, text, lines=None, missing="", report="", @@ -225,21 +232,14 @@ class CoverageTest( # print(" actual:", analysis.arc_possibilities()) # print("Executed:") # print(" actual:", sorted(set(analysis.arcs_executed()))) - with self.delayed_assertions(): - self._assert_equal_arcs( - arcs, analysis.arc_possibilities(), - "Possible arcs differ: minus is expected, plus is actual" - ) - - self._assert_equal_arcs( - arcs_missing, analysis.arcs_missing(), - "Missing arcs differ: minus is expected, plus is actual" - ) - - self._assert_equal_arcs( - arcs_unpredicted, analysis.arcs_unpredicted(), - "Unpredicted arcs differ: minus is expected, plus is actual" - ) + # TODO: this would be nicer with pytest-check, once we can run that. + msg = ( + self._check_arcs(arcs, analysis.arc_possibilities(), "Possible") + + self._check_arcs(arcs_missing, analysis.arcs_missing(), "Missing") + + self._check_arcs(arcs_unpredicted, analysis.arcs_unpredicted(), "Unpredicted") + ) + if msg: + assert False, msg if report: frep = StringIO() diff --git a/tests/test_arcs.py b/tests/test_arcs.py index 2f49ecfb..3b63bcc2 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -270,13 +270,10 @@ class LoopArcTest(CoverageTest): # With "while 1", the loop knows it's constant. if env.PYBEHAVIOR.keep_constant_test: arcz = ".1 12 23 34 45 36 62 57 7." - arcz_missing = "" elif env.PYBEHAVIOR.nix_while_true: arcz = ".1 13 34 45 36 63 57 7." - arcz_missing = "" else: arcz = ".1 12 23 34 45 36 63 57 7." - arcz_missing = "" self.check_coverage("""\ a, i = 1, 0 while 1: @@ -287,7 +284,6 @@ class LoopArcTest(CoverageTest): assert a == 4 and i == 3 """, arcz=arcz, - arcz_missing=arcz_missing, ) def test_while_true(self): -- cgit v1.2.1