introduce new --testpkg importpath option, add more meat to draft release announcement
This commit is contained in:
		
							parent
							
								
									1a7f2e77e8
								
							
						
					
					
						commit
						707775dcfa
					
				|  | @ -3,14 +3,24 @@ py.test 2.0.0: standalone, features++, implementation++, docs++ | ||||||
| 
 | 
 | ||||||
| XXX PENDING | XXX PENDING | ||||||
| 
 | 
 | ||||||
| Welcome to pytest-2.0.0!  With this release py.test becomes its own standalone | Welcome to pytest-2.0.0, rapid and easy testing for and with Python. | ||||||
| PyPI distribution, named ``pytest``, installing the ``py.test`` command line | py.test now comes as its own PyPI distribution named ``pytest`` which | ||||||
| tool.  Apart from a great internal cleanup this release comes with tons | installs the ``py.test`` tool.  It removes most long-deprecated code, | ||||||
| of improvements and new features and a completely revamped extensive | providing for a much smaller and easier to understand code base.  There | ||||||
| documentation, including many continously tested examples. See | are also many new features and much improved documentation. See | ||||||
| 
 | 
 | ||||||
|     http://pytest.org |     http://pytest.org | ||||||
| 
 | 
 | ||||||
|  | for details or below for some more information. | ||||||
|  | 
 | ||||||
|  | Thanks to all issue reporters and people asking questions or | ||||||
|  | complaining.  Particular thanks to Floris Bruynooghe and Ronny Pfannschmidt | ||||||
|  | for their great coding contributions. | ||||||
|  | 
 | ||||||
|  | best, | ||||||
|  | holger | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| New Features | New Features | ||||||
| ----------------------- | ----------------------- | ||||||
| 
 | 
 | ||||||
|  | @ -20,31 +30,117 @@ New Features | ||||||
|     python -m pytest.main # on all pythons >= 2.5 |     python -m pytest.main # on all pythons >= 2.5 | ||||||
|     import pytest ; pytest.main(args, plugins) |     import pytest ; pytest.main(args, plugins) | ||||||
| 
 | 
 | ||||||
|   see http://pytest.org/2.0.0/invoke.html for details. |   see http://pytest.org/2.0.0/usage.html for details. | ||||||
|  | 
 | ||||||
|  | - new and better reporting information in assert expressions | ||||||
|  |   which compare lists, sequences or strings. | ||||||
|  | 
 | ||||||
|  |   see http://pytest.org/2.0.0/assert.html for details. | ||||||
| 
 | 
 | ||||||
| - new configuration through ini-files (setup.cfg or tox.ini recognized), | - new configuration through ini-files (setup.cfg or tox.ini recognized), | ||||||
|   for example:: |   for example:: | ||||||
| 
 | 
 | ||||||
|     [pytest] |     [pytest] | ||||||
|     norecursedirs = .hg _build |     norecursedirs = .hg data*  # don't ever recurse in such dirs | ||||||
|     python_collect_funcprefix = test_ |     addopts = -x --pyargs      # add these options by default | ||||||
|     python_collect_classprefix = Test |  | ||||||
| 
 | 
 | ||||||
|   see http://pytest.org/2.0.0/customize.html |   see http://pytest.org/2.0.0/customize.html | ||||||
| 
 | 
 | ||||||
| - | - improved standard unittest support.  For example you can now run | ||||||
|  |   the tests of an installed 'unittest' package with py.test:: | ||||||
| 
 | 
 | ||||||
| Thanks to issue reporters, people asking questions, complaining and |     py.test --pyargs unittest | ||||||
| generally to Ronny Pfannschmidt for his awesome help on many issues. |  | ||||||
| 
 | 
 | ||||||
| cheers, | - add a new "-q" option which decreases verbosity and prints a more | ||||||
| holger krekel |   nose/unittest-style "dot" output. | ||||||
| 
 | 
 | ||||||
| Changes between 1.3.3 and 1.3.4 | Fixes | ||||||
|  | ----------------------- | ||||||
|  | 
 | ||||||
