Just wanted to share an update, as we've continued to write more and more tests for code that uses Swift concurrency. Introducing Swift concurrency to a feature continues to be the biggest cause of test flakiness in our experience, but we have managed to reduce flakiness dramatically by cribbing some helpers from swift-async-algorithms, in particular, a "C async support" module, which exposes a global hook override for task enqueuing, which we use to redirect everything to the main, serial executor:
Whenever we have a flakey continuous integration failure, we wrap the test with this helper and don't typically have a concurrency-based problem with that test again. As a bonus, the test runs more quickly.
The solution is far from perfect, but has saved us from a ton of pain, and we think it basically makes async code behave more like Combine code (i.e. well-defined "subscription" order), and hence becomes a lot more reliable to test.
I believe it will probably only work for code that does not use custom executors, but that should be the case for most folks right now. We also haven't tried to include this code in library/application code yet, but if Swift doesn't provide a public solution to the problem, we'll likely look into extracting this helper into its own package, which should make it easier to drop into a project.