I have always had trouble explaining to developers how they should test their code and why they should care about writing tests. Concrete examples seem to be the best medium for teaching and these examples by John Sundell are fantastic.
When starting to work with tests, there's one problem in particular that almost every developer runs into - how to test asynchronous code. It can be code that makes network requests, that performs work on multiple threads, or schedules delayed operations.
One example I love in particular is where he talks about modifying a method to take in a dispatch queue. The method didn't need this because it wants to do all of the work on a background queue. But if you expose this functionality it immediately improves the testability of the code while not changing the underlying purpose.
A developer should always strive to make their code more testable and never be afraid to modify it to reach this goal.
Regardless of which technique you choose, I really recommend staying away from adding waiting time (like calling sleep) in your tests - that'll just make them slow and can be a huge source of flakiness down the line.
In my opinion a test should take hundreds of milliseconds to run at the maximum. If it takes longer you're probably testing incorrectly and are exposing yourself to flakiness and other issues.