【问题标题】:assertRaises in loop: 1 test per iteration循环中的 assertRaises:每次迭代 1 次测试
【发布时间】:2015-02-09 04:35:54
【问题描述】:

我正在尝试在循环中使用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() 永远不会被调用。

【问题讨论】:

标签: python unit-testing testing nose


【解决方案1】:

你正在使用支持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

【讨论】:

  • 谢谢。我正在尝试这个,但无法正确使用语法。没想到我可以把所有这些都放在产量和中提琴之后
  • 当我将 test_loop() 设为 TestCase 的实例方法时,这将失败。只是不返回任何功能。我已经更新了我的问题以反映这一点。有什么建议吗?
  • @AdamHughes,测试生成器不支持基于unittest.TestCase 的类。但是您仍然可以使用非基于unittest.TestCase 的类。试试这个:pastebin.com/YvjpZhXP
【解决方案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

【讨论】:

    猜你喜欢
    • 2014-07-06
    • 2017-04-28
    • 1970-01-01
    • 1970-01-01
    • 2020-01-05
    • 1970-01-01
    • 1970-01-01
    • 2018-02-13
    • 1970-01-01
    相关资源
    最近更新 更多