一个简单易用的多语言测试运行器。
项目描述
Polytester是一个简单易用的多语言测试运行器。
它使您能够轻松地在多语言项目中运行测试。可以并行运行python、javascript、ruby、java等多种语言。它抽象了配置的痛苦,让您专注于开发。简单高效。
Polytester与任何在shell中运行的测试框架(是的,这几乎涵盖了地球上的一切)兼容,并且提供了对包括django、karma、protractor等众多常见框架的额外平滑集成。Polytester由Steven Skoczen构建。
安装
pip install polytester
入门
-
创建一个tests.yml文件。以下示例展示了django、protractor和karma(jasmine)测试。
api: command: python manage.py test js: command: karma start karma.conf.js e2e: command: protractor
-
运行
polytester
$ polytester Detecting... ✔ api detected as django tests. ✔ e2e detected as protractor tests. ✔ js detected as karma tests. Running tests... ✔ api - 35 tests passed. ✔ e2e - 17 tests passed. ✔ js - 23 tests passed. ✔ All tests passed.
请注意,返回的状态码是正确的,因此您可以将这些内容直接放入CI服务中,完成任务。
这就是全部。没有第三步。
因为每个人都喜欢动画GIF
以下内容 - polytester安装、配置和运行只需不到30秒
支持框架
任何返回标准错误代码的测试框架都将直接工作。几乎涵盖了所有内容。
此外,polytester会逐步将具有解析器的框架输出升级到更优秀的级别。截至v1.0版本,以下解析器是内置的,编写自己的也非常简单。更多解析器通过PR贡献将非常欢迎,如下所示,编写它们非常容易!
但是再次强调,为了更清晰,如果你的测试运行器返回正常输出代码,你只需将其添加进去,它将运行得非常好。
命令行选项
运行polytester。
Polytester会响应pt
或polytester
。两者做的完全一样。
选项
有各种选项可以简化开发。
polytester foo
或polytester foo,bar
将运行指定的测试套件。--autoreload
或--ci
监视在watch_glob
中指定的所有文件,并在文件更改时立即运行相关的套件。任何正在运行的测试都将被终止。--wip
通过运行所有指定该选项的套件的wip_command
来运行标记为“工作正在进行中”的测试。--verbose
或-v
将所有输出打印到shell。为了避免冲突,在此模式下运行时,测试套件将按顺序执行,而不是正常并行执行。--parallel n m
仅运行m
个测试块中的n
个,用于并行构建测试环境。--config foo.yml
指定配置文件的不同位置。默认为tests.yml
高级用法
如果您想充分利用polytester,其背后还有更多内容,包括wip、自动重载、通过/失败计数、自定义框架等。
这里是一切美好。
自动重载
当文件更改时自动运行测试非常方便。使用polytester,这很简单。
-
在您的
tests.yml
中指定一个watch_glob
(可选地指定一个watch_dir
)python: command: nosetests watch_glob: "*.py" watch_dir: api
-
使用
--autoreload
运行polytester --autoreload
每次更改匹配glob的文件时,polytester都会立即运行匹配的测试套件。该套件的任何正在运行的测试都会立即被终止。
注意事项
- 如果没有指定
watch_dir
,它默认为当前目录。 - 要指定多种文件类型,可以使用标准的Unix glob,例如
*.html;*.js;*.css
。 - 使用
--autoreload
运行时,只会运行配置中包含watch_glob
的测试。这听起来很合理,但一开始可能会让你感到惊讶。
自动重载演示
工作正在进行中的测试
能够标记和运行某些测试组可以大大节省大型代码库的开发时间。Polytester使这变得简单。只需指定一个wip_command
,然后使用--wip
运行。
-
在您的
tests.yml
中指定一个wip_command
python: command: nosetests wip_command: nosetests -a wip
-
使用
--wip
运行polytester --wip
就这样!
并行执行
如果您在一个具有并行构建的ci平台上运行,如CircleCI,那么--parallel
选项可以为您节省一些时间。
只需设置您的构建配置以使用它,并传入适当的shell变量。
对于CircleCI,只需设置您的circle.yml
为
test:
override:
- polytester --parallel $CIRCLE_NODE_INDEX $CIRCLE_NODE_TOTAL:
parallel: true
然后您就设置好了。您的测试套件将根据您拥有的构建容器的数量自动拆分。
指定测试框架
如果您使用的是任何支持框架的默认测试命令,polytester将检测正确的框架,并让您继续。但是,如果您使用的是自定义运行器或一些特别的东西,您可以很容易地指定polytester应使用哪个解析器。
假设由于过于复杂的解释原因,我有一个围绕我的nose脚本的定制包装器。没问题。在我的tests.yml
中,我只告诉polytester期望nose输出。
python:
command: my_custom_nose_script.sh
parser: polytester.NoseParser
现在,当您运行时,您将得到以下输出
$ polytester
Detecting...
✔ python specified as nose tests.
Running tests...
✔ python: 47 tests passed.
✔ All tests passed.
以下是内置解析器的完整列表
DefaultParser
(仅监听退出代码,不支持测试数量。)NoseParser
DjangoParser
KarmaParser
ProtractorParser
SaladParser
如果您需要列表中未包含的解析器,您可以通过编写几个简单的函数来创建它。请参阅下方的自定义解析器。
所有选项
这是一个包含所有内容的 yml 文件,仅用于方便参考。
python:
command: nosetests
wip_command: nosetests -a wip
watch_glob: "*.py;*.html" # Note you do need quotes because of the *.
watch_dir: my_app/foo
parser: my_parsers.MyNiftyCustomNoseParser
编写自定义解析器
任何返回标准错误代码(0 表示通过,非零表示失败)的测试框架都可以直接使用。但是,如果您想要更复杂的测试计数(以及将来更多),编写自定义解析器很容易。
只需编写一个继承自 DefaultParser
的类,将其放在您的 python 路径上的某个位置,将其放入您的 tests.yml
文件中,您就可以开始了。以下是一个针对 pep8 的示例。
请注意:如果您是为常见的框架/用例编写,请提交一个 pull request!
-
编写您自己的解析器。
my_parsers.py
from polytester.parsers import DefaultParser class MyCustomParser(DefaultParser): name = "my custom" def tests_passed(self, result): # Required, the code below is the default in DefaultParser return result.return_code == 0 def num_failed(self, result): # Optional. m = re.match("(\d+) failed", result.output) return int(m.group(0)) def num_passed(self, result): # Optional. return self.num_total(result) - self.num_failed(result) def num_total(self, result): # Optional. m = re.match("(\d+) total", result.output) return int(m.group(0)) def command_matches(self, command_string): # Optional, used for trying to auto-detect the test framework. # Since this is totally custom, we just return false return False
为了参考,
results
是一个具有以下属性的对象output
- 运行时产生的 stdout 和 stderr 的顺序。cleaned_output
-output
,但移除了所有 ANSI 颜色和转义代码。return_code
- 返回代码。passed
- 一个布尔值,表示测试是否通过。在得到最终答案之前为None
。parser
- 解析器类的实例。(即您可以使用result.parser.num_failed(result)
调用它)。
-
在您的 test.yml 文件中指定它。
custom: command: run_tests.sh parser: my_parsers.MyCustomParser
-
像平常一样运行您的测试!
$ polytester Detecting... ✔ custom specified as my custom tests. Running tests... ✔ custom: 18 tests passed. ✔ All tests passed.
当事情出错时。
当测试失败时,polytester 只会回退到您的测试框架已提供的有用输出。
$ polytester
Detecting...
✔ api detected as django tests.
✔ e2e detected as karma tests.
✔ js detected as protractor tests.
Running tests...
✘ api - 1 of 35 tests failed.
======================================================================
FAIL: test_addition (events.tests.SampleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/me/project/events/tests.py", line 6, in test_addition
self.assertEquals(1+1, 3)
AssertionError: 2 != 3
----------------------------------------------------------------------
Ran 35 tests in 1.642s
FAILED (failures=1)
✔ e2e - 17 tests passed.
✔ js - 23 tests passed.
✘ Tests failed
站在巨人的肩膀上
Polytester 利用一些出色的库。没有它们,它就不会存在。
Polytester 还得到了许多程序员的帮助。按字母顺序排列
- brandoncazander 为您在较旧的 python 版本中提供了更健壮的 ansi 解析。
- calebmeyer 为您提供了 rspec 支持。
- joshfriend 添加了 py.test 支持,并在 python 2.7.x 中发现了
--ci
的一个错误。 - jpulec 为您修复了 karma 测试解析。
版本发布
1.2.2 - 2022 年 2 月 19 日
- 取消锁定需求,添加了更新的 python 覆盖率,以便使用新的 pip 解析器更容易解决。
1.2.1 - 2015 年 3 月 12 日
- 由于 jpulec 的贡献,对 karma 测试输出解析进行了改进。
1.2.0 - 2015 年 3 月 6 日
- 对测试运行器和监视线程的处理方式进行了相当大的重写,以修复 alecklandgraf 报告的不兼容性。
1.1.3 - 2015 年 3 月 3 日
- 由于 calebmeyer 的贡献,添加了 rspec 解析器。
- 由于 brandoncazander 的贡献,对较旧的 python 版本的 ansi 解析进行了改进。
1.1.2 - 2015 年 2 月 5 日
- 修复了 python 3.4 中的
--ci
的错误。
1.1.1 - 2015 年 1 月 30 日
- 修复了 django 解析器的 copypasta 错误。
1.1 - 2015 年 1 月 30 日
- polytester 测试套件的开始,完全归功于 joshfriend。
- joshfriend 添加了 python unittest 运行器的解析器。
- joshfriend 通过修复 nose 解析器。
- 修复了由1.0.2版本引入的测试输出中的错误。感谢joshfriend提供报告。
- 注意到一个模式吗?这个模式就是像joshfriend这样的人让开源变得如此精彩。
- 现在所有代码都通过了pep8检查。
1.0.2 - 2015年1月30日
- 添加了对py.test的支持,感谢joshfriend。
- 修复了在python 2.7.x上的KeyboardInterrupts支持,感谢joshfriend的报告。
1.0.1 - 2015年1月27日
- 修复了--parallel的bug。
1.0 - 2015年1月27日 - "Rick James"
- 所有RDD特性都已实现,我们正在生产中使用polytester。
0.1.3 - 2015年1月22日
- 除了
--ci
、--failfast
和几个解析器外,其他所有内容都已包含。
0.1.2 - 2015年1月21日
- 在python 3上运行正常。首个稳定版本!
0.1.1 - 2015年1月21日
- 修复了包含wsgiref的问题,这会导致python 3因print语句而出错。
0.1 - 2015年1月21日
- 首次发布。基本功能正常,仅包含Django解析器。非常RDD。
展望未来
与我所管理的所有开源项目一样,我将项目的未来留给了使用该项目的用户的需求,以及提交的PR。
但以下是我脑海中思考的一些未来功能
- 完整的测试覆盖率。我们已经有了良好的开端,但长期目标是100%(或接近)的覆盖率,包括一些集成测试。
- 更好的测试输出解析,仅列出失败的测试文件名和行号或其他高级特性。
- xUnit输出
--failfast
,用于超快速迭代。- 解析器能够更好地进行并行化内省(基于glob等)的能力
- 你带来的任何优秀内容!
贡献
PR欢迎!
如果你想添加对某种语言或框架的支持,这些PR总是受欢迎的。
如果你有一个更大的想法,只需打开一个问题,我们将会讨论,这样在PR来的时候我们不会出现交叉线。
文化
无论技能水平或经验如何,任何人都可以为polytester做出贡献。为了使polytester变得尽可能好,我们有一个重要的文化原则
友好。
简单。容易,对吧?
我们都是新手程序员,我们都曾有过糟糕的日子,我们都对库感到沮丧,我们都说过后来才学的语言。在与其他程序员、PR和CR的讨论中,我们只是给予每个人好处,认真倾听,并假设他们的最佳意图。这效果非常好。
这并不意味着我们没有关于将polytester推向前进的方向或如何实现功能的坦诚而热烈的讨论。我们确实有。我们只是在做的时候互相尊重。不太好,对吧?:)
测试
为了您的测试方便,包含了一个Makefile
。以下是一些示例命令
$ make test # run the tests on the default python version (3.4)
$ make test-all # run tests on all supported pythons (2.7, 3.3, 3.4)
$ make flake8 # run a pep8/pyflakes style/syntax check
$ make clean # remove cached/compiled python test data
$ make clean-all # rebuild the virtualenv from scratch
Makefile
将负责创建virtualenv并安装所需的依赖项(并保持它们更新)。
如果您未安装所有支持的Python版本,请不要担心!将您的更改推送到分支,打开一个pull-request,Travis将代表您运行测试。
项目详情
下载文件
下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。