Docs about cx_freeze support and minor adjustments
--HG-- branch : cx_freeze-support
This commit is contained in:
		
							parent
							
								
									990e7bf3b9
								
							
						
					
					
						commit
						b7b96b24d8
					
				|  | @ -1,52 +1,56 @@ | ||||||
|  | """ | ||||||
|  | Package to support embedding pytest runner into executable files. | ||||||
| 
 | 
 | ||||||
|  | .. note:: Since we are imported into pytest namespace, we use local imports to | ||||||
|  |           be as cheap as possible. | ||||||
|  | """ | ||||||
| 
 | 
 | ||||||
| def includes(): | def includes(): | ||||||
|     return [ |     """ | ||||||
|         '_pytest.assertion.newinterpret', |     Returns a list of module names used by py.test that should be | ||||||
|         '_pytest.assertion.oldinterpret', |     included by cx_freeze. | ||||||
|         '_pytest.assertion.reinterpret', |     """ | ||||||
|         '_pytest.assertion.rewrite', |     import py | ||||||
|         '_pytest.assertion.util', |     import _pytest | ||||||
| 
 | 
 | ||||||
|         '_pytest._argcomplete', |     result = list(_iter_all_modules(py)) | ||||||
|         '_pytest.doctest', |     result += list(_iter_all_modules(_pytest)) | ||||||
|         '_pytest.pdb', |  | ||||||
|         '_pytest.unittest', |  | ||||||
|         '_pytest.capture', |  | ||||||
|         '_pytest.config', |  | ||||||
|         '_pytest.core', |  | ||||||
|         '_pytest.genscript', |  | ||||||
|         '_pytest.helpconfig', |  | ||||||
|         '_pytest.hookspec', |  | ||||||
|         '_pytest.junitxml', |  | ||||||
|         '_pytest.main', |  | ||||||
|         '_pytest.mark', |  | ||||||
|         '_pytest.monkeypatch', |  | ||||||
|         '_pytest.nose', |  | ||||||
|         '_pytest.pastebin', |  | ||||||
|         '_pytest.pytester', |  | ||||||
|         '_pytest.python', |  | ||||||
|         '_pytest.recwarn', |  | ||||||
|         '_pytest.resultlog', |  | ||||||
|         '_pytest.runner', |  | ||||||
|         '_pytest.skipping', |  | ||||||
|         '_pytest.standalonetemplate', |  | ||||||
|         '_pytest.terminal', |  | ||||||
|         '_pytest.tmpdir', |  | ||||||
| 
 | 
 | ||||||
|         'py._builtin', |     # builtin files imported by pytest using py.std implicit mechanism; | ||||||
|         'py._path.local', |     # should be removed if https://bitbucket.org/hpk42/pytest/pull-request/185 | ||||||
|         'py._io.capture', |     # gets merged | ||||||
|         'py._io.saferepr', |     result += [ | ||||||
|         'py._iniconfig', |  | ||||||
|         'py._io.terminalwriter', |  | ||||||
|         'py._xmlgen', |  | ||||||
|         'py._error', |  | ||||||
|         'py._std', |  | ||||||
| 
 |  | ||||||
|         # builtin files imported by pytest using py.std implicit mechanism |  | ||||||
|         'argparse', |         'argparse', | ||||||
|         'shlex', |         'shlex', | ||||||
|         'warnings', |         'warnings', | ||||||
|         'types', |         'types', | ||||||
|     ] |     ] | ||||||
|  |     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', | ||||||
|  |              ... | ||||||
|  |             ] | ||||||
|  |     """ | ||||||
|  |     import pkgutil | ||||||
|  |     import os | ||||||
|  | 
 | ||||||
|  |     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 | ||||||
|  |  | ||||||
|  | @ -694,33 +694,26 @@ 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 | 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. | invaluable to obtain more information about a hard to reproduce bug. | ||||||
| 
 | 
 | ||||||
| Unfortunately embedding the ``pytest`` runner into a frozen executable using | Unfortunately ``cx_freeze`` can't discover them | ||||||
| ``cx_freeze`` is not as straightforward as one would like, | automatically because of ``pytest``'s use of dynamic module loading, so you | ||||||
| because ``pytest`` makes heavy use of dynamic module loading which | must declare them explicitly by using ``pytest.cx_freeze_support.includes()``:: | ||||||
| ``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:: |  | ||||||
| 
 | 
 | ||||||
|     # contents of setup.py |     # contents of setup.py | ||||||
|     from cx_Freeze import setup, Executable |     from cx_Freeze import setup, Executable | ||||||
|  |     import pytest | ||||||
| 
 | 
 | ||||||
|     includes = [ |  | ||||||
|         '_pytest.doctest', |  | ||||||
|         '_pytest.unittest', |  | ||||||
|         # ... lots more |  | ||||||
|     ] |  | ||||||
|     setup( |     setup( | ||||||
|         name="runtests", |         name="runtests", | ||||||
|         options={"build_exe": {'includes': includes}}, |         options={"build_exe": | ||||||
|  |             { | ||||||
|  |             'includes': pytest.cx_freeze_support.includes()} | ||||||
|  |             }, | ||||||
|         # ... other options |         # ... other options | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
| (For the complete list, check out the modules under ``_pytest`` in your | If you don't want to ship a different executable just in order to run your tests, | ||||||
| site-packages). | you can make your program check for a certain flag and pass control | ||||||
| 
 | over to ``pytest`` instead. For example:: | ||||||
| With that, you can make your program check for a certain flag and pass control |  | ||||||
| over to ``pytest``:: |  | ||||||
| 
 | 
 | ||||||
|     # contents of app_main.py |     # contents of app_main.py | ||||||
|     import sys |     import sys | ||||||
|  | @ -734,6 +727,6 @@ over to ``pytest``:: | ||||||
|         ... |         ... | ||||||
| 
 | 
 | ||||||
| This makes it convenient to execute your tests from within your frozen | 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/ |     $ ./app_main --pytest --verbose --tb=long --junit-xml=results.xml test-suite/ | ||||||
|  | @ -1,7 +0,0 @@ | ||||||
| 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)) |  | ||||||
|  | @ -1,7 +1,6 @@ | ||||||
| """ | """ | ||||||
| Simple script that actually executes py.test runner when passed "--pytest" as | This is the script that is actually frozen into an executable: simply executes | ||||||
| first argument; in this case, all other arguments are forwarded to pytest's | py.test main(). | ||||||
| main(). |  | ||||||
| """ | """ | ||||||
| 
 | 
 | ||||||
| if __name__ == '__main__': | if __name__ == '__main__': | ||||||
|  |  | ||||||
|  | @ -1,6 +1,9 @@ | ||||||
|  | """ | ||||||
|  | Sample setup.py script that generates an executable with pytest runner embedded. | ||||||
|  | """ | ||||||
| from cx_Freeze import setup, Executable | from cx_Freeze import setup, Executable | ||||||
| 
 |  | ||||||
| import pytest | import pytest | ||||||
|  | 
 | ||||||
| setup( | setup( | ||||||
|     name="runtests", |     name="runtests", | ||||||
|     version="0.1", |     version="0.1", | ||||||
|  |  | ||||||
|  | @ -0,0 +1,14 @@ | ||||||
|  | """ | ||||||
|  | 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). | ||||||
|  | """ | ||||||
|  | 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)) | ||||||
							
								
								
									
										4
									
								
								tox.ini
								
								
								
								
							
							
						
						
									
										4
									
								
								tox.ini
								
								
								
								
							|  | @ -1,6 +1,6 @@ | ||||||
| [tox] | [tox] | ||||||
| distshare={homedir}/.tox/distshare | 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] | [testenv] | ||||||
| changedir=testing | changedir=testing | ||||||
|  | @ -129,7 +129,7 @@ changedir=testing/cx_freeze | ||||||
| basepython=python2.7 | basepython=python2.7 | ||||||
| commands= | commands= | ||||||
|     {envpython} runtests_setup.py build --build-exe build |     {envpython} runtests_setup.py build --build-exe build | ||||||
|     {envpython} run.py |     {envpython} tox_run.py | ||||||
| 
 | 
 | ||||||
| [pytest] | [pytest] | ||||||
| minversion=2.0 | minversion=2.0 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue