当前位置: 首页 > 知识库问答 >
问题:

PyTest测试套件在Python中测试另一个线程的结果时,当断言应该失败时传递?

屠锦
2023-03-14

我目前正在使用pytest测试一个现有的(根据文档中的unittest测试套件)。我目前正在编写一个线程,等待分配一个IP地址,然后将其返回给回调函数,并编写单元测试来伴随它。

这是我编写的测试用例类。

class TestGetIpAddressOnNewThread(unittest.TestCase):

    def test_get_existing_ip(self):
        def func(ip):
            assert ip == "192.168.0.1" # Not the real IP
            # Even when I introduce an assert statement that should fail, test still passes
            assert ip == "shouldn't be the ip" 

        ip_check = GetInstanceIpThread(instance, func)
        ip_check.start()
        ip_check.join()

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

下面是GetInstanceIpThread伪定义:

class GetInstanceIpThread(threading.Thread):
    def __init__(self, instance, callback):
        threading.Thread.__init__(self)
        self.event = threading.Event()
        self.instance = instance
        self.callback = callback

    def run(self):
        self.instance.wait_until_running()

        ip = self.instance.ip_address
        self.callback(ip)

当我运行这个测试用例使用pytestpath_to_file.py::TestGetIpaddressOnNewThread,它通过(耶!)但是即使我引入了应该100%失败的断言语句(嘘!)。出了什么问题,我如何编写实际失败的测试?

共有2个答案

储俊英
2023-03-14

我遇到了同样的问题,但是没有访问创建线程的代码。我为该用例发布了一个小的测试助手包pytest reraise:

pip安装pytest重新发布

Pytest风格的测试用例:

def test_get_existing_ip(reraise):
    def func(ip):
        with reraise:
            assert ip == "192.168.0.1" # Not the real IP
            assert ip == "shouldn't be the ip" 

    ip_check = GetInstanceIpThread(instance, func)
    ip_check.start()
    ip_check.join()

Unittest样式测试用例:

from pytest-reraise import Reraise

class TestGetIpAddressOnNewThread(unittest.TestCase):

    def test_get_existing_ip(self):
        reraise = Reraise()

        def func(ip):
            with reraise:
                assert ip == "192.168.0.1" # Not the real IP
                assert ip == "shouldn't be the ip" 

        ip_check = GetInstanceIpThread(instance, func)
        ip_check.start()
        ip_check.join()

        # Re-raise the first exception that the `reraise` context manager captured:
        reraise()

两个测试用例都按预期失败,并报告AssertionError

柴高岑
2023-03-14

所以我要回答我自己的问题,因为虽然我能够在StackOverflow上找到答案,但它不在任何有用的关键字下,因为大多数答案都是关于如何使用pytest xdist进行多线程测试,而不是测试多线程。我最终使用了pytest-s路径到文件。py::TestGetIpAddressOnNewThread在调试过程中,这里提到了一个由打字错误引起的异常,该异常正在打印中,但并没有导致测试失败。

这让我想到了这个问题,我本来就不考虑这个问题,因为我没有意识到资产只是提高了资产错误。

因此,我调整了社区wiki答案如下,以使断言正确工作!

class GetInstanceIpThread(threading.Thread):
    def __init__(self, instance, callback=None):
        threading.Thread.__init__(self)
        self.event = threading.Event()
        self.instance = instance
        self.callback = callback

    def _run(self):
        # The original run code goes here
        self.instance.wait_until_running()

        ip = self.instance.ip_address
        self.callback(ip)

    def run(self):
        self.exc = None
        try:
            self._run()
        except BaseException as e:
            self.exc = e

    def join(self):
        super(GetInstanceIpThread, self).join()
        if self.exc:
            raise self.exc

请注意,只要另一个线程有任何异常,您的测试就会失败。这可能不是您想要的,所以如果您只想在断言失败或类似情况下失败,您可以将BaseExc0019更改为AssertError(或任何您想要失败的内容)。

重写join()是必要的,因为您必须在pytest的主线程上引发异常,以便它正确地使测试失败。

 类似资料:
  • 问题内容: 我有一个Jenkins作业,它通过Nightwatch.js框架在Browserstack上运行Selenium测试。我们有一套完整的测试程序,可以让守夜人在不同的进程中运行,并且我们需要一种在所有测试运行后将通过/失败值返回给Jenkins的方法。 我一直在尝试使用Nightwatch挂钩在每个模块的末尾运行一段代码,但是我无法弄清楚需要采取什么措施才能使Jenkins作业可以访问该

  • 我有一个maven项目,它有一个名为“BlahITCase”的集成测试。该测试目前失败,进而导致“mvn安装”失败。这是预期的行为吗?我的理解是,单元测试(surefire)失败会导致构建失败,但集成测试(使用故障保护)失败不会。 我在我的pom的构建插件部分有以下内容: 注释出验证目标似乎给了我想要的行为。

  • 问题内容: 编辑:切换到一个更好的示例,并阐明了为什么这是一个真正的问题。 我想用Python编写在断言失败时继续执行的单元测试,这样我就可以在一个测试中看到多个失败。例如: 在这里,测试的目的是确保Car’s正确设置其字段。我可以将其分解为四个方法(这通常是个好主意),但是在这种情况下,我认为将其保留为测试单个概念的单个方法(“对象已正确初始化”)更容易理解。 如果我们认为最好不要破坏该方法,那

  • 当我尝试执行一个新的单元测试用例时,它会显示以下错误。 注意:我没有特权设置路径,因为我已经将chrome web驱动程序放在D驱动器中。 测试在14:56开始。。。C:\Users\xxx.xxxx\PyCharm项目\Automation\venv\Scripts\python.exe“C:\Users\xx.xxx\AppData\Local\JetBrains\PyCharm社区版2019

  • 我使用assertJ,在我的测试用例中有多个assertThat断言。当第一个断言失败时,测试就完成了,但我不希望这样。我想知道测试用例单次执行后所有失败断言的信息。有什么办法可以做到吗?我在这里找到了SoftAssertions的解决方案->http://joel-costigliola.github.io/assertj/assertj-core-features-highlight.html