17

我曾与 Spock 合作过,并且喜欢 'where' 子句,它允许您轻松地使用多个输入和输出来练习测试用例。例如:

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
    }
} 

Python有类似的东西吗?

4

6 回答 6

12

就在这里!

我是Nimoy的作者——一个为 Python 构建的框架。

您可以创建数据驱动的测试:

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

您可以进行模拟:

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

我们也有非常模拟的断言:

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)
于 2019-10-24T08:12:54.103 回答
5

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
于 2012-06-12T10:15:14.973 回答
5

我也是 Java/Groowy 世界中 Spock 框架的忠实粉丝。在 Python 中搜索类似。在我的搜索中,我发现了看起来很有希望的nimoy 。

来自官方页面的示例:

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

还有作者博客文章为什么它诞生了。

于 2019-05-12T21:45:38.860 回答
3

如果你有多个测试,我会推荐一个 BDD 框架,比如行为。您指定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"

以及用于解析它的 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'])

编写 Python 代码相当容易,网上有许多样板代码示例。这种技术的美妙之处在于您的测试套件具有高度的可重用性,并且可以很容易地由非程序员进行扩展。

于 2014-02-01T17:10:09.470 回答
2

不,那里没有。这很可悲,因为Spock真的很棒。我已经找了一年了,因为我非常想念它,所以我一直在思考在 python 中创建这样一个 DSL 需要什么。

Behave 和 Lettuce 将为您提供 BDD 样式的语法和习语,但您必须维护与您的场景文件匹配的单独步骤文件。显然,当您想要进行 TDD 但具有 Spock 所支持的 BDD 的可读性时,这很糟糕。

如果您还想要 Spock 风格的模拟,那么Mox是我找到的最接近的。但是一旦你被Spock宠坏了,它又是一个糟糕的替代品。

于 2015-08-31T19:19:51.307 回答
0

有一个新的 pytest 插件可以做到这一点:https ://github.com/zen-xu/spock

下面是一个测试函数的例子,取自它的文档:

@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

我喜欢你可以使用内部 python 方法的方式,文档清晰且易于使用。

于 2021-11-04T06:03:40.367 回答