Monday, July 30, 2018

Re: [Channels] How to write tests with database access?

The question is whether testing asynchronous operations and <any other stateful information> is compatible.

In my understanding, Andrew's hint points you in the only good direction.  You've got to turn the async initiate/complete cycle back into a synchronous flow.

You can poll from another thread, or use a message queue, or any of a number of approaches.  But there is no way around the need to wait until completion before your test the state after completion.

On Saturday, July 28, 2018 at 10:49:39 AM UTC-4, Neraste wrote:
Thanks for the hint, Andrew. I think it is a neat approach. But I start to wonder if asynchronous tests + database manipulation are naturally and painlessly compatible.

Le dimanche 22 juillet 2018 18:44:52 UTC+2, Andrew Godwin a écrit :
Asynchronous testing is very hard, unfortunately. I suspect what you are doing is awaiting the sending of the message, but not awaiting any response back, so your test continues once it's sent the message into the application but not waiting for that application to finish processing.

The best pattern for this is probably to send something back when you've finished processing and await receiving that, then you should guarantee that the work has been finished before your test continues.

Andrew

On Thu, Jul 19, 2018 at 8:18 AM Neraste <neraste...@gmail.com> wrote:

Hello Django users,

This sounds like a pretty newbish question, but I am struggling on how to write tests for Django-channels 2 websocket consumers that access the database. I am not familiar with pytest and asynchronous programming (the bread and butter of Channels testing), so while I caught up with pytest, I am still a bit lost between `async` and `await`.

Using Django/Django-REST, when I test a view method which modifies a database object for a given request, here is what I usually do:

  1. Assert the initial state of the object ;
  2. Use the test client to send the request ;
  3. Assert the outcome of the request ;
  4. Assert the final state of the object, which should be different.

All of this synchronously. With Channels, I thought I could do the same for a consumer method which modifies a database object on a given event:

  1. Assert the initial state of the object ;
  2. Use the test communicator to send the event ;
  3. Assert the final state of the object, which should have changed.

All of this asynchronously, as stated in the documentation, but this is a synchronous test scenario! Obviously, it does not work, as step 2. is executed with `await` and step 3. is achieved before step 2. finishes. I tried to execute step 2. synchronously using `async_to_sync` but it does not work (I can give details).

I am missing something, how can I test such a consumer method? Is this possible? The documentation does not give any hint on this…

Help would be much appreciated!

Cheers,

--   Neraste

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/c22c1afb-ff85-5af9-66f6-a94cdc77a545%40gmail.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/e2824e79-cb0b-4d70-9867-884104e0508f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment