-
-
Notifications
You must be signed in to change notification settings - Fork 407
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generalize waiting for asynchronous behaviour in testing #218
Comments
/cc @rwjblue as proposer of the appoach |
@cibernox I'm not a big fan of the example given in "Proposed approach". IMHO those testing hooks should only exist/be called in dev/test mode, but not in production which the example seems to suggest. I'd rather see the existing networking addons provide some sort of hook that can be enabled/implemented by the test helpers or the test adapter in Ember. |
@Turbo87 I agree that they should only be called in testing, not in dev/productio (I'd be ok if they are called in dev, not a big deal). |
This may be relevant: (TL;DR copy Capybara’s approach) |
@jgwhite This is where we head. That is where we are already if we use jQuery, but people (read "me") want to use fetch. |
@jgwhite I know, I already do that (different syntax. Using an independent |
@cibernox thanks for clarifying 👍 |
@cibernox these utility functions can be implemented today in an addon by utilizing |
Also, although it can be a pain to do so for each kind of async, using waiters for things like |
yep, but the idea here is to get "buy in" to using a shared addon
How so? ember-fetch / ember-network would still have to implement their own See liquid-fire's transition-map (which is guarded to only setup when `isTesting) for an example of this... |
@hjdivad Using The problem is that if we don't track pending promises, like fetch requests. What I propose is add conventional utility functions to track async stuff in testing instead of leaving everyone come up with their own approach. The alternative is that That is doable, but I thought that a unified utility could be better. The idea behind having a single utility is that we can put more effort in making smarter (p.e. a babel-tranform that removes that logic in production). If I was the author of |
Also, I think that that network requests is something we always what to wait for, so I'd add that waiter by default. |
By registering the waiter only in tests, and mocking the underlying API only in tests (in cases where you can't hook into before/after events, as with something like
Yes but isn't that better than users needing to remember to call something at every async point? Installing something like actions: {
submit(data) {
let promise = fetch('/somewhere', { method: 'POST', data }).then(() => this.showGreenFlash());
runInDebug(() => trackPromise(promise))
}
} Calling
Yes, I absolutely agree. There seems to be a tradeoff between needing to write many waiters or imposing a burden on the user at async call sites. Do you agree this is the tradeoff? |
@hjdivad I don't indent this to be usually done by users. Indeed,
All this work can be done without touching ember's core since it's not giving the users new capabilities but exposing a conventional way (for library authors mostly) to register something all tests should wait for, and probably some build-pipeline magic to strip all that in production. |
Ah okay, I see. Thanks for clarifying.
Makes sense. My feeling is still that this already kind of exists, between registering a waiter and putting the registration code within test support. |
I'm not sure how things like ember-fetch or liquid-fire could put the registration code in test support. The addons Regardless, it seems that we all are in violent agreement that |
I believe that the majority of the asks in this issue have been addressed, specifically @cibernox - Would you mind reviewing to see if we can close this one? |
I'm closing this due to inactivity. This doesn't mean that the idea presented here is invalid, but that, unfortunately, nobody has taken the effort to spearhead it and bring it to completion. Please feel free to advocate for it if you believe that this is still worth pursuing. Thanks! |
I write this as an issue instead of as a full blown RFC because I might no be needed, but
I'm happy to escalate it if feels that deserves more official discussion.
The problem
This problem arises from my effors to allowing async/await in testing to actually work as
expected in the Grand Testing Unification and also decoupling Ember from jQuery.
ember-native-dom-helpers makes integrations
and acceptance testing almost usable, but there is a very important edge case that doesn't
support, and neither does the
andThen
helper:Waiting for asynchronous behaviour not happenig inside route's hooks.
I thought that
andThen
and thewait()
function from ember-test-helpers waited for allpromises to be resolved, but that is not the case. They wait for:
Ember.run.later
to be fired.Therefore, that means we cannot test at the moment, with any approach, things like:
The reason why people rarely complain about this is because the big mayority of the community
uses
ember-ajax
or Ember.$
, and jQuery requests are tracked using theajaxSend
andajaxComplete
events [see code]This problem is/will be also in glimmer.
What do we need
We need a way to wait for async behaviour (usually network, but not exclusively) in testing. Ideally it should be:
unconventional events, like waiting until a websockets receive a message.
Proposed approach
I propose a couple of low level utility functions, probably living in ember-test-helpers, that behave
similarly to defer/advanceReadiness in initializers. One of those functions increments a
global counter of "things being waited on" and another function decrements it.
The
andThen
andwait()
helpers will wait until the counter of waiters to be zero.Usage example:
This would allow to test this as:
It might worth having a slightly less low level convenience function that handles promises
and it is not tied to any RSVP specific feature ("Use the platform" and all that jazz).
The implementation of that track promise function would just be:
How to make users mostly unaware of this
Wrapping every async on this just for testing purposes is pretty annoying but there isn't
really any generic way of knowing when async stuff have finished. The closest thing is using
some obscure RSVP instrumentation and still that doesn't cover other uses like websockets, browser timers (no
run.later
), posting messages to web workers and awaiting their response.This has always been broken and people didn't complain that much because jquery AJAX
was covered, so to me it shows that just by covering requests we are accounting for almost all
usecases people might have.
If we make PRs to the most popular networking addons in the wild (ember-fetch, ember-network, ember-ajax) most people will never know that this exists.
Open questions.
ember-test-helpers
?runInDebug
good enough? Does itremove dead code and unused imports?
could be removed into:
The text was updated successfully, but these errors were encountered: