Thanks for spending the time to go deep on this and report back! In addition to @mbrandonw's point about losing some testability, I'd like to share some thoughts on a few of your points:
The issue I'm trying to demonstrate here is subtle, but I don't think it has anything to do with AsyncSequence
specifically and really does affect all async
-await
code more broadly.
I agree that a simple async function with no dependencies can be easy to test. But I also think a simple async sequence should be easy to test. After all, testing code that interacts with a plain ole Swift Sequence
isn't much harder than testing code that interacts with another kind of value.
What I'm trying to point out is that as async
-await
code interacts with other code it quickly becomes impossible to reliably test due to our inability to control (or reason about) how work will be scheduled.
While it's true that the demo app I posted uses an AsyncSequence
, the problem it demonstrates really has nothing to do with that construct, and really does apply to async
-await
code more generally. In fact, the task
endpoint could be refactored to suspend for a single unit of work (with no AsyncSequence
in sight) and the problem would still exist.
Unless I'm mistaken, NotificationCenter
is predictable and totally controllable when you use its non-async
-await
interfaces (the Combine- and subscription-equivalent code demonstrates this), and so the only real issue here is the use of async
-await
, not NotificationCenter
.
Unfortunately a lot of the discussion here has gotten lost in the weeds about the specifics of Notification Center when I want to focus on the general problem of testing async
-await
, so maybe I ought to change the example or come up with another one.
While testing the full view lifecycle is an admirable goal, I again think this is straying the topic from its focus on the testability of async
-await
. (Though I do think that testing a view model directly is a reasonable lightweight alternative to full UI testing or UIWindow
-hosting.)
I mentioned it above, but also to reiterate, the problem does not really have anything to do with AsyncSequence
. While a single async
function with no dependencies is relatively easy to test, a system built in async
-await
with many moving parts (that may or may not include async sequences) is what becomes completely untestable very quickly.
Doesn't it seem like Apple's Async Algorithms project intends to succeed Combine? If so, wouldn't it also be case that folks should always reach for the appropriate AsyncSequence
over a Combine publisher alternative?
I do want to say thanks again for taking the considerable time to explore, but hope my points make sense and also help emphasize the thorniness of the problem!