Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. 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?

like image 998
bjnortier Avatar asked Jun 12 '12 09:06

bjnortier


2 Answers

Yes, there is!

I'm the author of Nimoy - a framework that was built with the purpose of being 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)
like image 156
noamt Avatar answered Oct 19 '22 10:10

noamt


pytest allows you to parametrise a test function:

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
like image 41
ecatmur Avatar answered Oct 19 '22 11:10

ecatmur