如何使用 assertRaises() 引发错误

How to use assertRaises() to rise an error

我正在学习如何在 Python 中使用 unittest 进行单元测试。 我想做的是在转数为负的情况下引发 ValueError,并显示一条消息,例如 'turn cannot be negative'.

到目前为止我写的代码如下:

import unittest
from canvas import Game


class TestPlayer1(unittest.TestCase):

    def setUp(self):

        # Game objects
        self.game_turn_0 = Game()
        self.game_turn_5 = Game()
        self.game_turn_negative = Game()

        # values
        self.game_turn_0.turn = 0
        self.game_turn_5.turn = 5
        self.game_turn_negative = -2

    def test_get_turn(self):
        self.assertEqual(self.game_turn_0.get_turn(), 0)
        self.assertEqual(self.game_turn_5.get_turn(), 5)
        with self.assertRaises(ValueError):
            print('value error!')


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

但是结果并不如你所见,如你所见:

Testing started at 09:55 ...
C:\Users\oricc\PycharmProjects\practisingDrowing\venv\Scripts\python.exe "C:\Program Files\JetBrains\PyCharm Community Edition 2019.2.3\helpers\pycharm\_jb_unittest_runner.py" --target test_canvas.TestPlayer1.test_get_turn
Launching unittests with arguments python -m unittest test_canvas.TestPlayer1.test_get_turn in C:\Users\oricc\PycharmProjects\practisingDrowing

pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
value error!

Failure
Traceback (most recent call last):
  File "C:\Users\oricc\AppData\Local\Programs\Python\Python37-32\lib\unittest\case.py", line 59, in testPartExecutor
    yield
  File "C:\Users\oricc\AppData\Local\Programs\Python\Python37-32\lib\unittest\case.py", line 628, in run
    testMethod()
  File "C:\Users\oricc\PycharmProjects\practisingDrowing\test_canvas.py", line 23, in test_get_turn
    print('value error!')
  File "C:\Users\oricc\AppData\Local\Programs\Python\Python37-32\lib\unittest\case.py", line 203, in __exit__
    self._raiseFailure("{} not raised".format(exc_name))
  File "C:\Users\oricc\AppData\Local\Programs\Python\Python37-32\lib\unittest\case.py", line 135, in _raiseFailure
    raise self.test_case.failureException(msg)
AssertionError: ValueError not raised


Assertion failed

Assertion failed


Ran 1 test in 0.034s

FAILED (failures=1)

Process finished with exit code 1

Assertion failed

Assertion failed

Assertion failed

Assertion failed

我现在已经看了一些视频,阅读了 python website 上的文档,并阅读了一些帖子。我刚好能掌握。

我的意思是,我不知道如何在我的案例中使用它。

任何人都可以向我解释一下这是如何工作的吗? 谢谢

class TestPlayer1(unittest.TestCase):

    def setUp(self):

        # Game objects
        self.game_turn_0 = Game()
        self.game_turn_5 = Game()
        self.game_turn_negative = Game()

        # values
        self.game_turn_0.turn = 0
        self.game_turn_5.turn = 5
        self.game_turn_negative = -2

    def test_get_turn(self):
        self.assertEqual(self.game_turn_0.get_turn(), 0)
        self.assertEqual(self.game_turn_5.get_turn(), 5)
        with self.assertRaises(ValueError):
            print('value error!')


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

您在预期会引发错误的操作周围使用 assertRaises 上下文管理器。如果您查看您的测试代码,您能看到应该引发错误的行吗?我不能。

你很接近 - 你有一般的结构。但你需要的是

def test_get_turn(self):
    self.assertEqual(self.game_turn_0.get_turn(), 0)
    self.assertEqual(self.game_turn_5.get_turn(), 5)
    with self.assertRaises(ValueError):
        self.game_turn_negative.get_turn()

我只改了最后一行。看看您期望引发异常的操作是怎样的?

此外,您在 setUp 中有一个错误 - 您需要设置 self.game_turn_negative.turn = -2,而不是 self.game_turn_negative = -2。一定要解决这个问题。

现在要检查测试是否有效,请尝试 运行 测试并查看它是否通过,然后更改您的代码,使负转向值 不会 引发异常,然后 运行 再次测试。您应该会看到测试套件失败,并抱怨 ValueError 没有在预期的时候出现。

with assertRaises 是围绕 with 块中引发异常的预期而设计的。在这种情况下,with 块中唯一的代码 运行 是 print('value error!') - 它永远不会引发 ValueError。这会导致断言失败,因为未引发 ValueError

要解决您的问题,您需要调整您的应用程序,以便在检测到无效条件时引发 ValueError。然后,您将能够在 assertRaises 块内捕获 ValueError。值得注意的是,您对 self.game_turn_negative 的分配似乎有问题。对于 game_turn_0game_turn_5 值,您将整数值分配给 .turn 属性,而不是顶级变量。对于 game_turn_negative,您将其设置为 Game(),然后再将其设置为 -2(而不是设置 self.game_turn_negative.turn)。

要修复您的代码,这可能有效:

import unittest
from canvas import Game


class TestPlayer1(unittest.TestCase):

    def setUp(self):

        # Game objects
        self.game_turn_0 = Game()
        self.game_turn_5 = Game()
        self.game_turn_negative = Game()

        # values
        self.game_turn_0.turn = 0
        self.game_turn_5.turn = 5
        self.game_turn_negative.turn = -2

    def test_get_turn(self):
        self.assertEqual(self.game_turn_0.get_turn(), 0)
        self.assertEqual(self.game_turn_5.get_turn(), 5)
        with self.assertRaises(ValueError):
            self.game_turn_negative.get_turn()


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