Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/296.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

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 如何对大量数据测试相同的断言_Python_Unit Testing_Python Unittest - Fatal编程技术网

Python 如何对大量数据测试相同的断言

Python 如何对大量数据测试相同的断言,python,unit-testing,python-unittest,Python,Unit Testing,Python Unittest,我正在使用PythonUnitTest模块做一些测试;然而,它是非常重复的 我有很多数据,我想一遍又一遍地通过相同的测试,检查是否正确。但是,我必须为每个人定义一个测试 例如,我想做一些类似的事情。我知道我可以使用生成器(在前面的线程中找到)。但是否有其他选择,甚至可能使用不同的测试模块 任何建议都很好 import unittest class TestData(unittest.TestCase): def testNumbers(self): numbers =

我正在使用PythonUnitTest模块做一些测试;然而,它是非常重复的

我有很多数据,我想一遍又一遍地通过相同的测试,检查是否正确。但是,我必须为每个人定义一个测试

例如,我想做一些类似的事情。我知道我可以使用生成器(在前面的线程中找到)。但是否有其他选择,甚至可能使用不同的测试模块

任何建议都很好


import unittest

class TestData(unittest.TestCase):
    def testNumbers(self):
        numbers = [0,11,222,33,44,555,6,77,8,9999]
        for i in numbers:
            self.assertEqual(i, 33)

在循环中运行断言的问题是,如果其中一个断言失败,您不知道是哪个值导致了它(在您的示例中,它将在
0
上失败,但在调试之前您不知道)。另一方面,重复self.assertEqual(i,33)是一个更糟糕的想法,因为它引入了代码复制

我在测试中所做的是在测试中创建一个简单的、命名简短的内部函数,并使用不同的参数调用它。因此,您的函数如下所示:

import unittest

class TestData(unittest.TestCase):
    def testNumbers(self):
        def eq(i):
            self.assertEqual(i, 33)
        eq(0)
        eq(11)
        eq(222)
        eq(33)
        eq(44)
        eq(555)
        ... 
import unittest

class DataTestCase(unittest.TestCase):
    def __init__(self, number):
        unittest.TestCase.__init__(self, methodName='testOneNumber')
        self.number = number

    def testOneNumber(self):
        self.assertEqual(self.number, 33)

    def shortDescription(self):
        # We need to distinguish between instances of this test case.
        return 'DataTestCase for number %d' % self.number


def get_test_data_suite():
    numbers = [0,11,222,33,44,555,6,77,8,9999]
    return unittest.TestSuite([DataTestCase(n) for n in numbers])

if __name__ == '__main__':
    testRunner = unittest.TextTestRunner()
    testRunner.run(get_test_data_suite())

这样,当<代码> 0 断言时,您可以立即在“代码> UnTest.<代码>模块打印的堆栈跟踪中看到它。

< P>您可能需要考虑使用UNITTest.TestSu套类,这将允许您动态地构造一组单独运行的UNITest.TestCase实例。您的unittest.TestCase子类应该只定义一个测试方法,该类接受一个构造参数,并为该特定实例传递要测试的值

Bill Gribble建议的解决方案示例代码如下所示:

import unittest

class TestData(unittest.TestCase):
    def testNumbers(self):
        def eq(i):
            self.assertEqual(i, 33)
        eq(0)
        eq(11)
        eq(222)
        eq(33)
        eq(44)
        eq(555)
        ... 
import unittest

class DataTestCase(unittest.TestCase):
    def __init__(self, number):
        unittest.TestCase.__init__(self, methodName='testOneNumber')
        self.number = number

    def testOneNumber(self):
        self.assertEqual(self.number, 33)

    def shortDescription(self):
        # We need to distinguish between instances of this test case.
        return 'DataTestCase for number %d' % self.number


def get_test_data_suite():
    numbers = [0,11,222,33,44,555,6,77,8,9999]
    return unittest.TestSuite([DataTestCase(n) for n in numbers])

