简体   繁体   English

是否有类似 Spock 的 Python 测试库

[英]Is there a Spock-like testing library for Python

I've worked with Spock and loved the 'where' clause, which allows you to easily exercise the test case with multiple inputs and outputs.我曾与 Spock 合作过并且喜欢“where”子句,它允许您轻松地使用多个输入和输出来练习测试用例。 For example:例如:

class HelloSpock extends spock.lang.Specification {
    def "length of Spock's and his friends' names"() {
        expect:
            name.size() == length

        where:
            name     | length
            "Spock"  | 5
            "Kirk"   | 4
            "Scotty" | 6
    }
} 

Is there something similar for Python? Python有类似的东西吗?

pytest allows you to parametrise a test function : pytest可以参数化测试功能

import pytest
@pytest.mark.parametrize(("input", "expected"), [
    ("3+5", 8),
    ("2+4", 6),
    ("6*9", 42),
])
def test_eval(input, expected):
    assert eval(input) == expected

If you have more than a few tests, I would recommend a BDD framework like behave . 如果您进行的测试不止几个,那么我建议使用BDD框架,例如behavior You specify a Gherkin syntax , eg (code from the linked tutorial): 您指定一个Gherkin语法 ,例如(链接教程中的代码):

Scenario: some scenario
  Given a set of specific users
     | name      | department  |
     | Barry     | Beer Cans   |
     | Pudey     | Silly Walks |
     | Two-Lumps | Silly Walks |

 When we count the number of people in each department
 Then we will find two people in "Silly Walks"
  But we will find one person in "Beer Cans"

And a Python code for parsing it, eg: 以及用于解析它的Python代码,例如:

@given('a set of specific users')
def step_impl(context):
    for row in context.table:
        model.add_user(name=row['name'], department=row['department'])

Writing the Python code is fairly easy, and there are numerous boilerplate code examples online. 编写Python代码非常容易,并且在线上有许多样板代码示例。 The beauty in this technique is that your testing suite is highly re-usable, and can be extended by non-programmers quite easily. 这种技术的优点在于您的测试套件可以高度重用,并且可以由非程序员轻松扩展。

I'm also big fan of Spock framework in Java/Groowy world. 我还是Java / Groowy世界中Spock框架的忠实拥护者。 In search similar in Python. 在搜索中类似Python。 In my searching I found nimoy which looks very promising. 在搜索中,我发现nimoy看起来很有希望。

Example from official page: 来自官方页面的示例:

from nimoy.specification import Specification

class MySpec(Specification):

    def my_feature_method(self):
        with given:
            a = value_of_a
            b = value_of_b

        with expect:
            (a * b) == expected_value

        with where:
            value_of_a | value_of_b | expected_value
            1          | 10         | 10
            2          | 20         | 40

And there also author blog post why it is born. 还有作者博客文章它为什么诞生。

No, there is not. 不,那里没有。 Which is sad because Spock is truly excellent. 令人遗憾的是,Spock确实很棒。 I have been looking for a year now and have pondered what it would take to create such a DSL in python since I miss it so much. 我一直在寻找一年,因为我非常想念它,所以在思考用python创建这样的DSL所需的时间。

Behave and Lettuce will get you BDD style syntax and idioms but you must maintain separate step files that match to your scenario files. 行为和生菜将为您提供BDD样式的语法和习惯用法,但您必须维护与方案文件匹配的单独的步骤文件。 Obviously this sucks for when you want to do TDD but have the readability of BDD which is what Spock enables. 显然,这在您想要进行TDD时很烂,但是却具有Spock启用的BDD的可读性。

If you also want Spock style mocks then Mox is the closest I have found. 如果您还想要Spock风格的模拟,那么Mox是我找到的最接近的。 But again it's a poor substitute once you are spoiled by Spock. 但是一旦您被Spock宠坏了,它仍然是一个糟糕的替代品。

Yes, there is! 就在这里!

I'm the author of Nimoy - a framework that was built with the purpose of being Spock for Python. 我是Nimoy的作者-这个框架的构建目的是成为Spock for Python。

You can create data driven tests: 您可以创建数据驱动的测试:

from nimoy.specification import Specification

class MySpec(Specification):

    def my_feature_method(self):
        with given:
            a = value_of_a
            b = value_of_b

        with expect:
            (a * b) == expected_value

        with where:
            value_of_a | value_of_b | expected_value
            1          | 10         | 10
            2          | 20         | 40

You can stage mocks: 您可以进行模拟:

from unittest import mock
from nimoy.specification import Specification

class MySpec(Specification):

    def my_feature_method(self):
        with setup:
            the_mock = mock.Mock()

        with when:
            the_mock.some_method() << [5, 6, 7]

        with then:
            the_mock.some_method() == 5
            the_mock.some_method() == 6
            the_mock.some_method() == 7

And we have pretty mock assertions as well: 而且,我们还有一些相当不错的断言:

from unittest import mock
from nimoy.specification import Specification

class MySpec(Specification):

    def my_feature_method(self):
        with setup:
            the_mock = mock.Mock()

        with when:
            the_mock.some_method('abcd', True)

        with then:
            1 * the_mock.some_method('abcd', True)

There is a new pytest plugin to do just that: https://github.com/zen-xu/spock有一个新的 pytest 插件可以做到这一点: https : //github.com/zen-xu/spock

Here is an example of a test function, taken from its documentation:这是一个测试函数的示例,取自其文档:

@pytest.mark.spock("{a} > {b}")
def test_bigger():
    def expect(a, b):
        assert a > b

    def where(_, a, b):
        _ | a | b
        _ | 7 | 3
        _ | 5 | 2

I like the way that you can use inner python methods, the documentation is clear and simple to use.我喜欢您可以使用内部 Python 方法的方式,文档清晰且易于使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM