如何对python中的不同实现使用相同的单元测试?

如何对python中的不同实现使用相同的单元测试?,python,unit-testing,automated-tests,tdd,python-unittest,Python,Unit Testing,Automated Tests,Tdd,Python Unittest,我正在开发多个函数,它们回答同一个问题,但使用不同的算法 因此,所有函数的相同输入应该生成相同的输出,这就是为什么我选择使用相同的单元测试,而不是使用相同的逻辑创建多个测试 我使用的是Python unittest框架,我想使用一个抽象测试类,用一个函数变量定义泛型测试,这样我就可以用我想在另一个普通测试类中测试的泛型函数实例化该泛型函数。但我似乎无法在子类中实例化函数变量 下面是一个抽象类的示例,其中包含多个函数的通用测试 class AbstractTestCase(): def

我正在开发多个函数,它们回答同一个问题,但使用不同的算法

因此,所有函数的相同输入应该生成相同的输出,这就是为什么我选择使用相同的单元测试,而不是使用相同的逻辑创建多个测试

我使用的是Python unittest框架,我想使用一个抽象测试类,用一个函数变量定义泛型测试,这样我就可以用我想在另一个普通测试类中测试的泛型函数实例化该泛型函数。但我似乎无法在子类中实例化函数变量

下面是一个抽象类的示例,其中包含多个函数的通用测试

class AbstractTestCase():

    def test_generic_input_one(self):
        result = self.function("input 1")
        self.assertFalse(result)

    def test_generic_input_two(self):
        result = self.function("input 2")
        self.assertTrue(result)
这里您将为
函数a
创建一个特定的测试类,该类继承了
AbstractTestCase
类的通用测试,并实现了自己的测试

class TestsFunctionA(AbstractTestCase, unittest.TestCase):

    def setUp(self):
        self.function = function_a

    def test_specific_input(self):
        result = self.assertTrue(self.function("specific input"))
        self.assertTrue(result)
我很确定这是可以做到的,但我似乎找不到一个例子来说明如何实现它。我希望避免代码重复


最简单和最好的方法是什么?

我一直在寻找它,并得到了一些示例,如:

但对我帮助最大的是制作一个类工厂,它将接受参数并相应地创建测试用例

该函数获取参数化测试用例的参数,实际的测试用例类可以毫无问题地引用这些参数

下面是一个示例,以具有以下内容的
foo.py
文件为例:

导入单元测试
def制造测试用例(x):
类MyTestCase(unittest.TestCase):
def测试_-foo(自身):
self.assertEquals(x,1)
返回MyTestCase
类ConcreteTestCase(生成测试用例(1)):
通过
然后运行测试:


基本上,这是非常灵活的,并且非常适合我的用例

基本上,您需要使用函数参数化您的测试

对于
unittest
,您可以使用

或者,您可以仅使用普通OOP:

class AbstractTestCase(object):

    def test_generic_input_one(self):
        result = self.function("input 1")
        self.assertFalse(result)

    def test_generic_input_two(self):
        result = self.function("input 2")
        self.assertTrue(result)

class TestsFunctionA(AbstractTestCase, unittest.TestCase):

    def function(self, param):
        return function_a(param)

    def test_specific_input(self):
        self.assertTrue(self.function("specific input"))

class TestsFunctionB(AbstractTestCase, unittest.TestCase):

    def function(self, param):
        return function_b(param)

    def test_another_specific_input(self):
        self.assertTrue(self.function("another specific input"))

我来这里是为了寻找一种方法来测试同一函数的多个实现。我的用例是测试学生提交的不同搜索算法,这些算法都提供了相同的测试数据,并且应该返回相同的结果

Sylhare的答案很容易采纳,但分享也无妨,因此以下是如何做到的:

import unittest

def function_a():
    result = ...
    return result

def function_b():
    result = ...
    return result

def make_test(function):

    class TestImplementation(unittest.TestCase):

        def test_foo(self):
            self.assertEquals(function, 1)

    return TestImplementation

class TestImplementationA(make_test(function_a)): 
    pass

class TestImplementationB(make_test(function_b)): 
    pass

给定的结构

├── README.md
├── requirements.txt
├── test
│   ├── __init__.py
│   └── two_sum
│       ├── __init__.py
│       ├── base_test_suite.py
│       ├── test_brute_force.py
│       └── test_two_pass_hash_table.py
└── two_sum
    ├── __init__.py
    ├── brute_force.py
    └── two_pass_hash_table.py
two\u sum
模块中的相应文件中有蛮力和两次传递哈希表解决方案(函数名为
two\u sum

基本测试套件.py

class TestTwoSum:
    def __init__(self, unittest, two_sum_func):
        self.two_sum = two_sum_func
        self.unittest = unittest

    def test_it_returns_indices_of_two_numbers_that_add_up_to_target(self):
        # given
        numbers = [2, 7, 11, 15]
        target = 9

        # when
        result = self.two_sum(numbers, target)

        # then
        self.unittest.assertEqual(result, [0, 1])
测试暴力

从unittest导入TestCase
从test.two\u sum.base\u test\u套件导入TestTwoSum
从two_sum.brute_force导入two_sum
类测试(TestCase):
def测试(自我):
case=TestTwoSum(self,two_sum)
case.test\u it\u返回两个\u数字的\u索引\u,这些数字加起来\u到\u目标()
测试两次通过哈希表.py

从unittest导入TestCase
从test.two\u sum.base\u test\u套件导入TestTwoSum
从two\u sum.two\u pass\u哈希表导入two\u sum
类测试(TestCase):
def测试(自我):
case=TestTwoSum(self,two_sum)
case.test\u it\u返回两个\u数字的\u索引\u,这些数字加起来\u到\u目标()

然后可以运行
python-m unittest
,它将对两个和问题的不同解决方案运行相同的单元测试。

您能否再详细说明一下这句话:“我想使用一个抽象测试类,但它不接受任何类型的变量,因此我无法传递函数。”?我编辑了这个问题,我的目标是用抽象类中的函数变量定义泛型测试,这样我就可以用我想在子测试类中测试的函数实例化泛型函数。但是我似乎无法在子类中实例化函数变量。谢谢你的回答!——我认为ddt已被弃用,但pytest似乎与annotation具有相同的特性。对于简单的OOP示例:它非常好!我想知道它是否能处理多重继承。我将用你的例子来验证这一点。你觉得我找到的答案怎么样?多重继承会很好。我知道类生成的解决方案不必要地复杂。哦,我发现了一件事,你不能将
unittest.Testcase
继承到AbstractTestClass,否则测试将在其中运行并失败。它应该类似于
TestFunction(AbstractTestCase,unittest.TestCase)
让测试与子类一起运行。即使您使用的是pytest,这也会起作用。你可以省去遗产。
├── README.md
├── requirements.txt
├── test
│   ├── __init__.py
│   └── two_sum
│       ├── __init__.py
│       ├── base_test_suite.py
│       ├── test_brute_force.py
│       └── test_two_pass_hash_table.py
└── two_sum
    ├── __init__.py
    ├── brute_force.py
    └── two_pass_hash_table.py
class TestTwoSum:
    def __init__(self, unittest, two_sum_func):
        self.two_sum = two_sum_func
        self.unittest = unittest

    def test_it_returns_indices_of_two_numbers_that_add_up_to_target(self):
        # given
        numbers = [2, 7, 11, 15]
        target = 9

        # when
        result = self.two_sum(numbers, target)

        # then
        self.unittest.assertEqual(result, [0, 1])