Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Py.test:参数化类中的测试用例_Python_Unit Testing_Automated Tests_Pytest - Fatal编程技术网

Python Py.test:参数化类中的测试用例

Python Py.test:参数化类中的测试用例,python,unit-testing,automated-tests,pytest,Python,Unit Testing,Automated Tests,Pytest,我目前正在遵循这个示例,当我不使用类时,它会起作用,但是当我将测试用例引入类时,我失败了 我设法编写的最小案例如下: import unittest import pytest class FixtureTestCase(unittest.TestCase): @pytest.mark.parametrize("test_input,expected", [ ("3+5", 8), ("2+4", 6), ("6*9", 42), ]) de

我目前正在遵循这个示例,当我不使用类时,它会起作用,但是当我将测试用例引入类时,我失败了

我设法编写的最小案例如下:

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)

如何生成一组测试1测试?

如果您从
unittest.TestCase
生成子类,您的测试方法不能有其他参数。如果您只是从
对象
中创建子类,它将起作用(尽管您必须使用常规的
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

然而,在这一点上,它有点回避了这样一个问题:为什么要使用类而不仅仅是定义函数,因为测试本质上是相同的,但需要更少的总体样板和代码。

最后,考虑到@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)
然后,我可以通过以下命令执行测试:


我不知道5年前是否是这样,但现在您可以使用parameterized()和pytest来修饰测试类上的测试方法,是的,包括unittest.TestCase,而不必求助于nose。例如:

从unittest导入TestCase
从参数化导入参数化
类SomeTestCase(TestCase):
@参数化.expand([
(1, 2),
(‘a’、‘b’)
])
def测试(自身、参数1、参数2):
...

唯一的问题是,但您最好记住这一点,装饰程序将为每个列出的输入参数生成新的测试方法,因此您将无法通过在命令行上指定它来直接运行原始测试方法。例如,
pytest some_test.py::SomeTestCase::test_something
将不再工作(因为您的测试方法现在需要两个参数)。但是,您可以直接调用生成的方法,您可以在运行整个TestCase时从pytest错误输出中获取名称,也可以通过执行
pytest--collect only

对于仍然感兴趣的人,我在@pytest.mark.parametrize replacement for unittest.TestCase中写了一个drop in@pytest.mark.parametrize:

$pytest.py::FixtureTestCase::test\u 1

Test session starts (platform: darwin, Python 3.9.4, pytest 6.2.4, pytest-sugar 0.9.4)
plugins: sugar-0.9.4, cov-2.11.1, mock-3.6.0
collecting ... 
 test.py ✓✓                                                       67% ██████▋   

―――――――――――――――――――――――― FixtureTestCase.test_1[6*9-42] ――――――――――――――――――――――――

self = <test.FixtureTestCase testMethod=test_1[6*9-42]>, test_input = '6*9'
expected = 42

    @parametrize(
        "test_input,expected",
        [
            ("3+5", 8),
            ("2+4", 6),
            ("6*9", 42),
        ]
    )
    def test_1(self, test_input, expected):
>       self.assertEqual(eval(test_input), expected)
E       AssertionError: 54 != 42

test.py:16: AssertionError

 test.py ⨯                                                       100% ██████████
=========================== short test summary info ============================
FAILED test.py::FixtureTestCase::test_1[6*9-42] - AssertionError: 54 != 42

Results (0.09s):
       2 passed
       1 failed
         - test.py:7 FixtureTestCase.test_1[6*9-42]
测试会话开始(平台:darwin、Python 3.9.4、pytest 6.2.4、pytest sugar 0.9.4)
插件:sugar-0.9.4、cov-2.11.1、mock-3.6.0
收集。。。
test.py✓✓                                                       67% ██████▋   
――――FixtureTestCase.test―U1[6*9-42]―――
self=,测试输入='6*9'
期望值=42
@参数化(
“应为测试输入”,
[
("3+5", 8),
("2+4", 6),
("6*9", 42),
]
)
def测试单元1(自身,测试单元输入,预期):
>self.assertEqual(评估(测试输入),预期)
E断言错误:54!=42
test.py:16:AssertionError
test.py⨯                                                       100% ██████████
==============================================短测试摘要信息============================
失败的测试。py::FixtureTestCase::test_1[6*9-42]-断言错误:54!=42
结果(0.09s):
2通过
1次失败
-test.py:7 FixtureTestCase.test_1[6*9-42]

您的类是否需要成为
TestCase
的子类?目前,它不是强制性的,我需要的是将定义到类中的测试参数化。对于
TestCase
方法的参数化测试,这个老问题的答案似乎仍然有效:简言之:混合这两个概念是行不通的。这个建议工作正常,但pytest未标识任何测试。它打印出图例“收集的0项”。有什么建议吗?抱歉,我还想指出类名需要以
Test
开头,pytest也需要这样做。我刚刚接受了答案,但是我想知道当类从unittest继承时是否还有一个选项。TestCase?您将无法使用
参数化
。来自@t的链接homasLotze对此进行了解释。它们提供了一些绕过限制的可能性,在您的情况下,这可能涉及在类上设置测试值,然后在测试函数中循环通过它来运行具有多个测试值的测试。我有一个原因想知道,如果不可能,我将需要重新实现nu测试类的数量。
import unittest

from parametrize import parametrize

class FixtureTestCase(unittest.TestCase):

    @parametrize(
        "test_input,expected",
        [
            ("3+5", 8),
            ("2+4", 6),
            ("6*9", 42),
        ]
    )
    def test_1(self, test_input, expected):
        self.assertEqual(eval(test_input), expected)
Test session starts (platform: darwin, Python 3.9.4, pytest 6.2.4, pytest-sugar 0.9.4)
plugins: sugar-0.9.4, cov-2.11.1, mock-3.6.0
collecting ... 
 test.py ✓✓                                                       67% ██████▋   

―――――――――――――――――――――――― FixtureTestCase.test_1[6*9-42] ――――――――――――――――――――――――

self = <test.FixtureTestCase testMethod=test_1[6*9-42]>, test_input = '6*9'
expected = 42

    @parametrize(
        "test_input,expected",
        [
            ("3+5", 8),
            ("2+4", 6),
            ("6*9", 42),
        ]
    )
    def test_1(self, test_input, expected):
>       self.assertEqual(eval(test_input), expected)
E       AssertionError: 54 != 42

test.py:16: AssertionError

 test.py ⨯                                                       100% ██████████
=========================== short test summary info ============================
FAILED test.py::FixtureTestCase::test_1[6*9-42] - AssertionError: 54 != 42

Results (0.09s):
       2 passed
       1 failed
         - test.py:7 FixtureTestCase.test_1[6*9-42]