A hard coded sleep statement is generally supposed to represent some sort of mocked delay in the application that doesn't exist during testing.
The harmful aspect of this is that a hard coded value can't represent the complexity that actually exists in what its mocking.
Take for example a network delay. Your production system usually takes 4 seconds to go out over the network, take some data, and come back over the network with the result. So you simply mock up the data, toss in a 4 second delay, and give it back. Sounds simple.
Because it is simple - almost too simple. If something on your network changes, your test is now inaccurate. You can't see how the routine will react under abnormally heavy or abnormally light network load. In other words you're trying to test what you cannot control. You're make something repeatable (with the 4 second sleep) that really isn't repeatable (no run over the network will ever be the same twice).
And if the correctness of the test relies on an invalid and potentially often changing assumption, then what does that say about the reliability of the test?