|
| 1 | +# -*- coding: utf-8 -*- |
1 | 2 | import sys
|
2 | 3 |
|
3 | 4 | import _pytest._code
|
@@ -514,11 +515,20 @@ def test_pyargs_importerror(self, testdir, monkeypatch):
|
514 | 515 |
|
515 | 516 | result = testdir.runpytest("--pyargs", "tpkg.test_hello")
|
516 | 517 | assert result.ret != 0
|
517 |
| - # FIXME: It would be more natural to match NOT |
518 |
| - # "ERROR*file*or*package*not*found*". |
519 |
| - result.stdout.fnmatch_lines([ |
520 |
| - "*collected 0 items*" |
521 |
| - ]) |
| 518 | + |
| 519 | + # Depending on whether the process running the test is the |
| 520 | + # same as the process parsing the command-line arguments, the |
| 521 | + # type of failure can be different: |
| 522 | + if result.stderr.str() == '': |
| 523 | + # Different processes |
| 524 | + result.stdout.fnmatch_lines([ |
| 525 | + "collected*0*items*/*1*errors" |
| 526 | + ]) |
| 527 | + else: |
| 528 | + # Same process |
| 529 | + result.stderr.fnmatch_lines([ |
| 530 | + "ERROR:*file*or*package*not*found:*tpkg.test_hello" |
| 531 | + ]) |
522 | 532 |
|
523 | 533 | def test_cmdline_python_package(self, testdir, monkeypatch):
|
524 | 534 | monkeypatch.delenv('PYTHONDONTWRITEBYTECODE', False)
|
@@ -557,6 +567,68 @@ def join_pythonpath(what):
|
557 | 567 | "*not*found*test_hello*",
|
558 | 568 | ])
|
559 | 569 |
|
| 570 | + def test_cmdline_python_namespace_package(self, testdir, monkeypatch): |
| 571 | + """ |
| 572 | + test --pyargs option with namespace packages (#1567) |
| 573 | + """ |
| 574 | + monkeypatch.delenv('PYTHONDONTWRITEBYTECODE', raising=False) |
| 575 | + |
| 576 | + search_path = [] |
| 577 | + for dirname in "hello", "world": |
| 578 | + d = testdir.mkdir(dirname) |
| 579 | + search_path.append(d) |
| 580 | + ns = d.mkdir("ns_pkg") |
| 581 | + ns.join("__init__.py").write( |
| 582 | + "__import__('pkg_resources').declare_namespace(__name__)") |
| 583 | + lib = ns.mkdir(dirname) |
| 584 | + lib.ensure("__init__.py") |
| 585 | + lib.join("test_{0}.py".format(dirname)). \ |
| 586 | + write("def test_{0}(): pass\n" |
| 587 | + "def test_other():pass".format(dirname)) |
| 588 | + |
| 589 | + # The structure of the test directory is now: |
| 590 | + # . |
| 591 | + # ├── hello |
| 592 | + # │ └── ns_pkg |
| 593 | + # │ ├── __init__.py |
| 594 | + # │ └── hello |
| 595 | + # │ ├── __init__.py |
| 596 | + # │ └── test_hello.py |
| 597 | + # └── world |
| 598 | + # └── ns_pkg |
| 599 | + # ├── __init__.py |
| 600 | + # └── world |
| 601 | + # ├── __init__.py |
| 602 | + # └── test_world.py |
| 603 | + |
| 604 | + def join_pythonpath(*dirs): |
| 605 | + cur = py.std.os.environ.get('PYTHONPATH') |
| 606 | + if cur: |
| 607 | + dirs += (cur,) |
| 608 | + return ':'.join(str(p) for p in dirs) |
| 609 | + monkeypatch.setenv('PYTHONPATH', join_pythonpath(*search_path)) |
| 610 | + for p in search_path: |
| 611 | + monkeypatch.syspath_prepend(p) |
| 612 | + |
| 613 | + # mixed module and filenames: |
| 614 | + result = testdir.runpytest("--pyargs", "-v", "ns_pkg.hello", "world/ns_pkg") |
| 615 | + assert result.ret == 0 |
| 616 | + result.stdout.fnmatch_lines([ |
| 617 | + "*test_hello.py::test_hello*PASSED", |
| 618 | + "*test_hello.py::test_other*PASSED", |
| 619 | + "*test_world.py::test_world*PASSED", |
| 620 | + "*test_world.py::test_other*PASSED", |
| 621 | + "*4 passed*" |
| 622 | + ]) |
| 623 | + |
| 624 | + # specify tests within a module |
| 625 | + result = testdir.runpytest("--pyargs", "-v", "ns_pkg.world.test_world::test_other") |
| 626 | + assert result.ret == 0 |
| 627 | + result.stdout.fnmatch_lines([ |
| 628 | + "*test_world.py::test_other*PASSED", |
| 629 | + "*1 passed*" |
| 630 | + ]) |
| 631 | + |
560 | 632 | def test_cmdline_python_package_not_exists(self, testdir):
|
561 | 633 | result = testdir.runpytest("--pyargs", "tpkgwhatv")
|
562 | 634 | assert result.ret
|
@@ -697,4 +769,3 @@ def test_setup_function(self, testdir):
|
697 | 769 | * setup *test_1*
|
698 | 770 | * call *test_1*
|
699 | 771 | """)
|
700 |
| - |
|
0 commit comments