|  | - fix issue126 - introduce py.test.set_trace() to trace execution via | ||||||
|  |   PDB during the running of tests even if capturing is ongoing. | ||||||
|  | - fix issue124 - make reporting more resilient against tests opening | ||||||
|  |   files on filedescriptor 1 (stdout). | ||||||
|  | - fix issue109 - sibling conftest.py files will not be loaded. | ||||||
|  |   (and Directory collectors cannot be customized anymore from a Directory's | ||||||
|  |   conftest.py - this needs to happen at least one level up). | ||||||
|  | - fix issue88 (finding custom test nodes from command line arg) | ||||||
|  | - fix issue93 stdout/stderr is captured while importing conftest.py | ||||||
|  | - fix bug: unittest collected functions now also can have "pytestmark" | ||||||
|  |   applied at class/module level | ||||||
|  | 
 | ||||||
|  | Important Note on importing "pytest" versus "py.test" | ||||||
|  | ------------------------------------------------------- | ||||||
|  | 
 | ||||||
|  | The usual way in pre-2.0 times to use py.test in python code was | ||||||
|  | to import "py" and then e.g. use "py.test.raises" for the helper. | ||||||
|  | This remains valid and is not planned to be deprecated.  However, | ||||||
|  | in most examples and internal code you'll find "import pytest" | ||||||
|  | and "pytest.raises" used as the recommended default way. | ||||||
|  | 
 | ||||||
|  | (Incompatible) Removals | ||||||
|  | ----------------------------- | ||||||
|  | 
 | ||||||
|  | - py.test.config is now only available if you are in a test run. | ||||||
|  | 
 | ||||||
|  | - the following (mostly already deprecated) functionality was removed: | ||||||
|  |   - removed support for Module/Class/... collection node definitions | ||||||
|  |     in conftest.py files.  They will cause nothing special. | ||||||
|  |   - removed support for calling the pre-1.0 collection API of "run()" and "join" | ||||||
|  |   - removed reading option values from conftest.py files or env variables. | ||||||
|  |     This can now be done much much better and easier through the ini-file | ||||||
|  |     mechanism and the "addopts" entry in particular. | ||||||
|  |   - removed the "disabled" attribute in test classes.  Use the skipping | ||||||
|  |     and pytestmark mechanism to skip or xfail a test class. | ||||||
|  | 
 | ||||||
|  | - py.test.collect.Directory does not exist anymore and it | ||||||
|  |   is not possible to provide an own "Directory" object. | ||||||
|  |   If you have used this and don#t know what to do, get | ||||||
|  |   in contact.  We'll figure someting out. | ||||||
|  | 
 | ||||||
|  |   Note that pytest_collect_directory() is still called but | ||||||
|  |   any return value will be ignored.  This allows to keep | ||||||
|  |   old code working that performed for example "py.test.skip()" | ||||||
|  |   in collect() to prevent recursion into directory trees | ||||||
|  |   if a certain dependency or command line option is missing. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | More Detailed Changes between 1.3.4 and 2.0.0 | ||||||
| ================================================== | ================================================== | ||||||
| 
 | 
 | ||||||
