QT函数抑制python中的测试失败

Posted

技术标签:

【中文标题】QT函数抑制python中的测试失败【英文标题】:QT function suppressing test failures in python 【发布时间】:2022-01-02 14:59:21 【问题描述】:

处理正在测试 python UI 的复杂单元测试,并且 QT 函数似乎正在抑制测试失败。我相信我已经能够创建一个重复该行为的最小文件:

import pytest
from unittest import TestCase
from PySide2.QtCore import QTimer

def meaningless():
    return 'fire'


class TestClass(TestCase):

    def test_1(self):
        def inner_test_1():
            self.assertEqual(meaningless(),'x')
        
        inner_test_1()

    def test_2(self):
        def inner_test_2():
            self.assertEqual(meaningless(),'x')

        QTimer.singleShot(1, inner_test_2)


if __name__ == '__main__':
    import sys

    sys.exit(pytest.main([__file__]))

第一个测试失败了,但第二个测试错误地通过了。在我更复杂的真实世界单元测试中,“inner_test_2”的等效项确实会触发,并且可以在测试日志中看到由此产生的断言错误,但测试不会注册为失败。从我在 QT 文档中可以看出,这可能与多线程有关?如何让失败失败?

【问题讨论】:

您的示例没有运行事件循环,因此行为正确且符合预期。您可能应该使用 pytest-qt 之类的东西。 对不起,如果我在这里分裂头发,但在这种情况下,“预期行为”=“因为使用错误而无法正常工作”或“这是 QTimer 的合法使用,但它不会生产你想要的东西。” ? 好吧,你写了测试用例,所以只有你才能真正回答这个问题。你在测试成功还是失败?如果没有正在运行的事件循环,您究竟希望single-shot timer 做什么?测试用例部分(或有时甚至主要)旨在记录程序员对 API 的理解,而不仅仅是 API 本身。 由于您给出的示例不能代表您的真实代码(您的真实代码执行inner_test_2,而示例没有)我只能猜测它可能与多线程有关?如果assertEqual(meaningless(),'x') 在不同的线程中运行,则可能会出现问题。 【参考方案1】:

这可能与多线程有关?

是的,没错。失败的测试是通过异常检测的,而不同线程中的异常不会被 unittest 框架捕获,因为它无法将线程与测试相关联。

minimal, reproducible example 将是:

import pytest
from unittest import TestCase
import threading

class TestClass(TestCase):
    def test_2(self):
        def inner_test_2():
            self.assertTrue(False)
        myTestThread = threading.Thread(target=inner_test_2)
        myTestThread.start()
        myTestThread.join()

if __name__ == '__main__':
    import sys

    sys.exit(pytest.main([__file__]))

请注意,虽然assertTrue(False) 引发异常,但我们没有看到失败的测试。但我们确实看到(除了异常的堆栈跟踪)是来自pytest 的警告:

    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

-- Docs: https://docs.pytest.org/en/stable/warnings.html

我如何让失败失败?

您需要从线程中捕获异常并在主线程中引发它们,以便 unittest 框架可以拾取它们并了解哪些测试失败了。如何做到这一点是另一个话题,请参阅Make Python unittest fail on exception from any thread。

【讨论】:

以上是关于QT函数抑制python中的测试失败的主要内容,如果未能解决你的问题,请参考以下文章

Qt中的单元测试非返回函数[关闭]

关于winsock2中的connect函数

python中的Elasticsearch parallel_bulk辅助函数在使用响应时会因部分失败而引发错误

抑制 libsvm (python) 中的输出

Python/scipy 中的一维非最大抑制

如何使变量在 Python(和 Qt)中的函数之外可用