diff --git a/doc/example/pythoncollection.txt b/doc/example/pythoncollection.txt index 99b4f5d1e..a39cd169e 100644 --- a/doc/example/pythoncollection.txt +++ b/doc/example/pythoncollection.txt @@ -12,6 +12,18 @@ You can set the :confval:`norecursedirs` option in an ini-file, for example your This would tell py.test to not recurse into typical subversion or sphinx-build directories or into any ``tmp`` prefixed directory. +always try to interpret arguments as Python packages +----------------------------------------------------- + +You can use the ``--pyargs`` option to make py.test try +interpreting arguments as python package names, deriving +their file system path and then running the test. Through +an ini-file and the :confval:`addopts` option you can make +this change more permanently:: + + # content of setup.cfg or tox.ini + [pytest] + addopts = --pyargs finding out what is collected ----------------------------------------------- diff --git a/doc/usage.txt b/doc/usage.txt index 02607ee99..067a6f54b 100644 --- a/doc/usage.txt +++ b/doc/usage.txt @@ -36,7 +36,7 @@ Several test run options:: Import 'pkg' and use its filesystem location to find and run tests:: - py.test --testpkg=pypkg # run all tests found below directory of pypkg + py.test --pyargs pkg # run all tests found below directory of pypkg calling pytest through ``python -m pytest`` ----------------------------------------------------- diff --git a/pytest/plugin/session.py b/pytest/plugin/session.py index e54fbc1d8..a7c3a4724 100644 --- a/pytest/plugin/session.py +++ b/pytest/plugin/session.py @@ -366,9 +366,10 @@ class Collection(FSCollector): self.trace.root.indent += 1 self._notfound = [] self._initialpaths = set() - self._initialargs = args + self._initialparts = [] for arg in args: parts = self._parsearg(arg) + self._initialparts.append(parts) self._initialpaths.add(parts[0]) self.ihook.pytest_collectstart(collector=self) rep = self.ihook.pytest_make_collect_report(collector=self) @@ -376,7 +377,7 @@ class Collection(FSCollector): self.trace.root.indent -= 1 if self._notfound: for arg, exc in self._notfound: - line = "no name %r in any of %r" % (exc.args[1], exc.args[0]) + line = "(no name %r in any of %r)" % (arg, exc.args[0]) raise pytest.UsageError("not found: %s\n%s" %(arg, line)) if not genitems: return rep.result @@ -388,8 +389,9 @@ class Collection(FSCollector): return items def collect(self): - for arg in self._initialargs: - self.trace("processing arg", arg) + for parts in self._initialparts: + arg = "::".join(map(str, parts)) + self.trace("processing argument", arg) self.trace.root.indent += 1 try: for x in self._collect(arg): @@ -417,8 +419,9 @@ class Collection(FSCollector): def _collectfile(self, path): ihook = self.gethookproxy(path) - if ihook.pytest_ignore_collect(path=path, config=self.config): - return () + if not self.isinitpath(path): + if ihook.pytest_ignore_collect(path=path, config=self.config): + return () return ihook.pytest_collect_file(path=path, parent=self) def _recurse(self, path): @@ -439,6 +442,8 @@ class Collection(FSCollector): p = py.path.local(mod.__file__) if p.purebasename == "__init__": p = p.dirpath() + else: + p = p.new(basename=p.purebasename+".py") return p def _parsearg(self, arg): diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index 12afa28bd..d9dea4716 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -310,7 +310,8 @@ class TestInvocationVariants: out, err = capsys.readouterr() assert "--myopt" in out - def test_cmdline_python_package(self, testdir): + def test_cmdline_python_package(self, testdir, monkeypatch): + monkeypatch.delenv('PYTHONDONTWRITEBYTECODE') path = testdir.mkpydir("tpkg") path.join("test_hello.py").write("def test_hello(): pass") path.join("test_world.py").write("def test_world(): pass") diff --git a/testing/plugin/test_assertion.py b/testing/plugin/test_assertion.py index 59c36ca0b..d1a531a7c 100644 --- a/testing/plugin/test_assertion.py +++ b/testing/plugin/test_assertion.py @@ -161,15 +161,6 @@ def test_functional(testdir): result = testdir.runpytest("--no-assert") assert "3 == 4" not in result.stdout.str() -def test_AssertionErrorIdentity(testdir): - testdir.makepyfile(""" - def test_hello(): - import exceptions - assert AssertionError is exceptions.AssertionError - """) - result = testdir.runpytest() - result.stdout.fnmatch_lines(["*1 passed*"]) - def test_triple_quoted_string_issue113(testdir): testdir.makepyfile(""" def test_hello(): diff --git a/testing/test_collection.py b/testing/test_collection.py index 9aa0fb96d..6e983e157 100644 --- a/testing/test_collection.py +++ b/testing/test_collection.py @@ -213,6 +213,19 @@ class TestCustomConftests: assert result.ret == 0 result.stdout.fnmatch_lines(["*1 passed*"]) + def test_ignore_collect_not_called_on_argument(self, testdir): + testdir.makeconftest(""" + def pytest_ignore_collect(path, config): + return True + """) + p = testdir.makepyfile("def test_hello(): pass") + result = testdir.runpytest(p) + assert result.ret == 0 + assert "1 passed" in result.stdout.str() + result = testdir.runpytest() + assert result.ret == 0 + assert "1 passed" not in result.stdout.str() + def test_collectignore_exclude_on_option(self, testdir): testdir.makeconftest(""" collect_ignore = ['hello', 'test_world.py']