ZC Buildout recipe for creating test runners
项目描述
此配方生成用于测试一组egg的zope.testing测试运行脚本。
在 buildout.cfg 中的示例用法
[buildout] parts = test [test] recipe = zc.recipe.testrunner eggs = <eggs to test>
变更历史
3.1 (2024-09-27)
添加对Python 3.12的支持。
放弃对Python 3.7的支持。
修复测试,使其能够成功运行在较新的 setuptools 版本上。
3.0 (2023-02-08)
添加对Python 3.10、3.11的支持。
放弃对Python 2.7、3.5、3.6的支持。
2.2 (2020-11-30)
添加对Python 3.9、PyPy2和PyPy3的支持。
2.1 (2019-05-14)
添加对Python 3.5至3.8a3的支持。
2.0.0 (2013-02-10)
与buildout 2兼容。
这是从1.3.0开始的,然后
合并来自1.2.1(svn://svn.zope.org/repos/main/zc.recipe.testrunner/tags/1.2.1)的修复,不包括nailing zope.testing版本。这修复了一些Windows问题
1.4.0 (2010-08-27)
更新为使用zc.buildout 1.5.0脚本生成。这增加了以下选项:include-site-packages、allowed-eggs-from-site-packages、extends和exec-sitecustomize。
合并来自1.2.1(svn://svn.zope.org/repos/main/zc.recipe.testrunner/tags/1.2.1)的修复,不包括nailing zope.testing版本。这修复了一些Windows问题
1.3.0 (2010-06-09)
更新测试,以便与所有模块的最新版本一起运行。
移除了对已弃用的zope.testing.doctest的使用,因此也放弃了Python 2.3的支持。
开始使用zope.testrunner而不是zope.testing.testrunner。
1.2.1 (2010-08-24)
修复了大量Windows问题
将版本固定为ZTK 1.0a2(唉,至少我们要有一些稳定性)
修复了一些其他测试失败,这些失败似乎来自其他包
1.2.0 (2009-03-23)
添加了一个相对路径选项,用于使用egg、测试和工作目录路径相对于测试脚本。
1.1.0 (2008-08-25)
要求至少使用zope.testing 3.6.0。
修复了一个错误:当使用工作目录参数时,层并行运行失败。
1.0.0 (2007-11-04)
准备稳定发布。
1.0.0b8 (2007-07-17)
添加了使用初始化选项的能力,该选项将在设置环境后插入到bin/test中。
1.0.0b7 (2007-04-26)
特性变更
添加了可选的环境选项,允许在buildout.cfg中定义一个部分,用于指定在运行测试之前应设置的变量。
1.0.0b6 (2007-02-25)
特性变更
如果没有指定工作目录,或指定为空字符串,将为测试创建一个空的部分目录。
1.0.0b5 (2007-01-24)
修复的漏洞
当
使用工作目录选项时,
并且测试运行器需要重启自己
并且测试运行器以相对路径(例如bin/test)运行
那么测试运行器无法成功重启,因为sys.argv[0]中的相对路径已不再有效。
现在我们将sys.argv[0]转换为绝对路径。
1.0.0b4 (2006-10-24)
特性变更
添加了一个工作目录选项,用于指定生成的脚本的运行目录。
1.0.0b3 (2006-10-16)
更新到可以与(zc.buildout 1.0.0b10)一起工作(不会收到警告)。
1.0.0b2
添加了默认选项,用于指定测试运行器默认选项。
1.0.0b1
更新到可以与zc.buildout 1.0.0b5一起工作。
1.0.0a3
添加了默认选项,允许指定测试运行器的默认选项。
1.0.0a2
现在提供了额外的路径选项,用于在测试脚本中包含额外的路径。这对于依赖未打包为egg的Python包的egg很有用。
1.0.0a1
初始公开版本
详细文档
测试运行器配方
测试运行器配方,zc.recipe.testrunner,为项目创建测试运行器。
测试运行器配方有几个选项
- eggs
eggs选项指定了要测试的egg列表,作为一个或多个setuptools要求字符串。每个字符串必须在单独的一行上给出。
- script
script选项给出了要生成的脚本的名称,在buildout的bin目录中。如果不使用此选项,则将使用部分名称。
- extra-paths
要包含在生成的测试脚本中的一或多个额外路径。
- defaults
defaults选项允许指定测试运行器的默认选项。这些作为Python源代码指定,通常是一个列表字面量。
- working-directory
working-directory选项允许指定测试将运行的目录。当运行时,测试运行器将切换到该目录。如果工作目录为空字符串或未指定,则配方将在部分中创建一个工作目录。
- environment
在开始测试之前应导出的环境变量集。
- initialization
提供在运行测试之前要运行的初始化代码。
- relative-paths
使用相对于测试脚本的egg、测试和工作目录路径。
(注意,由于Zope测试运行器的限制,目前分布不能是zip文件。待办事项:修复测试运行器!)
为了说明这一点,我们将在我们的示例buildout中创建一对项目
>>> mkdir(sample_buildout, 'demo') >>> mkdir(sample_buildout, 'demo', 'demo') >>> write(sample_buildout, 'demo', 'demo', '__init__.py', '') >>> write(sample_buildout, 'demo', 'demo', 'tests.py', ... ''' ... import unittest ... ... class TestDemo(unittest.TestCase): ... def test(self): ... pass ... ... def test_suite(): ... loader = unittest.TestLoader() ... return loader.loadTestsFromTestCase(TestDemo) ... ''')>>> write(sample_buildout, 'demo', 'setup.py', ... """ ... from setuptools import setup ... ... setup(name = "demo") ... """)>>> write(sample_buildout, 'demo', 'README.txt', '')>>> mkdir(sample_buildout, 'demo2') >>> mkdir(sample_buildout, 'demo2', 'demo2') >>> write(sample_buildout, 'demo2', 'demo2', '__init__.py', '') >>> write(sample_buildout, 'demo2', 'demo2', 'tests.py', ... ''' ... import unittest ... ... class Demo2Tests(unittest.TestCase): ... def test2(self): ... pass ... ... def test_suite(): ... loader = unittest.TestLoader() ... return loader.loadTestsFromTestCase(Demo2Tests) ... ''')>>> write(sample_buildout, 'demo2', 'setup.py', ... """ ... from setuptools import setup ... ... setup(name = "demo2", install_requires= ['demoneeded']) ... """)>>> write(sample_buildout, 'demo2', 'README.txt', '')
Demo 2依赖于demoneeded
>>> mkdir(sample_buildout, 'demoneeded') >>> mkdir(sample_buildout, 'demoneeded', 'demoneeded') >>> write(sample_buildout, 'demoneeded', 'demoneeded', '__init__.py', '') >>> write(sample_buildout, 'demoneeded', 'demoneeded', 'tests.py', ... ''' ... import unittest ... ... class TestNeeded(unittest.TestCase): ... def test_needed(self): ... pass ... ... def test_suite(): ... loader = unittest.TestLoader() ... return loader.loadTestsFromTestCase(TestNeeded) ... ''')>>> write(sample_buildout, 'demoneeded', 'setup.py', ... """ ... from setuptools import setup ... ... setup(name = "demoneeded") ... """)>>> write(sample_buildout, 'demoneeded', 'README.txt', '')
我们将更新我们的buildout,以将demo项目作为开发egg安装,并创建测试脚本
>>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... develop = demo demoneeded demo2 ... parts = testdemo ... offline = true ... ... [testdemo] ... recipe = zc.recipe.testrunner ... eggs = ... demo ... demo2 ... script = test ... """)
请注意,我们在eggs选项中指定了demo和demo2,并且我们将它们放在不同的行上。
我们还指定了离线选项,以在离线模式下运行buildout。
现在,当我们运行buildout时
>>> import os >>> os.chdir(sample_buildout) >>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'), ... end='')
我们在bin目录中安装了一个测试脚本
>>> ls(sample_buildout, 'bin') - buildout - test
我们还获得了一个用于运行测试的部分目录
>>> ls(sample_buildout, 'parts') d testdemo
更新时保持其内容完整
>>> _ = system(os.path.join(sample_buildout, 'bin', 'test') + ... ' -q --coverage=coverage') >>> ls(sample_buildout, 'parts', 'testdemo') d coverage >>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'), ... end='') >>> ls(sample_buildout, 'parts', 'testdemo') d coverage
我们可以运行测试脚本来运行我们的演示测试
>>> print_(system(os.path.join(sample_buildout, 'bin', 'test') + ' -vv'), ... end='') Running tests at level 1 Running zope.testrunner.layer.UnitTests tests: Set up zope.testrunner.layer.UnitTests in 0.001 seconds. Running: test (demo.tests.TestDemo...) test2 (demo2.tests.Demo2Tests...) Ran 2 tests with 0 failures, 0 errors and 0 skipped in 0.001 seconds. Tearing down left over layers: Tear down zope.testrunner.layer.UnitTests in 0.001 seconds.
请注意,我们没有运行所需的演示测试。测试仅针对列出的蛋(egg)运行,而不是它们的依赖项。
如果我们从配置中省略脚本选项,那么测试脚本将从中获得它的名称
>>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... develop = demo ... parts = testdemo ... offline = true ... ... [testdemo] ... recipe = zc.recipe.testrunner ... eggs = demo ... """)>>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'), ... end='')>>> ls(sample_buildout, 'bin') - buildout - testdemo
我们可以运行测试脚本来运行我们的演示测试
>>> print_(system(os.path.join(sample_buildout, 'bin', 'testdemo') + ' -q'), ... end='') Running zope.testrunner.layer.UnitTests tests: Set up zope.testrunner.layer.UnitTests in 0.001 seconds. Ran 1 tests with 0 failures, 0 errors and 0 skipped in 0.001 seconds. Tearing down left over layers: Tear down zope.testrunner.layer.UnitTests in 0.001 seconds.
如果我们需要在测试脚本中包含其他路径,我们可以使用extra-paths选项来指定它们
>>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... develop = demo ... parts = testdemo ... offline = true ... ... [testdemo] ... recipe = zc.recipe.testrunner ... eggs = demo ... extra-paths = /usr/local/zope/lib/python ... """)>>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'), ... end='')>>> cat(sample_buildout, 'bin', 'testdemo') # doctest: +ELLIPSIS #!/usr/local/bin/python2.4 <BLANKLINE> import sys sys.path[0:0] = [ ... ] <BLANKLINE> import os sys.argv[0] = os.path.abspath(sys.argv[0]) os.chdir('/sample-buildout/parts/testdemo') <BLANKLINE> <BLANKLINE> import zope.testrunner <BLANKLINE> if __name__ == '__main__': sys.exit(zope.testrunner.run([ '--test-path', '/sample-buildout/demo', ]))
我们可以使用working-directory选项来指定工作目录
>>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... develop = demo ... parts = testdemo ... offline = true ... ... [testdemo] ... recipe = zc.recipe.testrunner ... eggs = demo ... extra-paths = /usr/local/zope/lib/python ... working-directory = /foo/bar ... """)>>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'), ... end='')>>> cat(sample_buildout, 'bin', 'testdemo') # doctest: +ELLIPSIS #!/usr/local/bin/python2.4 <BLANKLINE> import sys sys.path[0:0] = [ ... ] <BLANKLINE> import os sys.argv[0] = os.path.abspath(sys.argv[0]) os.chdir('/foo/bar') <BLANKLINE> <BLANKLINE> import zope.testrunner <BLANKLINE> if __name__ == '__main__': sys.exit(zope.testrunner.run([ '--test-path', '/sample-buildout/demo', ]))
现在,我们的测试使用指定的工作目录,其指定的部分目录已消失
>>> ls(sample_buildout, 'parts')
如果我们需要指定默认选项,我们可以使用defaults选项。例如,Zope 3应用程序通常在名为ftests或tests的模块中定义测试套件。默认测试运行器的行为是查找名为tests的模块。要指定我们希望在tests和ftests模块中查找,我们需要为–tests-pattern选项提供一个默认值。如果我们喜欢点(dots),我们也可以使用-v选项请求更详细的输出
>>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... develop = demo ... parts = testdemo ... offline = true ... ... [testdemo] ... recipe = zc.recipe.testrunner ... eggs = demo ... extra-paths = /usr/local/zope/lib/python ... defaults = ['--tests-pattern', '^f?tests$', ... '-v' ... ] ... """)>>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'), ... end='')>>> cat(sample_buildout, 'bin', 'testdemo') # doctest: +ELLIPSIS #!/usr/local/bin/python2.4 <BLANKLINE> import sys sys.path[0:0] = [ ... ] <BLANKLINE> import os sys.argv[0] = os.path.abspath(sys.argv[0]) os.chdir('/sample-buildout/parts/testdemo') <BLANKLINE> <BLANKLINE> import zope.testrunner <BLANKLINE> if __name__ == '__main__': sys.exit(zope.testrunner.run((['--tests-pattern', '^f?tests$', '-v' ]) + [ '--test-path', '/sample-buildout/demo', ]))
从这个示例中需要注意的一些事项
给定表达式的两侧放置了括号。
去除了前导空白。
为了演示环境(environment)选项,我们首先更新测试以包含对环境变量的检查
>>> write(sample_buildout, 'demo', 'demo', 'tests.py', ... ''' ... import unittest ... import os ... ... class DemoTests(unittest.TestCase): ... def test(self): ... self.assertEqual('42', os.environ.get('zc.recipe.testrunner', '23')) ... ... def test_suite(): ... loader = unittest.TestLoader() ... return loader.loadTestsFromTestCase(DemoTests) ... ''')
使用当前构建输出(buildout)运行它们会产生失败
>>> print_(system(os.path.join(sample_buildout, 'bin', 'testdemo') ... + ' -vv'), ... end='') # doctest: +ELLIPSIS Running tests at level 1 Running zope.testrunner.layer.UnitTests tests: Set up zope.testrunner.layer.UnitTests in 0.001 seconds. Running: test (demo.tests.DemoTests...) (... s) <BLANKLINE> <BLANKLINE> Failure in test test (demo.tests.DemoTests...) Traceback (most recent call last): ... AssertionError: '42' != '23' ... Ran 1 tests with 1 failures, 0 errors and 0 skipped in 0.001 seconds. Tearing down left over layers: Tear down zope.testrunner.layer.UnitTests in 0.001 seconds. <BLANKLINE> Tests with failures: test (demo.tests.DemoTests...)
让我们更新构建输出以指定测试运行器所需的环境变量
>>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... develop = demo ... parts = testdemo ... offline = true ... ... [testdemo] ... recipe = zc.recipe.testrunner ... eggs = demo ... environment = testenv ... ... [testenv] ... zc.recipe.testrunner = 42 ... """)
运行构建输出(buildout)并看到测试运行器脚本现在包括设置环境变量的步骤。此外,测试再次通过
>>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'), ... end='')>>> cat(sample_buildout, 'bin', 'testdemo') # doctest: +ELLIPSIS #!/usr/local/bin/python2.4 <BLANKLINE> import sys sys.path[0:0] = [ ... ] <BLANKLINE> import os sys.argv[0] = os.path.abspath(sys.argv[0]) os.chdir('/sample-buildout/parts/testdemo') os.environ['zc.recipe.testrunner'] = '42' <BLANKLINE> <BLANKLINE> import zope.testrunner <BLANKLINE> if __name__ == '__main__': sys.exit(zope.testrunner.run([ '--test-path', '/sample-buildout/demo', ]))>>> print_(system(os.path.join(sample_buildout, 'bin', 'testdemo')+' -vv'), ... end='') Running tests at level 1 Running zope.testrunner.layer.UnitTests tests: Set up zope.testrunner.layer.UnitTests in 0.001 seconds. Running: test (demo.tests.DemoTests...) Ran 1 tests with 0 failures, 0 errors and 0 skipped in 0.001 seconds. Tearing down left over layers: Tear down zope.testrunner.layer.UnitTests in 0.001 seconds.
我们可以在构建输出(buildout)中添加初始化步骤。这些步骤将被添加到脚本末尾
>>> write(sample_buildout, 'buildout.cfg', ... r""" ... [buildout] ... develop = demo ... parts = testdemo ... offline = true ... ... [testdemo] ... recipe = zc.recipe.testrunner ... eggs = demo ... extra-paths = /usr/local/zope/lib/python ... defaults = ['--tests-pattern', '^f?tests$', ... '-v' ... ] ... initialization = sys.stdout.write('Hello all you egg-laying pythons!\n') ... """)>>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'), ... end='')>>> cat(sample_buildout, 'bin', 'testdemo') # doctest: +ELLIPSIS #!/usr/local/bin/python2.4 <BLANKLINE> import sys sys.path[0:0] = [ ... ] <BLANKLINE> import os sys.argv[0] = os.path.abspath(sys.argv[0]) os.chdir('/sample-buildout/parts/testdemo') sys.stdout.write('Hello all you egg-laying pythons!\n') <BLANKLINE> import zope.testrunner <BLANKLINE> if __name__ == '__main__': sys.exit(zope.testrunner.run((['--tests-pattern', '^f?tests$', '-v' ]) + [ '--test-path', '/sample-buildout/demo', ]))
这也可以与多行初始化部分一起工作
>>> write(sample_buildout, 'buildout.cfg', ... r""" ... [buildout] ... develop = demo ... parts = testdemo ... offline = true ... ... [testdemo] ... recipe = zc.recipe.testrunner ... eggs = demo ... extra-paths = /usr/local/zope/lib/python ... defaults = ['--tests-pattern', '^f?tests$', ... '-v' ... ] ... initialization = sys.stdout.write('Hello all you egg-laying pythons!\n') ... sys.stdout.write('I thought pythons were live bearers?\n') ... """)>>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'), ... end='')>>> cat(sample_buildout, 'bin', 'testdemo') # doctest: +ELLIPSIS #!/usr/local/bin/python2.4 <BLANKLINE> import sys sys.path[0:0] = [ ... ] <BLANKLINE> import os sys.argv[0] = os.path.abspath(sys.argv[0]) os.chdir('/sample-buildout/parts/testdemo') sys.stdout.write('Hello all you egg-laying pythons!\n') sys.stdout.write('I thought pythons were live bearers?\n') <BLANKLINE> import zope.testrunner <BLANKLINE> if __name__ == '__main__': sys.exit(zope.testrunner.run((['--tests-pattern', '^f?tests$', '-v' ]) + [ '--test-path', '/sample-buildout/demo', ]))
如果使用relative-paths选项,egg(和额外)路径将以测试脚本为基准生成
>>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... develop = demo ... parts = testdemo ... offline = true ... ... [testdemo] ... recipe = zc.recipe.testrunner ... eggs = demo ... extra-paths = /usr/local/zope/lib/python ... ${buildout:directory}/sources ... relative-paths = true ... """)>>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'), ... end='')>>> cat(sample_buildout, 'bin', 'testdemo') # doctest: +ELLIPSIS #!/usr/local/bin/python2.4 <BLANKLINE> import os <BLANKLINE> join = os.path.join base = os.path.dirname(os.path.abspath(os.path.realpath(__file__))) base = os.path.dirname(base) <BLANKLINE> import sys sys.path[0:0] = [ join(base, 'demo'), ... '/usr/local/zope/lib/python', join(base, 'sources'), ] <BLANKLINE> import os sys.argv[0] = os.path.abspath(sys.argv[0]) os.chdir(join(base, 'parts/testdemo')) <BLANKLINE> <BLANKLINE> import zope.testrunner <BLANKLINE> if __name__ == '__main__': sys.exit(zope.testrunner.run([ '--test-path', join(base, 'demo'), ]))
relative-paths选项可以在构建输出(buildout)级别指定
>>> write(sample_buildout, 'buildout.cfg', ... """ ... [buildout] ... develop = demo ... parts = testdemo ... offline = true ... relative-paths = true ... ... [testdemo] ... recipe = zc.recipe.testrunner ... eggs = demo ... extra-paths = /usr/local/zope/lib/python ... ${buildout:directory}/sources ... """)>>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'), ... end='')>>> cat(sample_buildout, 'bin', 'testdemo') # doctest: +ELLIPSIS #!/usr/local/bin/python2.4 <BLANKLINE> import os <BLANKLINE> join = os.path.join base = os.path.dirname(os.path.abspath(os.path.realpath(__file__))) base = os.path.dirname(base) <BLANKLINE> import sys sys.path[0:0] = [ join(base, 'demo'), ... '/usr/local/zope/lib/python', join(base, 'sources'), ] <BLANKLINE> import os sys.argv[0] = os.path.abspath(sys.argv[0]) os.chdir(join(base, 'parts/testdemo')) <BLANKLINE> <BLANKLINE> import zope.testrunner <BLANKLINE> if __name__ == '__main__': sys.exit(zope.testrunner.run([ '--test-path', join(base, 'demo'), ]))
项目详情
zc.recipe.testrunner-3.1.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | bbffa7197fb915245345bc443656fac5018a58f54f93d3613fac5120e307f4a9 |
|
MD5 | 460d3f3d8681bbceabc1be844a9e5848 |
|
BLAKE2b-256 | 364d3f76e6a0abe183415fe914dc3b616ef379238937c695aebb1c0c531ab109 |
zc.recipe.testrunner-3.1-py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 3136328f393f3041b7cee43f92dff0962f4fbfa9941f9bc6d82eb818a3760131 |
|
MD5 | 642518d29a4fab921fc682aa7271bdaf |
|
BLAKE2b-256 | 5cc7e1a43fc55910d05111d98985f5a34046f288505db4b9f63c9cdd8c01f859 |