if __name__ == '__main__':
    testRunner = unittest.TextTestRunner()
    testRunner.run(get_test_data_suite())

在另一篇文章中,我无意中看到了罗斯 它更适合于数据驱动的测试


class Test_data():
    def testNumbers():
        numbers = [0,11,222,33,44,555,6,77,8,9999]
        for i in numbers:
            yield checkNumber, num

def checkNumber(num):
    assert num == 33
上面的代码与我的第一篇文章完全相同。 不需要导入,只需编写一个python类

您可以通过键入以下内容来执行测试:

nostests文件名

的构建旨在准确地解决您需要的
unittest
[*]

例如:

import ddt
import unittest

@ddt.ddt
class EvalTests(unittest.TestCase):

    @ddt.data(
            ('1', 1),
            ('1 == 1',  True),
            ('1 == 2',  False),
            ('1 + 2',   4),  ## This will fail
    )
    def test_eval_expressions(self, case):
        expr, exp_value = case
        self.assertEqual(eval(expr), exp_value)
当您运行它时,您会得到4个测试用例,而不是一个:

$ python -m unittest  -v  test_eval.py
test_eval_expressions_1___1___1_ (test_eval.EvalTests) ... ok
test_eval_expressions_2___1__1___True_ (test_eval.EvalTests) ... ok
test_eval_expressions_3___1__2___False_ (test_eval.EvalTests) ... ok
test_eval_expressions_4___1_2___4_ (test_eval.EvalTests) ... FAIL

======================================================================
FAIL: test_eval_expressions_4___1_2___4_ (test_eval.EvalTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python/lib/site-packages/ddt.py", line 129, in wrapper
    return func(self, *args, **kwargs)
  File "/Work/test_eval.py", line 15, in test_eval_expressions
    self.assertEqual(eval(expr), exp_value)
AssertionError: 3 != 4

----------------------------------------------------------------------
Ran 4 tests in 0.002s

FAILED (failures=1)
请注意,ddt试图为生成的TC命名

使用pip安装它:

pip install ddt
[*]pythonic
pytest
框架(
pytest.mark.parametrize
)的相同解决方案集成到了核心工具中,仅此功能就值得切换到
pytest

answer的衍生产品,这对我来说不太管用。在我没有处理大量数据的地方,我确实需要用不同的输入运行相同的测试。以下测试使用了我想要自定义的
create_a
create_b
方法

要求使用相同的定制运行两个测试

类测试(unittest.TestCase):
def测试_a_使用_b(自身):
a=创建_a()
b=创建_b()
a、 b=b
自我主张(b.a,a)
def测试_b_使用_a(自身):
a=创建_a()
b=创建_b()
b、 a=a
自我断言(a.b,b)
我自己实例化
TestSuite
TestCase
时,绕过了测试加载程序,导致了一个错误,因为它需要一个名为
runTest
的方法

结果是:

类测试(unittest.TestCase):
定义初始化(自我、创建a、创建b):
super()。\uuuu init\uuuuu()
self.create\u b=创建
self.create\u a=创建
def测试_a_使用_b(自身):
a=自我。创建
b=自创建
a、 b=b
自我主张(b.a,a)
def测试_b_使用_a(自身):
a=自我。创建
b=自创建
b、 a=a
自我断言(a.b,b)
类TestPair1(测试):
定义初始化(自):
super()。uuu init_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
类TestPair2(测试):
定义初始化(自):
super()。uuu init_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

从Python3.4开始,您可以使用
unittest.TestCase.subTest(msg=None,**参数)
上下文管理器()。这将允许您通过只添加一条语句来实现所需

下面是修改为使用
subTest()


我知道你在做什么。这是个好主意。但是当它第一次达到33时,它将停止执行其余的代码。如果你说的是你必须为每个数字重新创建测试夹具,那么你应该按照Bill Gribble的建议,动态构建一个测试套件。这有什么错?它看起来很棒。基本上,只要断言为真,它就会停止执行。这个答案正是OP(和我)所需要的,只需要很少的重写。