assertRaises in循环:每次迭代1次测试

时间:2015-02-09 04:35:55

标签: python unit-testing testing nose

我正在尝试在循环中使用assertRaises,因此我可以测试多个错误分隔符([',', ':', '-']),而无需为每个案例编写新的测试。我在循环中使用assertRaises时遇到问题。我做了一个unittest.TestCase的最小工作示例,它在循环中调用assertRaises

import sys
import unittest

def throw_error():
   sys.stderr.write('In throw error!')
   raise TypeError

class Test(unittest.TestCase):

   def test_loop(self):
      for i in range(5):
         self.assertRaises(TypeError, throw_error)

这是有效的,但它只算作1次测试,当我更喜欢它被理解为5次测试时。有没有规范的方法来获得这种行为?

>>> nosetests ../footest.py
In throw error!
In throw error!
In throw error!
In throw error!
In throw error!
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

我想要这种行为的主要原因是因为这看起来像是一个黑盒子太多了,我最终会忘记这是1中的5个测试。也许写入stderr因为我已经完成了自定义消息是否足够好,或者你有更好的建议吗?

Falsetru的答案很有效,但我不能适应我的情况

Falsetru的答案作为一个独立的例子,但我的test_loop()函数需要是TestCase的实例方法,因为它需要使用许多属性和方法。因此,当我调整他的答案仍然使用TestCase时,它不再有效:

import sys
import unittest
import nose.tools as ntools

def throw_error():
   sys.stderr.write('In throw error!')
   raise TypeError

class Test(unittest.TestCase):

   def test_loop(self):
      for i in range(5):
         yield ntools.assert_raises, TypeError, throw_error

这导致输出:

.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

永远不会调用throw_error()的含义。

2 个答案:

答案 0 :(得分:4)

您正在使用支持tests generator的鼻子:

from nose.tools import assert_raises                                            

def throw_error():
   raise TypeError

def test_loop():
    for i in range(5):
        yield assert_raises, TypeError, throw_error

答案 1 :(得分:2)

这是您使用unittest.TestCase

的方式
import sys
import unittest
from nose.tools import istest

def throw_error():
   sys.stderr.write('In throw error!')
   raise TypeError

class Test(unittest.TestCase):
    pass

def _create():
    """ Helper method to make functions on the fly """

    @istest
    def func_name(self):
        self.assertRaises(TypeError, throw_error)

    return func_name

def populate(cls, tests):
    """ Helper method that injects tests to the TestCase class """

    for index, problem in enumerate(tests):
        test_method_name = '_'.join(['test', str(index)])
        _method = _create()
        _method.__name__ = test_method_name
        _method.__doc__ = test_method_name
        setattr(cls, _method.__name__, _method)

tests = range(5)

populate(Test, tests)

这是输出:

$ nosetests  -v
test_0 ... In throw error!ok
test_1 ... In throw error!ok
test_2 ... In throw error!ok
test_3 ... In throw error!ok
test_4 ... In throw error!ok

----------------------------------------------------------------------
Ran 5 tests in 0.031s

OK