Py.test: параметризовать тестовые примеры из классов

В настоящее время я следую этому примеру py.test, и он работает, когда я не использую классы, однако, когда я вводил тестовые примеры в классы я терпеть неудачу.

Самый маленький случай, который мне удалось написать, следующий:

import unittest

import pytest

class FixtureTestCase(unittest.TestCase):

    @pytest.mark.parametrize("test_input,expected", [
    ("3+5", 8),
    ("2+4", 6),
    ("6*9", 42),
    ])
    def test_1(self, a, b):
        self.assertEqual(a, b)

К сожалению, когда я выполняю

  py.test  test_suite.py

Я получаю сообщение об ошибке:

  TypeError: test_1() takes exactly 3 arguments (1 given)

Как я могу сделать, чтобы создать батарею тестов test_1?

Ответ 1

Если вы подклассом из unittest.TestCase, ваши методы тестирования не могут иметь дополнительных аргументов. Если вы просто подклассом из object, он будет работать (хотя вам придется использовать регулярные операторы assert вместо методов TestCase.assertEqual.

import unittest

import pytest

class TestCase(object):

    @pytest.mark.parametrize("test_input,expected", [
    ("3+5", 8),
    ("2+4", 6),
    ("6*9", 42),
    ])
    def test_1(self, a, b):
        assert eval(a) == b

В этот момент, однако, это вызывает вопрос, почему вы используете классы, а не просто определяете функции, поскольку тест будет по существу тем же, но требует меньше общего шаблона и кода.

Ответ 2

Наконец, и учитывая ответ @Brendan Abel и комментарии, мне удалось добиться успеха в том, что я собирался сделать:

class TestCase(object):

    @parameterized.expand([
    ("negative", -1.5, -2.0),
    ("integer", 1, 1.0),
    ("large fraction", 1.6, 1),
    ])
    def test_floor(self, name, input, expected):
        assert_equal(math.floor(input), expected)


    @parameterized.expand([
    ("3+5", 8),
    ("2+4", 6),
    ("6*9", 42),
    ])
    def test_1(self, a, b):
        assert_equal(eval(a), b)

Затем я могу выполнить тесты командой nosetests:

  nosetests -v --with-id class.py