| - fix issue111: improve install documentation for windows | - pytest-2.0 is now its own package and depends on pylib-2.0 | ||||||
| - fix issue119: fix custom collectability of __init__.py as a module | - new ability: python -m pytest / python -m pytest.main ability | ||||||
| - fix issue116: --doctestmodules work with __init__.py files as well | - new python invcation: pytest.main(args, plugins) to load | ||||||
| - fix issue115: unify internal exception passthrough/catching/GeneratorExit |   some custom plugins early. | ||||||
| - fix issue118: new --tb=native for presenting cpython-standard exceptions | - try harder to run unittest test suites in a more compatible manner | ||||||
|  |   by deferring setup/teardown semantics to the unittest package. | ||||||
|  | - introduce a new way to set config options via ini-style files, | ||||||
|  |   by default setup.cfg and tox.ini files are searched.  The old | ||||||
|  |   ways (certain environment variables, dynamic conftest.py reading | ||||||
|  |   is removed). | ||||||
|  | - add a new "-q" option which decreases verbosity and prints a more | ||||||
|  |   nose/unittest-style "dot" output. | ||||||
|  | - fix issue126 - introduce py.test.set_trace() to trace execution via | ||||||
|  |   PDB during the running of tests even if capturing is ongoing. | ||||||
|  | - fix issue123 - new "python -m py.test" invocation for py.test | ||||||
|  |   (requires Python 2.5 or above) | ||||||
|  | - fix issue124 - make reporting more resilient against tests opening | ||||||
|  |   files on filedescriptor 1 (stdout). | ||||||
|  | - fix issue109 - sibling conftest.py files will not be loaded. | ||||||
|  |   (and Directory collectors cannot be customized anymore from a Directory's | ||||||
|  |   conftest.py - this needs to happen at least one level up). | ||||||
|  | - introduce (customizable) assertion failure representations and enhance | ||||||
|  |   output on assertion failures for comparisons and other cases (Floris Bruynooghe) | ||||||
|  | - nose-plugin: pass through type-signature failures in setup/teardown | ||||||
|  |   functions instead of not calling them (Ed Singleton) | ||||||
|  | - remove py.test.collect.Directory (follows from a major refactoring | ||||||
|  |   and simplification of the collection process) | ||||||
|  | - majorly reduce py.test core code, shift function/python testing to own plugin | ||||||
|  | - fix issue88 (finding custom test nodes from command line arg) | ||||||
|  | - refine 'tmpdir' creation, will now create basenames better associated | ||||||
|  |   with test names (thanks Ronny) | ||||||
|  | - "xpass" (unexpected pass) tests don't cause exitcode!=0 | ||||||
|  | - fix issue131 / issue60 - importing doctests in __init__ files used as namespace packages | ||||||
|  | - fix issue93 stdout/stderr is captured while importing conftest.py | ||||||
|  | - fix bug: unittest collected functions now also can have "pytestmark" | ||||||
|  |   applied at class/module level | ||||||
|  |  | ||||||
|  | @ -25,39 +25,18 @@ To stop the testing process after the first (N) failures:: | ||||||
|     py.test -x            # stop after first failure |     py.test -x            # stop after first failure | ||||||
|     py.test -maxfail=2    # stop after two failures |     py.test -maxfail=2    # stop after two failures | ||||||
| 
 | 
 | ||||||
| calling pytest from Python code | specifying tests / selecting tests | ||||||
| ---------------------------------------------------- | --------------------------------------------------- | ||||||
| 
 | 
 | ||||||
| .. versionadded: 2.0 | Several test run options:: | ||||||
| 
 | 
 | ||||||
| You can invoke ``py.test`` from Python code directly:: |     py.test test_mod.py   # run tests in module | ||||||
|  |     py.test somepath      # run all tests below path | ||||||
|  |     py.test -k string     # only run tests whose names contain a string | ||||||
| 
 | 
 | ||||||
|     pytest.main() | Import 'pkg' and use its filesystem location to find and run tests:: | ||||||
| 
 | 
 | ||||||
| this acts as if you would call "py.test" from the command line. |     py.test --testpkg=pypkg # run all tests found below directory of pypkg | ||||||
| It will not raise ``SystemExit`` but return the exitcode instead. |  | ||||||
| You can pass in options and arguments:: |  | ||||||
| 
 |  | ||||||
|     pytest.main(['x', 'mytestdir']) |  | ||||||
| 
 |  | ||||||
| or pass in a string:: |  | ||||||
| 
 |  | ||||||
|     pytest.main("-x mytestdir") |  | ||||||
| 
 |  | ||||||
| You can specify additional plugins to ``pytest.main``:: |  | ||||||
| 
 |  | ||||||
|     # content of myinvoke.py |  | ||||||
|     import pytest |  | ||||||
|     class MyPlugin: |  | ||||||
|         def pytest_addoption(self, parser): |  | ||||||
|             raise pytest.UsageError("hi from our plugin") |  | ||||||
| 
 |  | ||||||
|     pytest.main(plugins=[MyPlugin()]) |  | ||||||
| 
 |  | ||||||
| Running it will exit quickly:: |  | ||||||
| 
 |  | ||||||
|     $ python myinvoke.py |  | ||||||
|     ERROR: hi from our plugin |  | ||||||
| 
 | 
 | ||||||
