def test_elsewhere_fixture_with_yield_nested(testdir_setup): testdir_setup.makepyfile(test_file=""" import pytest @pytest.fixture def fixie(): class C: def __init__(self): print("in init") # <- line 7 def ran(self): return True c = C() yield c del c def test_foo(fixie): assert fixie.ran() """) pe = testdir_setup.spawn_pytest("--break=test_file.py:7") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines(["*>*/test_file.py(7)__init__()", "->*# <- line 7"]) pe.sendline("c") pe.expect(EOF) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines("*1 passed*")
def test_elsewhere_fixture_double(testdir_setup): testdir_setup.makepyfile(test_file=""" import pytest @pytest.fixture def fixie(): return True # <- line 5 def test_foo(fixie): assert fixie def test_bar(fixie): assert fixie """) pe = testdir_setup.spawn_pytest("--break=test_file.py:5") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines(["*>*/test_file.py(5)fixie()", "->*# <- line 5"]) pe.sendline("c") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines(["*>*/test_file.py(5)fixie()", "->*# <- line 5"]) pe.sendline("c") pe.expect(EOF) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines("*2 passed*")
def test_marked_module_func_nested(testdir): filename = testdir.copy_example("asyncio/test_marked_mod.py") assert filename.exists() pe = testdir.spawn_pytest("--break=test_marked_mod.py:24 " "test_marked_mod.py::test_baz") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines(["*>*(24)inner()*", '*assert x*']) # Ensure previous frames properly hidden pe.sendline("w") pe.expect(prompt_re) assert b")runcall_until" not in pe.before assert b"runcall_until_async" not in pe.before befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines([ "*(26)test_baz()*", "*->*await inner*", "*(24)inner()*", ]) pe.sendline("c") pe.expect(EOF) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines([ "*1 passed*", ])
def test_elsewhere_fixture_parametrize(testdir_setup): # TODO try hard-coding coordinates to show ordering is predictable testdir_setup.makepyfile(test_file=""" import pytest @pytest.fixture(params=["a", "b"]) def fixie(request): spam = request.param # <- line 5 yield spam.upper() del spam def test_foo(fixie): assert fixie in "AB" def test_bar(fixie): assert fixie in "AB" """) pe = testdir_setup.spawn_pytest("--break=test_file.py:5") pairs = [("foo", "a"), ("foo", "b"), ("bar", "a"), ("bar", "b")] for word, letter in pairs: pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines(["*>*/test_file.py(5)fixie()", "->*# <- line 5"]) pe.sendline("request.node.name, request.param") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines([f"*test_{word}*{letter}*{letter}*"]) pe.sendline("c") pe.expect(EOF) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines("*4 passed*")
def test_capsys(testdir_setup, global_cap_method): testdir_setup.makepyfile(r""" def test_print(capsys): import sys print("a:out") print("a:err", file=sys.stderr) assert list(capsys.readouterr()) == ["a:out\n", "a:err\n"] assert True # line 6 print("b:out", flush=True) print("b:err", flush=True, file=sys.stderr) assert list(capsys.readouterr()) == ["b:out\n", "b:err\n"] """) # raw string \n pe = testdir_setup.spawn_pytest("--break=test_capsys.py:6 " "--capture=%s" % global_cap_method) pe.expect(prompt_re) befs = unansi(pe.before) assert "a:out" not in befs lbefs = LineMatcher(befs) lbefs.fnmatch_lines(("*>*/test_capsys.py(6)test_print()", "->*# line 6")) pe.sendline("c") pe.expect(EOF) befs = unansi(pe.before) assert "b:out" not in befs lbefs = LineMatcher(befs) lbefs.fnmatch_lines(["*[[]100%[]]*", "*1 passed*"])
def test_no_bt_all(testdir_setup): testdir_setup.makepyfile(test_file=""" def test_foo(): assert True """) pe = testdir_setup.spawn_pytest("--break=test_file.py:2") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines("*>*/test_file.py(2)test_foo()") pe.sendline("w") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) assert "runcall_until" not in befs.str() befs.fnmatch_lines("*>*/test_file.py(2)test_foo()") pe.sendline("c") pe.expect(EOF)
def test_class_gap_named(testdir_class): pe = testdir_class.spawn_pytest( "--break=test_class_gap_named.py:10 " "test_class_gap_named.py::TestClass::test_two") pe.expect(EOF) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines(["*unable to determine*", "*no tests ran*"])
def test_marked_module_class(testdir): filename = testdir.copy_example("asyncio/test_marked_mod.py") assert filename.exists() pe = testdir.spawn_pytest("--break=test_marked_mod.py:16 " "test_marked_mod.py::TestClass::test_bar") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines( ["*>*(16)test_bar()*", '*assert "asyncio" in request.keywords*']) pe.sendline("c") pe.expect(EOF) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines([ "*1 passed*", ])
def test_marked_module_fixture_after(testdir): filename = testdir.copy_example("asyncio/test_marked_mod.py") assert filename.exists() pe = testdir.spawn_pytest("--break=test_marked_mod.py:38 " "test_marked_mod.py::test_spam") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines(["*>*(38)somefix()*", '*del spam*']) pe.sendline("c") pe.expect(EOF) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines([ "*1 passed*", ])
def test_class_gap(testdir_class): # If a requested line precedes the start of the first test item, an error # is raised; same goes for intervals between items, as shown here pe = testdir_class.spawn_pytest("--break=test_class_gap.py:10") pe.expect(EOF) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines(["*unable to determine*", "*no tests ran*"])
def test_compat_invoke_same_after_baseline(testdir_setup): td = testdir_setup td.makepyfile(test_file=t2f4) pe = td.spawn_pytest("--pdb") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines(["*>*/test_file.py(4)test_foo()", "->*assert False*"]) pe.sendline("c")
def test_class_simple(testdir_class): pe = testdir_class.spawn_pytest("--break=test_class_simple.py:8") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines( ["*>*/test_class_simple.py(8)test_one()", "->*# line 8"]) pe.sendline("c") pe.expect(EOF)
def test_class_early(testdir_class): # Target docstring pe = testdir_class.spawn_pytest("--break=test_class_early.py:5") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines(["*>*/test_class_early.py(8)test_one()", "->*# line 8"]) pe.sendline("c") pe.expect(EOF)
def test_simple(testdir): filename = testdir.copy_example("asyncio/test_simple.py") assert filename.exists() pe = testdir.spawn_pytest("-vvv --break=test_simple.py:19") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines( ["*>*(19)test_bar()*", '*assert "asyncio" in request.keywords*']) pe.sendline("c") pe.expect(EOF) befs = LineMatcher(unansi(pe.before)) # Baz not registered as asyncio test befs.fnmatch_lines([ "*warnings summary*", "*test_simple.py::TestClass::test_baz*", ])
def test_two_funcs_comment(testdir_two_funcs): pe = testdir_two_funcs.spawn_pytest("--break=test_two_funcs_comment.py:2") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines([ "*>*/test_two_funcs_comment.py(3)test_true_int()", "->*somevar = True" ]) pe.sendline("c") pe.expect(EOF)
def test_simple_unknown(testdir): filename = testdir.copy_example("asyncio/test_simple.py") assert filename.exists() pe = testdir.spawn_pytest("--break=test_simple.py:4") pe.expect(EOF) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines([ "*unable to determine breakpoint*", ])
def test_compat_invoke_same_after(testdir_setup): td = testdir_setup td.makepyfile(test_file=""" def test_foo(): assert True # <- line 2 # comment assert False # <- line 4 """) pe = td.spawn_pytest("--break=2 --pdb") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines(["*>*/test_file.py(2)test_foo()", "->*assert True*"]) pe.sendline("c") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines([ "*entering PDB*", "*>*/test_file.py(4)test_foo()", "->*assert False*" ]) pe.sendline("c")
def test_two_funcs_simple(testdir_two_funcs): pe = testdir_two_funcs.spawn_pytest("--break=test_two_funcs_simple.py:4") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines([ "*>*/test_two_funcs_simple.py(4)test_true_int()", "->*# <- line 4", ]) pe.sendline("c") pe.expect(EOF)
def test_simple_nested_async(testdir_simple_nested_async): pe = testdir_simple_nested_async.spawn_pytest( "--break=test_simple_nested_async.py:6") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines([ "*>*/test_simple_nested_async.py(6)inner()", "->*# <- line 6", ]) pe.sendline("c") pe.expect(EOF)
def test_mark_param(testdir_setup): testdir_setup.makepyfile(""" import pytest @pytest.mark.parametrize("name,value", [("one", 1), ("two", 2)]) def test_number(name, value): print(name) assert len(name) > value # line 6 """) pe = testdir_setup.spawn_pytest("--break=test_mark_param.py:6 " "--capture=no") pe.expect(prompt_re) befs = unansi(pe.before) assert "one" in befs pe.sendline("c") pe.expect(prompt_re) befs = unansi(pe.before) assert "two" in befs pe.sendline("c") pe.expect(EOF)
def test_bt_all(testdir_setup): testdir_setup.makepyfile(test_file=""" def test_foo(): assert True """) pe = testdir_setup.spawn_pytest("--break=test_file.py:2 --bt-all") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines("*>*/test_file.py(2)test_foo()") pe.sendline("w") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) # Everythin shown befs.fnmatch_lines([ "*/_pytest/config/__init__.py(*)main()", "*/pytest_pdb_break.py(*)runcall_until()", "*>*/test_file.py(2)test_foo()" ]) pe.sendline("c") pe.expect(EOF)
def test_two_funcs_on(testdir_two_funcs): # On first line (declaration line) of function pe = testdir_two_funcs.spawn_pytest("--break=test_two_funcs_on.py:6") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines([ "*>*/test_two_funcs_on.py(7)test_false_int()", "->*isinstance(False, int)" ]) pe.sendline("c") pe.expect(EOF)
def test_elsewhere_fixture_nested_simple(testdir_setup): testdir_setup.makepyfile(test_file=""" import pytest @pytest.fixture def fixie(): def inner(): return True # <- line 6 return inner() def test_foo(fixie): assert fixie """) pe = testdir_setup.spawn_pytest("--break=test_file.py:6") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines(["*>*/test_file.py(6)inner()", "->*# <- line 6"]) pe.sendline("c") pe.expect(EOF) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines("*1 passed*")
def test_mark_param_quit(testdir_setup): # TODO note regression date range or commit span whenabouts this broke testdir_setup.makepyfile(test_foo=""" import pytest @pytest.mark.parametrize("name", ["one", "two"]) @pytest.mark.parametrize("value", [1, 2]) def test_number(name, value): # comment assert len(name) > value # line 6 """) pe = testdir_setup.spawn_pytest("--break=test_foo.py:7") pe.expect(prompt_re) pe.sendline("name") pe.expect(prompt_re) befs = unansi(pe.before) assert "'one'" in befs pe.sendline("q") pe.expect(EOF) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines(["*4 passed*"])
def test_invalid_arg(testdir_setup): td = testdir_setup td.makepyfile(""" def test_foo(): assert True """) # No line number (argparse error) result = td.runpytest("--break=test_invalid_arg.py") assert result.ret == 4 result.stderr.fnmatch_lines(["*usage:*", "*--break*invalid*value*"]) # Non-existent file result = td.runpytest("--break=foo:99") assert result.ret == 3 result.stdout.fnmatch_lines("INTERNALERROR>*FileNotFoundError*") # TODO usage msg appears in captured stderr but result.stderr is empty # Ambiguous case: no file named, but multiple given td.makepyfile(test_otherfile=""" def test_bar(): assert True def not_a_test(): return 1 """) result = td.runpytest("--break=1") assert result.ret == 3 result.stdout.fnmatch_lines("INTERNALERROR>*RuntimeError: " "unable to determine breakpoint file*") # Invalid line (regression): finder bails if node is None result = td.runpytest("--break=test_otherfile.py:99") assert result.ret == 3 result.stdout.fnmatch_lines("INTERNALERROR>*RuntimeError: " "unable to determine breakpoint location*") # No file named, but pytest arg names one pe = td.spawn_pytest("--break=1 test_otherfile.py") # <- Two sep args # XXX API call sig is different for these spawning funcs (string) pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines( ["*>*/test_otherfile.py(2)test_bar()", "->*assert True"]) pe.sendline("c") # requested line is adjusted to something breakable pe.expect(EOF) # Provided location is not a test result = td.runpytest("--break=5", "test_otherfile.py") assert result.ret == 3 result.stdout.fnmatch_lines("INTERNALERROR>*RuntimeError: " "*unable to determine*")
def test_elsewhere_fixture_with_yield(testdir_setup, lnum): testdir_setup.makepyfile(test_file=""" import pytest @pytest.fixture def fixie(): somevar = 1 # <- line 5 yield somevar del somevar # <- line 7 def test_foo(fixie): assert fixie """) pe = testdir_setup.spawn_pytest(f"--break=test_file.py:{lnum}") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines( [f"*>*/test_file.py({lnum})fixie()", f"->*# <- line {lnum}"]) pe.sendline("c") pe.expect(EOF) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines("*1 passed*")
def test_completion_commands(testdir_setup): # Note: \x07 is the BEL char testdir_setup.makepyfile(test_file=""" def test_foo(): assert True """) pe = testdir_setup.spawn_pytest("--break=test_file.py:2") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines("*>*/test_file.py(2)test_foo()") pe.send("hel\t") pe.expect("hel\x07?p") pe.send("\n") pe.expect("Documented commands") pe.expect(prompt_re) pe.send("whe\t") pe.expect("whe\x07?re") pe.send("\n") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines("*>*/test_file.py(2)test_foo()") pe.sendline("c")
def test_print_logs(testdir_setup, disabled): import os if not any(e in os.environ for e in ("PDBBRK_LOGYAML", "PDBBRK_LOGFILE")): pytest.skip("Logging helper not enabled") td = testdir_setup # ini turns log capturing OFF via --no-print-logs if not disabled: td.tmpdir.join("tox.ini").remove() td.makepyfile(test_file=t2f4) pe = td.spawn_pytest("--break=1") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines(["*>*/test_file.py(2)test_foo()", "->*assert True*"]) pe.sendline("c") rest = unansi(pe.read()) if disabled: assert "Captured log call" not in rest else: LineMatcher(rest).fnmatch_lines("*Captured log call*")
def test_inner_simple(testdir_setup, bt_all): testdir_setup.makepyfile(test_file=""" def test_foo(): def inner(x): print("inner") # <- line 4 return x + 1 assert inner(1) # <- line 7 assert True """) opts = "--break=test_file.py:4" if bt_all: opts += " --bt-all" pe = testdir_setup.spawn_pytest(opts) pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines(["*>*/test_file.py(4)inner()", "->*# <- line 4"]) # Stack pe.sendline("w") pe.expect(prompt_re) befs = LineMatcher(unansi(pe.before)) if bt_all: befs.fnmatch_lines([ "*/_pytest/config/__init__.py(*)main()", "*/pytest_pdb_break.py(*)runcall_until()", "*/test_file.py(7)test_foo()", "*assert inner(1)*line 7" ]) else: assert "runcall_until" not in befs.str() befs.fnmatch_lines( ["*/test_file.py(7)test_foo()", "*assert inner(1)*line 7"]) pe.sendline("c") pe.expect(EOF) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines("*1 passed*")
def test_inner_never_called(testdir_setup, at_def): testdir_setup.makepyfile(test_file=""" def test_foo(): def inner(x): # <- line 2 print("inner") # <- line 3 return x + 1 assert inner """) # The True case is unfortunate, may warrant switching behavior lnum = (3, 2)[at_def] pe = testdir_setup.spawn_pytest(f"--break=test_file.py:{lnum}") pe.expect(EOF) befs = LineMatcher(unansi(pe.before)) befs.fnmatch_lines("*1 passed*")