跳转到主要内容

一个简单易用的多语言测试运行器。

项目描述

Polytester Logo

Polytester是一个简单易用的多语言测试运行器。

它使您能够轻松地在多语言项目中运行测试。可以并行运行python、javascript、ruby、java等多种语言。它抽象了配置的痛苦,让您专注于开发。简单高效。

Polytester与任何在shell中运行的测试框架(是的,这几乎涵盖了地球上的一切)兼容,并且提供了对包括django、karma、protractor等众多常见框架的额外平滑集成。Polytester由Steven Skoczen构建。

Build Status Pypi Badge Downloads Badge

安装

pip install polytester

入门

  1. 创建一个tests.yml文件。以下示例展示了django、protractor和karma(jasmine)测试。

    api:
        command: python manage.py test
    js:
        command: karma start karma.conf.js
    e2e:
        command: protractor
    
  2. 运行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秒

install

支持框架

任何返回标准错误代码的测试框架都将直接工作。几乎涵盖了所有内容。

此外,polytester会逐步将具有解析器的框架输出升级到更优秀的级别。截至v1.0版本,以下解析器是内置的,编写自己的也非常简单。更多解析器通过PR贡献将非常欢迎,如下所示,编写它们非常容易!

但是再次强调,为了更清晰,如果你的测试运行器返回正常输出代码,你只需将其添加进去,它将运行得非常好。

命令行选项

运行polytester。

Polytester会响应ptpolytester。两者做的完全一样。

选项

有各种选项可以简化开发。

  • polytester foopolytester 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,这很简单。

  1. 在您的tests.yml中指定一个watch_glob(可选地指定一个watch_dir

    python: 
        command: nosetests
        watch_glob: "*.py"
        watch_dir: api
    
  2. 使用--autoreload运行

    polytester --autoreload
    

每次更改匹配glob的文件时,polytester都会立即运行匹配的测试套件。该套件的任何正在运行的测试都会立即被终止。

注意事项

  • 如果没有指定watch_dir,它默认为当前目录。
  • 要指定多种文件类型,可以使用标准的Unix glob,例如*.html;*.js;*.css
  • 使用--autoreload运行时,只会运行配置中包含watch_glob的测试。这听起来很合理,但一开始可能会让你感到惊讶。

自动重载演示

ci-small-2

工作正在进行中的测试

能够标记和运行某些测试组可以大大节省大型代码库的开发时间。Polytester使这变得简单。只需指定一个wip_command,然后使用--wip运行。

  1. 在您的tests.yml中指定一个wip_command

    python: 
        command: nosetests
        wip_command: nosetests -a wip
    
  2. 使用--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!

  1. 编写您自己的解析器。

    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) 调用它)。
  2. 在您的 test.yml 文件中指定它。

    custom: 
        command: run_tests.sh
        parser: my_parsers.MyCustomParser
    
  3. 像平常一样运行您的测试!

    $ 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 利用一些出色的库。没有它们,它就不会存在。

  • Clint 用于所有漂亮的 shell 输出,
  • Watchdog 用于神奇的文件监控,以及
  • PyYAML 因为没有人应该再次考虑解析 yaml 文件。

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将代表您运行测试。

项目详情


下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。

源代码分布

polytester-1.2.3.tar.gz (23.9 kB 查看哈希值)

上传时间 源代码

构建分布

polytester-1.2.3-py3-none-any.whl (22.5 kB 查看哈希值)

上传时间 Python 3

由以下支持