[TIP] Testing asyncio services

André Caron andre.l.caron at gmail.com
Mon Dec 7 19:59:41 PST 2015


Hi all,

I'm not sure if I'm addressing this to the right mailing list, but I think
a lot of you are into testing and Python so I'll try my luck anyways.

So I'm trying out a pet project to learn asyncio and I' having trouble
writing test cases for this project and I'm looking for some help getting
started :-)

The pet project is a clone of Foreman/Honcho written with asyncio.  One of
the building blocks I'm having problems with is this "run_once()" coroutine
which basically starts a subprocess, streams output (with timestamp and
process label prefix) to stdout and kills the process on request to cancel.

At its core, I have the following loop:

pending = {...}
while True:
  done, pending = yield from asyncio.wait(
    pending,
    return_when=asyncio.FIRST_COMPLETED,
  )
  for future in done:
    if future is x:
      # ...
    if future is y:
      # ...


(This loop's structure is heavily inspired by my experience with ZMQ.  If
you know of a better way to write this, please let me know.)

I want to test all possible code paths in the "for future in done" loop and
I'm trying to achieve that by sending a specific input, then waiting for
the input to be processed.  Then, I can have each test will run a different
path.

The path that shows that I'm correctly streaming output to stdout with
annotations is proving pretty hard to test since the "run_once()" coroutine
does not complete until the child process exits.

The problem I'm having is that I cannot figure out how to have the test and
this coroutine alternate executions.  Existing solutions for testing
asyncio code seems to work mostly with networked services where the test
can simply connect a socket and act like a client (the test can trivially
"resp = loop.run_until_complete(client.sendall(req))").

So far, I've been trying to emulate this by replacing sys.stdout with the
write end of a socketpair() and the read end in my test to follow this
pattern, but I'm having trouble.

Any suggestions?

The answer is posted up on StackOverflow[1] if you want to answer there
instead of replying to this email.

[1]: http://stackoverflow.com/q/34126076/313063

Thanks in advance,

André
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.idyll.org/pipermail/testing-in-python/attachments/20151207/96b1347a/attachment.htm>


More information about the testing-in-python mailing list