| calling pytest through ``python -m pytest`` | calling pytest through ``python -m pytest`` | ||||||
| ----------------------------------------------------- | ----------------------------------------------------- | ||||||
|  | @ -162,4 +141,39 @@ for example ``-x`` if you only want to send one particular failure. | ||||||
| 
 | 
 | ||||||
| Currently only pasting to the http://paste.pocoo.org service is implemented. | Currently only pasting to the http://paste.pocoo.org service is implemented. | ||||||
| 
 | 
 | ||||||
|  | calling pytest from Python code | ||||||
|  | ---------------------------------------------------- | ||||||
|  | 
 | ||||||
|  | .. versionadded: 2.0 | ||||||
|  | 
 | ||||||
|  | You can invoke ``py.test`` from Python code directly:: | ||||||
|  | 
 | ||||||
|  |     pytest.main() | ||||||
|  | 
 | ||||||
|  | this acts as if you would call "py.test" from the command line. | ||||||
|  | It will not raise ``SystemExit`` but return the exitcode instead. | ||||||
|  | You can pass in options and arguments:: | ||||||
|  | 
 | ||||||
|  |     pytest.main(['x', 'mytestdir']) | ||||||
|  | 
 | ||||||
|  | or pass in a string:: | ||||||
|  | 
 | ||||||
|  |     pytest.main("-x mytestdir") | ||||||
|  | 
 | ||||||
|  | You can specify additional plugins to ``pytest.main``:: | ||||||
|  | 
 | ||||||
|  |     # content of myinvoke.py | ||||||
|  |     import pytest | ||||||
|  |     class MyPlugin: | ||||||
|  |         def pytest_addoption(self, parser): | ||||||
|  |             raise pytest.UsageError("hi from our plugin") | ||||||
|  | 
 | ||||||
|  |     pytest.main(plugins=[MyPlugin()]) | ||||||
|  | 
 | ||||||
|  | Running it will exit quickly:: | ||||||
|  | 
 | ||||||
|  |     $ python myinvoke.py | ||||||
|  |     ERROR: hi from our plugin | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| .. include:: links.inc | .. include:: links.inc | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ see http://pytest.org for documentation and details | ||||||
| 
 | 
 | ||||||
| (c) Holger Krekel and others, 2004-2010 | (c) Holger Krekel and others, 2004-2010 | ||||||
| """ | """ | ||||||
| __version__ = '2.0.0.dev19' | __version__ = '2.0.0.dev20' | ||||||
| 
 | 
 | ||||||
