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
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
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
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-
await interfaces (the Combine- and subscription-equivalent code demonstrates this), and so the only real issue here is the use of
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
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
await. (Though I do think that testing a view model directly is a reasonable lightweight alternative to full UI testing or
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
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!