在 Python 中进行测试 - 如何在使用单元测试的测试中使用 assertRaises?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3877134/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 13:08:15  来源:igfitidea点击:

Testing in Python - how to use assertRaises in testing using unittest?

pythonunit-testingtestingexception-handling

提问by Tomas Novotny

I am trying to do a simple test in Python using unittest, to see if a class throws an exception if it gets an unsuitable input for the constructor. The class looks like this:

我正在尝试使用 unittest 在 Python 中进行一个简单的测试,以查看一个类是否在构造函数的输入不合适时抛出异常。这个类看起来像这样:

class SummaryFormula:
    def __init__( self, summaryFormula):
        self.atoms = {}
        for atom in re.finditer( "([A-Z][a-z]{0,2})(\d*)", summaryFormula):
            symbol = atom.group(1)
            count = atom.group(2)

            if pocet != "":
                self.atoms[ symbol] = int(count)
            else:
                self.atoms[ symbol] = 1

My test is following:

我的测试如下:

    class ConstructorTestCase(unittest.TestCase):
      def testEmptyString(self):
        self.assertRaises(TypeError, ukol1.SummaryFormula(), "testtest")

    if __name__ == '__main__':
      unittest.main()

All I want is the test to fail, meaning that the exception of unsuitable input for constructor is not handled.

我想要的只是测试失败,这意味着不处理构造函数的不合适输入的异常。

Instead, I get an error: __init__() takes exactly 2 arguments (1 given).

相反,我收到一个错误:__init__() takes exactly 2 arguments (1 given).

What am I missing? What is the second argument I should specify?

我错过了什么?我应该指定的第二个参数是什么?

Also, what type of Error should I use to handle exception that an input not matchable by my regexp was passed to the constructor?

另外,我应该使用什么类型的错误来处理我的正则表达式无法匹配的输入被传递给构造函数的异常?

Thank you, Tomas

谢谢你,托马斯

采纳答案by pyfunc

Thats because your class requires a parameter while instantiating the object

那是因为您的类在实例化对象时需要一个参数

while you are passing

当你经过时

ukol1.SummaryFormula()

you should have been passing the parameter summaryFormula to it.

您应该已经将参数 summaryFormula 传递给它。

ukol1.SummaryFormula(someSummaryFormula)

Also the confusion is because your class name is SummaryFormula and the parameter that you pass to __init__is also SummaryFormula

混淆也是因为您的类名是 SummaryFormula 而您传递给的参数__init__也是 SummaryFormula

or should this be

或者这应该是

self.assertRaises(TypeError, ukol1.SummaryFormula, "testtest")

回答by Ned Batchelder

assertRaisesis a little confusing, because you need to give it the callable, not an expression that makes the call.

assertRaises有点混乱,因为你需要给它 callable,而不是一个进行调用的表达式。

Change your code to:

将您的代码更改为:

self.assertRaises(TypeError, ukol1.SummaryFormula, "testtest")

In your code, you are invoking the constructor yourself, and it raises an exception about not having enough arguments. Instead, you need to give assertRaisesthe callable (ukol1.SummaryFormula), and the arguments to call it with ("testtest"). Then it can call it, catching and checking for exceptions.

在您的代码中,您自己调用构造函数,它引发了一个关于没有足够参数的异常。相反,您需要提供assertRaises可调用对象 (ukol1.SummaryFormula) 和调用它的参数 ("testtest")。然后它可以调用它,捕获和检查异常。

回答by Sarah Messer

A more-generic alternate format is

更通用的替代格式是

args=['testtest']
kwargs = {}
self.assertRaises(TypeError, ukol1.SummaryFormula, *args, **kwargs)

This is useful if your constructor is polymorphic and you want to loop over a list of different ways of miswriting the arguments, e.g.:

如果您的构造函数是多态的,并且您想遍历一系列错误写入参数的不同方式,这将很有用,例如:

arg_lists = [
    ['testtest'],
    ['anothertest'],
    ['YAT'],
]
for args in arg_lists:
    self.assertRaises(TypeError, ukol1.SummaryFormula, *args)

回答by Pratyush

A more pythonic way is to use withcommand (added in Python 2.7):

更pythonic的方法是使用with命令(在Python 2.7中添加):

with self.assertRaises(SomeException):
    do_something()

Documentation: https://docs.python.org/2/library/unittest.html#unittest.TestCase.assertRaises

文档:https: //docs.python.org/2/library/unittest.html#unittest.TestCase.assertRaises

回答by Debosmit Ray

Since none of the other answers point on how you can use the context that encapsulates the code that causes the exception, here's how you can do that.

由于其他答案都没有指出如何使用封装导致异常的代码的上下文,因此您可以这样做。

with self.assertRaises(ValueError) as ctx:
    <some code that throws an exception>

expected_msg = 'foo_bar_baz'
self.assertEquals(ctx.exception.message, expected_msg)

Attributes of interest in this unittest.case._AssertRaisesContext, are:

对此感兴趣的属性unittest.case._AssertRaisesContext是:

  • exception
  • expected
  • expected_regexp
  • failureException
  • 例外
  • 预期的
  • 预期的正则表达式
  • 失败异常