【发布时间】: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
...
更多信息
【问题讨论】:
-
“这意味着更改代码以使其可测试,我认为这不是一个好的设计” - 我不这么认为。考虑到可测试性编写代码是最好的方法,但事后重构以使其可测试也是一件好事,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