diff options
31 files changed, 1165 insertions, 1294 deletions
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("<pyfile>", lines[0]) - self.assertIn("--timid", out) - self.assertGreater(len(lines), 20) - self.assertEqual(lines[-1], "Full documentation is at {}".format(__url__)) + assert "<pyfile>" 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("<title>Coverage report</title>", index) - self.assertIn("<h1>Coverage report:", index) + assert "<title>Coverage report</title>" in index + assert "<h1>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("<title>Metrics & stuff!</title>", index) - self.assertIn("<h1>Metrics & stuff!:", index) + assert "<title>Metrics & stuff!</title>" in index + assert "<h1>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( - "<title>«ταБЬℓσ»" - " 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!</title>", index - ) - self.assertIn( - "<h1>«ταБЬℓσ»" - " & stüff!:", index - ) + assert "<title>«ταБЬℓσ»" \ + " & stüff!</title>" in index + assert "<h1>«ταБЬℓσ»" \ + " & 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", "<h1>This isn't python!</h1>") 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", "<h1>This isn't python!</h1>") 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", "<h1>This isn't python at all!</h1>") 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 '<code>' 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 '<code>' 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, "<string>", "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('<a href="hât_py.html">hât.py</a>', index) + assert '<a href="hât_py.html">hât.py</a>' 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('<a href="â_accented_py.html">â%saccented.py</a>' % os.sep, index) + assert '<a href="â_accented_py.html">â%saccented.py</a>' % 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 <module> 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) |