Merged in nocoddemus/pytest/cx_freeze-support (pull request #189)
This commit is contained in:
		
						commit
						eae1055fb0
					
				|  | @ -1,6 +1,10 @@ | |||
| NEXT | ||||
| ----------- | ||||
| 
 | ||||
| - Added function pytest.freeze_includes(), which makes it easy to embed | ||||
|   pytest into executables using tools like cx_freeze. | ||||
|   See docs for examples and rationale. Thanks Bruno Oliveira. | ||||
| 
 | ||||
| - Improve assertion rewriting cache invalidation precision. | ||||
| 
 | ||||
| - fixed issue561: adapt autouse fixture example for python3. | ||||
|  |  | |||
|  | @ -1,6 +1,12 @@ | |||
| """ generate a single-file self-contained version of pytest """ | ||||
| import py | ||||
| import os | ||||
| import sys | ||||
| import pkgutil | ||||
| 
 | ||||
| import py | ||||
| 
 | ||||
| import _pytest | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| def find_toplevel(name): | ||||
|  | @ -80,3 +86,42 @@ def pytest_cmdline_main(config): | |||
|         tw.line("generated pytest standalone script: %s" % genscript, | ||||
|                 bold=True) | ||||
|         return 0 | ||||
| 
 | ||||
| 
 | ||||
| def pytest_namespace(): | ||||
|     return {'freeze_includes': freeze_includes} | ||||
| 
 | ||||
| 
 | ||||
| def freeze_includes(): | ||||
|     """ | ||||
|     Returns a list of module names used by py.test that should be | ||||
|     included by cx_freeze. | ||||
|     """ | ||||
|     result = list(_iter_all_modules(py)) | ||||
|     result += list(_iter_all_modules(_pytest)) | ||||
|     return result | ||||
| 
 | ||||
| 
 | ||||
| def _iter_all_modules(package, prefix=''): | ||||
|     """ | ||||
|     Iterates over the names of all modules that can be found in the given | ||||
|     package, recursively. | ||||
| 
 | ||||
|     Example: | ||||
|         _iter_all_modules(_pytest) -> | ||||
|             ['_pytest.assertion.newinterpret', | ||||
|              '_pytest.capture', | ||||
|              '_pytest.core', | ||||
|              ... | ||||
|             ] | ||||
|     """ | ||||
|     if type(package) is not str: | ||||
|         path, prefix = package.__path__[0], package.__name__ + '.' | ||||
|     else: | ||||
|         path = package | ||||
|     for _, name, is_package in pkgutil.iter_modules([path]): | ||||
|         if is_package: | ||||
|             for m in _iter_all_modules(os.path.join(path, name), prefix=name + '.'): | ||||
|                 yield prefix + m | ||||
|         else: | ||||
|             yield prefix + name | ||||
|  |  | |||
|  | @ -682,33 +682,27 @@ included into the executable can be detected early while also allowing you to | |||
| send test files to users so they can run them in their machines, which can be | ||||
| invaluable to obtain more information about a hard to reproduce bug. | ||||
| 
 | ||||
| Unfortunately embedding the ``pytest`` runner into a frozen executable using | ||||
| ``cx_freeze`` is not as straightforward as one would like, | ||||
| because ``pytest`` makes heavy use of dynamic module loading which | ||||
| ``cx_freeze`` can't resolve by itself. | ||||
| 
 | ||||
| To solve this, you have to manually include ``pytest`` and ``py`` | ||||
| modules by using the ``build_exe`` option in your ``setup.py`` script, like this:: | ||||
| Unfortunately ``cx_freeze`` can't discover them | ||||
| automatically because of ``pytest``'s use of dynamic module loading, so you | ||||
| must declare them explicitly by using ``pytest.freeze_includes()``:: | ||||
| 
 | ||||
|     # contents of setup.py | ||||
|     from cx_Freeze import setup, Executable | ||||
|     import pytest | ||||
| 
 | ||||
|     includes = [ | ||||
|         '_pytest.doctest', | ||||
|         '_pytest.unittest', | ||||
|         # ... lots more | ||||
|     ] | ||||
|     setup( | ||||
|         name="runtests", | ||||
|         options={"build_exe": {'includes': includes}}, | ||||
|         name="app_main", | ||||
|         executables=[Executable("app_main.py")], | ||||
|         options={"build_exe": | ||||
|             { | ||||
|             'includes': pytest.freeze_includes()} | ||||
|             }, | ||||
|         # ... other options | ||||
|     ) | ||||
| 
 | ||||
| (For the complete list, check out the modules under ``_pytest`` in your | ||||
| site-packages). | ||||
| 
 | ||||
| With that, you can make your program check for a certain flag and pass control | ||||
| over to ``pytest``:: | ||||
| If you don't want to ship a different executable just in order to run your tests, | ||||
| you can make your program check for a certain flag and pass control | ||||
| over to ``pytest`` instead. For example:: | ||||
| 
 | ||||
|     # contents of app_main.py | ||||
|     import sys | ||||
|  | @ -722,7 +716,6 @@ over to ``pytest``:: | |||
|         ... | ||||
| 
 | ||||
| This makes it convenient to execute your tests from within your frozen | ||||
| application, using standard ``py.test`` command-line:: | ||||
| application, using standard ``py.test`` command-line options:: | ||||
| 
 | ||||
|     $ ./app_main --pytest --verbose --tb=long --junit-xml=results.xml test-suite/    /bin/sh: 1: ./app_main: not found | ||||
|     /bin/sh: 1: ./app_main: not found | ||||
|     $ ./app_main --pytest --verbose --tb=long --junit-xml=results.xml test-suite/ | ||||
|  |  | |||
|  | @ -0,0 +1,9 @@ | |||
| """ | ||||
| This is the script that is actually frozen into an executable: simply executes | ||||
| py.test main(). | ||||
| """ | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     import sys | ||||
|     import pytest | ||||
|     sys.exit(pytest.main()) | ||||
|  | @ -0,0 +1,15 @@ | |||
| """ | ||||
| Sample setup.py script that generates an executable with pytest runner embedded. | ||||
| """ | ||||
| if __name__ == '__main__': | ||||
|     from cx_Freeze import setup, Executable | ||||
|     import pytest | ||||
| 
 | ||||
|     setup( | ||||
|         name="runtests", | ||||
|         version="0.1", | ||||
|         description="exemple of how embedding py.test into an executable using cx_freeze", | ||||
|         executables=[Executable("runtests_script.py")], | ||||
|         options={"build_exe": {'includes': pytest.freeze_includes()}}, | ||||
|     ) | ||||
| 
 | ||||
|  | @ -0,0 +1,6 @@ | |||
| 
 | ||||
| 
 | ||||
| Testing doctest:: | ||||
| 
 | ||||
|     >>> 1 + 1 | ||||
|     2 | ||||
|  | @ -0,0 +1,6 @@ | |||
| 
 | ||||
| def test_upper(): | ||||
|     assert 'foo'.upper() == 'FOO' | ||||
| 
 | ||||
| def test_lower(): | ||||
|     assert 'FOO'.lower() == 'foo' | ||||
|  | @ -0,0 +1,15 @@ | |||
| """ | ||||
| Called by tox.ini: uses the generated executable to run the tests in ./tests/ | ||||
| directory. | ||||
| 
 | ||||
| .. note:: somehow calling "build/runtests_script" directly from tox doesn't | ||||
|           seem to work (at least on Windows). | ||||
| """ | ||||
| if __name__ == '__main__': | ||||
|     import os | ||||
|     import sys | ||||
| 
 | ||||
|     executable = os.path.join(os.getcwd(), 'build', 'runtests_script') | ||||
|     if sys.platform.startswith('win'): | ||||
|         executable += '.exe' | ||||
|     sys.exit(os.system('%s tests' % executable)) | ||||
|  | @ -36,3 +36,13 @@ def test_gen(testdir, anypython, standalone): | |||
|     result = standalone.run(anypython, testdir, p) | ||||
|     assert result.ret != 0 | ||||
| 
 | ||||
| 
 | ||||
| def test_freeze_includes(): | ||||
|     """ | ||||
|     Smoke test for freeze_includes(), to ensure that it works across all | ||||
|     supported python versions. | ||||
|     """ | ||||
|     includes = pytest.freeze_includes() | ||||
|     assert len(includes) > 1 | ||||
|     assert '_pytest.genscript' in includes | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										10
									
								
								tox.ini
								
								
								
								
							
							
						
						
									
										10
									
								
								tox.ini
								
								
								
								
							|  | @ -1,6 +1,6 @@ | |||
| [tox] | ||||
| distshare={homedir}/.tox/distshare | ||||
| envlist=flakes,py26,py27,py34,pypy,py27-pexpect,py33-pexpect,py27-nobyte,py32,py33,py27-xdist,py33-xdist,py27-trial,py33-trial,doctesting | ||||
| envlist=flakes,py26,py27,py34,pypy,py27-pexpect,py33-pexpect,py27-nobyte,py32,py33,py27-xdist,py33-xdist,py27-trial,py33-trial,doctesting,py27-cxfreeze | ||||
| 
 | ||||
| [testenv] | ||||
| changedir=testing | ||||
|  | @ -123,6 +123,14 @@ commands= | |||
|     {envpython} {envbindir}/py.test-jython \ | ||||
|         -rfsxX --junitxml={envlogdir}/junit-{envname}2.xml [] | ||||
| 
 | ||||
| [testenv:py27-cxfreeze] | ||||
| deps=cx_freeze | ||||
| changedir=testing/cx_freeze | ||||
| basepython=python2.7 | ||||
| commands= | ||||
|     {envpython} runtests_setup.py build --build-exe build | ||||
|     {envpython} tox_run.py | ||||
| 
 | ||||
| [pytest] | ||||
| minversion=2.0 | ||||
| plugins=pytester | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue