【问题标题】:Is it possible to test a while True loop with pytest (I try with a timeout)?是否可以使用 pytest 测试 while True 循环(我尝试超时)?
【发布时间】:2020-07-22 03:30:22
【问题描述】:

我有一个 Python 函数 foo,里面有一个 while True 循环。 对于背景:预计会从网络上传输信息,进行一些写作并无限期地运行。断言测试写入是否正确。

显然我需要它在某个时候停下来进行测试。

我所做的是通过multirpocessing 运行并在那里引入超时,但是当我看到测试覆盖率时,通过多处理运行的函数没有标记为已覆盖。

问题 1:为什么 pytest 现在会这样工作?

问题 2:我怎样才能完成这项工作?

我在想这可能是因为我在技术上退出了循环,所以也许 pytest 没有将其标记为已测试......

import time
import multiprocessing

def test_a_while_loop():
    # Start through multiprocessing in order to have a timeout.
    p = multiprocessing.Process(
        target=foo
        name="Foo",
    )
    try:
        p.start()
        # my timeout
        time.sleep(10)
        p.terminate()
    finally:
        # Cleanup.
        p.join()

    # Asserts below
    ...

更多信息

  1. 我考虑添加一个装饰器,例如@pytest.mark.timeout(5),但没有奏效,它停止了整个功能,所以我从来没有找到asserts。 (建议here)。
  2. 如果我没有找到方法,我将只测试部分,但理想情况下我想找到一种方法来打破循环进行测试。
  3. 我知道我可以重写我的代码以使其具有超时功能,但这意味着更改代码以使其可测试,我认为这不是一个好的设计。
    1. 我没有尝试过模拟(建议here),因为我不相信我可以模拟我所做的事情,因为它从网络上写入信息。我需要真正看到“原始”工作。

【问题讨论】:

  • “这意味着更改代码以使其可测试,我认为这不是一个好的设计” - 我不这么认为。考虑到可测试性编写代码是最好的方法,但事后重构以使其可测试也是一件好事,IMO - 主要还意味着使代码更加模块化。
  • asyncio 和 websockets - 你使用什么框架,aiohttp?您不需要为此运行无限循环。你能展示一些与你的用例更相关的代码吗?
  • @hoefling 代码看起来与这个非常相似:speakerdeck.com/pydataamsterdam/… 如果这有帮助,请告诉我。
  • 使用async for msg in conn: ... 循环而不是无限循环。当连接关闭时循环停止迭代,这很容易使用自定义服务器模拟进行测试。
  • 因为它更容易测试?用异步迭代器替换 websockets 连接比编写一个自定义对象更容易,该对象可以记住 receive 调用并引发以模拟连接关闭。如果你问我,async for 也比 while True 更 Pythonic。

标签: python unit-testing pytest infinite-loop


【解决方案1】:

将您要测试的功能分解为辅助方法。测试辅助方法。

def scrape_web_info(url):
  data = get_it(url)
  return data

# In production:

while True:
  scrape_web_info(...)

# During test:

def test_web_info():
  assert scrape_web_info(...) == ...

【讨论】:

  • 嗯...我的有点复杂,因为简而言之:连接到 websocket,然后获取数据。这是通过async/await 异步完成的。我会看看它是否可以像那样被打破...... :) 感谢您的输入
【解决方案2】:

是的,这是可能的,上面的代码显示了一种方法(通过超时运行多处理)。

由于断言运行良好,我发现问题不是pytest,而是覆盖报告没有正确考虑multiprocessing

我描述了我如何解决这个(现在是单独的)问题问题here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-15
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    • 2023-04-04
    • 2021-10-13
    相关资源
    最近更新 更多