I have a python function foo
with a while True
loop inside.
For background: It is expected do stream info from the web, do some writing and run indefinitely. The asserts test if the writing was done correctly.
Clearly I need it to stop sometime, in order to test.
What I did was to run via multirpocessing
and introduce a timeout there, however when I see the test coverage, the function which ran through the multiprocessing, are not marked as covered.
Question 1: Why does pytest now work this way?
Question 2: How can I make this work?
I was thinking it's probably because I technically exit the loop, so maybe pytest does not mark this as tested....
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
...
More info
- I looked into adding a decorator such as
@pytest.mark.timeout(5)
, but that did not work and it stops the whole function, so I never get to theassert
s. (as suggested here). - If I don't find a way, I will just test the parts, but ideally I would like to find a way to test by breaking the loop.
- I know I can re-write my code in order to make it have a timeout, but that would mean changing the code to make it testable, which I don't think is a good design.
- Mocks I have not tried (as suggested here), because I don't believe I can mock what I do, since it writes info from the web. I need to actually see the "original" working.
asyncio
and websockets - what framework are you using,aiohttp
? You don't need to run an endless loop for that. Can you show a bit of code that is more related to your use case? – Ycleptasync for msg in conn: ...
loop instead of an endless loop. The loop stops iterating when the connection is closed, which is pretty easy to test with a custom server mock. – Ycleptwhile True
. What is the benefit of using this vs while True? – Vilereceive
calls and raises to simulate a connection closing. Also anasync for
is simply more pythonic than awhile True
if you ask me. – Yclept