| __all__ = ['config', 'cmdline'] | __all__ = ['config', 'cmdline'] | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -9,8 +9,8 @@ cutdir = py.path.local(pytest.__file__).dirpath() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def pytest_addoption(parser): | def pytest_addoption(parser): | ||||||
|     group = parser.getgroup("terminal reporting") |     group = parser.getgroup("general") | ||||||
|     group._addoption('--funcargs', |     group.addoption('--funcargs', | ||||||
|                action="store_true", dest="showfuncargs", default=False, |                action="store_true", dest="showfuncargs", default=False, | ||||||
|                help="show available function arguments, sorted by plugin") |                help="show available function arguments, sorted by plugin") | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -31,6 +31,8 @@ def pytest_addoption(parser): | ||||||
|     group.addoption('--collectonly', |     group.addoption('--collectonly', | ||||||
|         action="store_true", dest="collectonly", |         action="store_true", dest="collectonly", | ||||||
|         help="only collect tests, don't execute them."), |         help="only collect tests, don't execute them."), | ||||||
|  |     group.addoption('--pyargs', action="store_true", | ||||||
|  |         help="try to interpret all arguments as python packages.") | ||||||
|     group.addoption("--ignore", action="append", metavar="path", |     group.addoption("--ignore", action="append", metavar="path", | ||||||
|         help="ignore path during collection (multi-allowed).") |         help="ignore path during collection (multi-allowed).") | ||||||
|     group.addoption('--confcutdir', dest="confcutdir", default=None, |     group.addoption('--confcutdir', dest="confcutdir", default=None, | ||||||
|  | @ -429,12 +431,29 @@ class Collection(FSCollector): | ||||||
|         ihook.pytest_collect_directory(path=path, parent=self) |         ihook.pytest_collect_directory(path=path, parent=self) | ||||||
|         return True |         return True | ||||||
| 
 | 
 | ||||||
|  |     def _tryconvertpyarg(self, x): | ||||||
|  |         try: | ||||||
|  |             mod = __import__(x, None, None, ['__doc__']) | ||||||
|  |         except ImportError: | ||||||
|  |             return x | ||||||
|  |         p = py.path.local(mod.__file__) | ||||||
|  |         if p.purebasename == "__init__": | ||||||
|  |             p = p.dirpath() | ||||||
|  |         return p | ||||||
|  | 
 | ||||||
|     def _parsearg(self, arg): |     def _parsearg(self, arg): | ||||||
|         """ return (fspath, names) tuple after checking the file exists. """ |         """ return (fspath, names) tuple after checking the file exists. """ | ||||||
|  |         arg = str(arg) | ||||||
|  |         if self.config.option.pyargs: | ||||||
|  |             arg = self._tryconvertpyarg(arg) | ||||||
|         parts = str(arg).split("::") |         parts = str(arg).split("::") | ||||||
|         path = self.fspath.join(parts[0], abs=True) |         path = self.fspath.join(parts[0], abs=True) | ||||||
|         if not path.check(): |         if not path.check(): | ||||||
|             raise pytest.UsageError("file not found: %s" %(path,)) |             if self.config.option.pyargs: | ||||||
|  |                 msg = "file or package not found: " | ||||||
|  |             else: | ||||||
|  |                 msg = "file not found: " | ||||||
|  |             raise pytest.UsageError(msg + arg) | ||||||
|         parts[0] = path |         parts[0] = path | ||||||
|         return parts |         return parts | ||||||
|     |     | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								setup.py
								
								
								
								
							
							
						
						
									
										2
									
								
								setup.py
								
								
								
								
							|  | @ -22,7 +22,7 @@ def main(): | ||||||
|         name='pytest', |         name='pytest', | ||||||
|         description='py.test: simple powerful testing with Python', |         description='py.test: simple powerful testing with Python', | ||||||
|         long_description = long_description, |         long_description = long_description, | ||||||
|         version='2.0.0.dev19', |         version='2.0.0.dev20', | ||||||
|         url='http://pytest.org', |         url='http://pytest.org', | ||||||
|         license='MIT license', |         license='MIT license', | ||||||
|         platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], |         platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], | ||||||
|  |  | ||||||
|  | @ -309,3 +309,24 @@ class TestInvocationVariants: | ||||||
|         out, err = capsys.readouterr() |         out, err = capsys.readouterr() | ||||||
|         assert "--myopt" in out |         assert "--myopt" in out | ||||||
| 
 | 
 | ||||||
|  |     def test_cmdline_python_package(self, testdir): | ||||||
|  |         path = testdir.mkpydir("tpkg") | ||||||
|  |         path.join("test_hello.py").write("def test_hello(): pass") | ||||||
|  |         path.join("test_world.py").write("def test_world(): pass") | ||||||
|  |         result = testdir.runpytest("--pyargs", "tpkg") | ||||||
|  |         assert result.ret == 0 | ||||||
|  |         result.stdout.fnmatch_lines([ | ||||||
|  |             "*2 passed*" | ||||||
|  |         ]) | ||||||
|  |         result = testdir.runpytest("--pyargs", "tpkg.test_hello") | ||||||
|  |         assert result.ret == 0 | ||||||
|  |         result.stdout.fnmatch_lines([ | ||||||
|  |             "*1 passed*" | ||||||
|  |         ]) | ||||||
|  | 
 | ||||||
|  |     def test_cmdline_python_package_not_exists(self, testdir): | ||||||
|  |         result = testdir.runpytest("--pyargs", "tpkgwhatv") | ||||||
|  |         assert result.ret | ||||||
|  |         result.stderr.fnmatch_lines([ | ||||||
|  |             "ERROR*file*or*package*not*found*", | ||||||
|  |         ]) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue