有没有一种方法可以在Python的unittest框架中自动创建测试用例?

问题描述 投票:0回答:1

[我们想为一个(简单的)数学库编写测试用例,该库(当前)仅实现两个例程sqrtln。除其他事项外,如果两个例程的输入为负,则它们都将提高ValueError。因此,测试用例将如下所示:

import unittest
from my_math_lib import sqrt, ln

class TestSqrt(unittest.TestCase):

    def test_negatives(self):
        self.assertRaises(ValueError, sqrt, -5)

    # ... any many other cases 

class TestLn(unittest.TestCase):

    def test_negatives(self):
        self.assertRaises(ValueError, ln, -5)

    # ... any many other cases 

显然,除了要测试的功能外,两个测试用例TestSqrt.test_negativesTestLn.test_negatives是相同的,重复完全相同的代码是个坏主意。

是否可以自动生成此类测试用例?例如,在C / C ++中,可能已经实现了一个宏,该宏使用适当的函数名定义了测试代码。 Python中有类似的解决方案吗?

python python-unittest
1个回答
0
投票

[@ jonrsharpe提出了子类化的可能性,尽管有一个警告。您不能从unittest.TestCase派生基类并在此处编写testXXX,因为这也会被发现并执行,并且会失败。您需要混入:

class BaseTest:
    def setUp(self):
        self.tested = None

    def test_negatives(self):
        self.assertRaises(ValueError, self.tested, -5)

class TestSqrt(unittest.TestCase, BaseTest):
    def setUp(self):
        self.tested = sqrt

class TestLn(unittest.TestCase, BaseTest):
    def setUp(self):
        self.tested = log

这有效,但是不好用,因为基类从TestCaseassertRaises)调用了一个不派生自该方法的方法,因此每一个linter或IDE检查都会警告您这一点。

要变通解决此问题,您可以只使用一种实际的实现作为基类:

class TestSqrt(unittest.TestCase):
    def setUp(self):
        self.tested = sqrt

    def test_negatives(self):
        self.assertRaises(ValueError, self.tested, -5)

class TestLn(TestSqrt):
    def setUp(self):
        self.tested = log

class TestSomethingElse(TestSqrt):
    def setUp(self):
        self.tested = something_else

如果可以使用pytest,我将使用夹具参数化:

import pytest

@pytest.fixture(params=[sqrt, log])
def tested_function(request):
    return request.param

def test_negatives(tested_function):
    with pytest.raises(ValueError):
        tested_function(-5)

def test_something_else(tested_function):
    ...

当然,您也可以将其放在课堂上。注意:unittest不起作用,或者至少我不知道一种干净的方法。

© www.soinside.com 2019 - 2024. All rights reserved.