Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.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';什么是单元测试子测试?_Python_Python 3.x_Unit Testing_Python Unittest - Fatal编程技术网

在使用Python';什么是单元测试子测试?

在使用Python';什么是单元测试子测试?,python,python-3.x,unit-testing,python-unittest,Python,Python 3.x,Unit Testing,Python Unittest,我很难为这种情况想出一个优雅的解决方案 假设我有一个Python中的unittest,它将测试一个iterable中的几个元素。由于这个iterable在内存中构建成本很高,所以我只想通过该方法构建一次。然后,在每个测试中,我想顺序地将iterable中的每个元素传递给测试,我可以使用。这一切都很好 下面的代码是一个模拟测试用例的示例,它完全按照我所描述的那样执行: import unittest class NumberTest(unittest.TestCase): @class

我很难为这种情况想出一个优雅的解决方案

假设我有一个Python中的unittest,它将测试一个iterable中的几个元素。由于这个iterable在内存中构建成本很高,所以我只想通过该方法构建一次。然后,在每个测试中,我想顺序地将iterable中的每个元素传递给测试,我可以使用。这一切都很好

下面的代码是一个模拟测试用例的示例,它完全按照我所描述的那样执行:

import unittest

class NumberTest(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.numbers = []
        for x in range(1000):
            cls.numbers.append(x)

    @classmethod
    def tearDownClass(cls):
        del cls.numbers

    def test_number_is_even(self):
        for n in self.numbers:
            with self.subTest(current_number=n):
                self.assertEqual(n % 2, 0)

    def test_number_is_odd(self):
        for n in self.numbers:
            with self.subTest(current_number=n):
                self.assertEqual(n % 2, 1)

    def test_number_is_positive(self):
        for n in self.numbers:
            with self.subTest(current_number=n):
                self.assertTrue(n > 0)

    def test_number_is_negative(self):
        for n in self.numbers:
            with self.subTest(current_number=n):
                self.assertTrue(n < 0)


if __name__ == '__main__':
    unittest.main()
导入单元测试
类NumberTest(unittest.TestCase):
@类方法
def设置等级(cls):
cls.numbers=[]
对于范围(1000)内的x:
cls.number.append(x)
@类方法
def拆卸类(cls):
del cls.number
def测试编号为偶数(自):
对于n,在self.number中:
使用self.subTest(当前_编号=n):
self.assertEqual(n%2,0)
def测试编号为奇数(自):
对于n,在self.number中:
使用self.subTest(当前_编号=n):
self.assertEqual(n%2,1)
def测试编号为正(自身):
对于n,在self.number中:
使用self.subTest(当前_编号=n):
self.assertTrue(n>0)
def测试编号为负(自身):
对于n,在self.number中:
使用self.subTest(当前_编号=n):
self.assertTrue(n<0)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
unittest.main()
让我头疼的是self.numbers:with self.subTest(current_number=n)中n的行
。有没有办法避免这种情况?我知道我可以简单地将所有的
self.assert
语句聚集在一个方法中,但这首先会破坏对不同方面进行不同测试的目的


在我看来,“理想”的解决方案是,以某种方式,
从iterable中产生
值(可能通过
设置
方法?没有线索),并在产生下一个测试方法之前将这些值传递给每个测试方法。但我不知道如何真正做到这一点,特别是因为它涉及到一个上下文管理器。。。有没有人有其他的解决方案,或者根本没有解决办法

一个简单的解决方案是将
语句外包给装饰师。但每个测试用例仍需要一行代码:

import functools
import unittest


class NumberTest(unittest.TestCase):
    # ...
    def for_each_number(test_func):
        @functools.wraps(test_func)
        def decorated(self):
            for n in self.numbers:
                with self.subTest(current_number=n):
                    test_func(self, n)
        return decorated

    @for_each_number
    def test_number_is_even(self, n):
        self.assertEqual(n % 2, 0)

    @for_each_number
    def test_number_is_odd(self, n):
        self.assertEqual(n % 2, 1)
    # ...

当然,这不会像理想的解决方案那样在iterable上运行一次。为此,你需要装饰整个班级。这似乎可以通过库中的
@参数化_类
装饰器实现。不过我从来没有单独使用过这个装饰器。

欢迎jfaccioni。你说你测试一个iterable的元素,但是,单元测试就是测试代码,看看代码中是否有bug。也许这是个误会。如果您试图在代码中找到bug,请您显示该代码好吗?否则,我们这里可能不会讨论单元测试。谢谢您的评论。我想做的是测试我的一门课。在我的实际代码中,这个类的实例是通过从一个长文件(显微镜检测数据)中读取输入值构建的,每行一个实例。对于这些测试,我创建了一个模拟数据文件,从中我在
setUpClass
方法中实例化了类的模拟实例。但现在我写了这篇文章,我意识到这可能根本不是单元测试。。。因为我测试的是类的不同实例,而不是代码本身。我不习惯单元测试,所以我可能以错误的心态处理问题。