首页 > 解决方案 > Python 3.x UnitTest 模块禁用 SystemExit 堆栈跟踪输出

问题描述

我正在学习如何使用 unittest 模块编写单元测试,并且已经深入使用元编程(我相信它也被称为猴子补丁),但是在失败的断言测试期间有一个堆栈跟踪正在打印出来。

<output cut for brevity>
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/case.py", line 203, in __exit__
    self._raiseFailure("{} not raised".format(exc_name))
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/case.py", line 135, in _raiseFailure
    raise self.test_case.failureException(msg)
AssertionError: SystemExit not raised

似乎我应该得到这个错误,因为测试应该失败,但我希望它更美观一些,并排除整个堆栈跟踪以及断言错误。

下面是使用上下文管理器检查 SystemExit 的代码:

with self.assertRaises(SystemExit) as cm:
    o_hue_user.getHueLoginAuthentication()
self.assertNotEqual(cm.exception.code, 0)

getHueLoginAuthentication方法exit(1)在意识到用户名或密码不正确时会执行,但我需要消除打印出的堆栈跟踪。

顺便说一句,我已经搜索了这个网站和其他网站,但找不到似乎有简单或完整解决方案的答案。

谢谢!


由于我是这个论坛的新手,我不确定这是否是回应答案的正确方法......

我可以尝试输入代码的关键区域,但我不能透露太多代码,因为我在一家金融机构工作,而且他们对共享内部工作有严格的规定。

要回答您的问题,这是执行 exit() 的代码:

authentication_fail_check = bool(re.search('Invalid username or password', r.text))
if (r.status_code != 200 or authentication_fail_check) :
    self.o_logging_utility.logger.error("Hue Login failed...")
    exit(1)

我使用 PyCharm 进行调试。这段代码的关键是返回一个不成功的执行,这样如果发生这个错误我可以停止执行。我认为没有必要在这里使用 try 块,但我认为这并不重要。你的专业意见是什么?当满足断言条件时,我得到一个通过并且没有跟踪堆栈。所有这一切似乎都在告诉我,断言没有得到满足。我的断言测试正在工作。我要做的就是摆脱跟踪堆栈,只打印最后一行:“AssertionError: SystemExit not raise” 如何摆脱堆栈跟踪并将输出的最后一行作为反馈?

谢谢!


我的意思是说谢谢你的热烈欢迎以及唐。

顺便说一句,我可以发布测试代码,因为它不是主代码库的一部分。这是我的第一个元编程(猴子补丁)单元测试,实际上是我的第二个单元测试。我仍然在努力解决构建一些代码的麻烦,这些代码会告诉我我得到了一个我知道无论如何我都会得到的特定结果。例如,在返回 false 布尔值的函数示例中,如果我编写的代码说使用这些参数执行此代码,并且我知道这些值将返回 false,那么为什么构建代码告诉我它将返回 false ? 我正在为如何设计不会告诉我明显显而易见的好测试而苦苦挣扎。

到目前为止,我所做的只是使用单元测试来告诉我,当我实例化一个对象并执行一个函数时,它是否告诉我登录是否成功。我可以更改输入以使其失败。但我已经知道它会失败。如果我正确理解单元测试,当我测试登录是否成功时,它更像是集成测试而不是单元测试。但是,问题是,我正在测试的这个特定类从配置文件中获取其参数并为特定连接设置实例变量。在测试代​​码中,我有 2 组测试代表一个好的登录和一个坏的登录。我知道单元测试更加自主,因为可以使用参数调用函数并独立测试。但是,这不是此代码的工作方式。所以我'

这是特定类的测试代码:

import unittest
from HueUser import *

test_data = \
    {
        "bad_login": {"hue_protocol": "https",
                      "hue_server": "my.server.com",
                      "hue_service_port": "1111",
                      "hue_auth_url": "/accounts/login/?next=/",
                      "hue_user": "baduser",
                      "hue_pw": "badpassword"},
        "good_login": {"hue_protocol": "https",
                       "hue_server": "my.server.com",
                       "hue_service_port": "1111",
                       "hue_auth_url": "/accounts/login/?next=/",
                       "hue_user": "mouser",
                       "hue_pw": "good password"}
    }

def hue_test_template(*args):
    def foo(self):
        self.assert_hue_test(*args)
    return foo

class TestHueUserAuthentication(unittest.TestCase):
    def assert_hue_test(self,o_hue_user):
        with self.assertRaises(SystemExit) as cm:
            o_hue_user.getHueLoginAuthentication()
        self.assertNotEqual(cm.exception.code, 0)

for behaviour, test_cases in test_data.items():
    o_hue_user = HueUser()
    for name in test_cases:
        setattr(o_hue_user, name, test_cases[name])
    test_name = "test_getHueLoginAuthentication_{0}".format(behaviour)
    test_case = hue_test_template(o_hue_user)
    setattr(TestHueUserAuthentication,test_name, test_case)

让我知道如何回复答案,或者我是否应该编辑我的帖子???

谢谢!

标签: pythonunit-testingstacktrace

解决方案


欢迎来到 Stack Overflow,罗伯特。如果您包含一个完整的示例,这将非常有帮助,以便其他人可以帮助您找到问题。

根据您提供的信息,我猜这getHueLoginAuthentication()实际上并没有引发您认为的错误。尝试使用调试器来跟踪它在做什么,或者在它调用exit().

这是一个完整的示例,展示了如何assertRaises()工作:

from unittest import TestCase


def foo():
    exit(1)


def bar():
    pass


class FooTest(TestCase):
    def test_foo(self):
        with self.assertRaises(SystemExit):
            foo()

    def test_bar(self):
        with self.assertRaises(SystemExit):
            bar()

这是我运行它时发生的情况:

$ python3.6 -m unittest scratch.py
F.
======================================================================
FAIL: test_bar (scratch.FooTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "scratch.py", line 19, in test_bar
    bar()
AssertionError: SystemExit not raised

----------------------------------------------------------------------
Ran 2 tests in 0.001s

FAILED (failures=1)

推荐阅读