WaitForEndOfFrame is a very nasty utility when creating Unity Tests.
If you have a simple test like the following:
[UnityTest]
IEnumerator WaitAFrame()
{
yield return new WaitForEndOfFrame();
Assert.IsTrue(true);
}
This will work on the editor so you’ll push it to your codebase, and if you have a CI service, like Unity Cloud Build, or you own solution (Travis/TeamCity/etc) which run your tests in batch mode, you’ll discover that this tests won’t succeed. In fact, it will fail with a timeout.
The reason for this is that WaitForEndOfFrame isn’t supported in batch mode, and, instead, you should use yield return null.
Now, the nasty thing here is that Unity doesn’t provide much information for this, only the previously linked documentation page and a note in the WaitForEndOfFrame doc page. And, when running this in batch mode, you won’t get any log, it will simply yield until it times out, making it a silent error.
Because we ran our tests in the editor, we won’t find this error, and then, when the CI service fails, we’ll have the infamous case of “it works on my machine”. I have spent years having tests fail with no idea why, always timing out, looking at the logic and finding no problems with it, and no clue in the logs, until one day I discovered by accident that it only timeout on the WaitForEndOfFrame call.
This could easily be fixed (or simplified) by Unity by adding an exception or a log when a WaitForEndOfFrame object is created in batch mode informing the user that this feature isn’t supported in batch mode.
Or, another alternative, is to handle WaitForEndOfFrame as a yield return null instead.
Any solution would be better than silently failing and discouraging confused users from using Unity tests.
I understand that this is used from a rendering perspective, but most Unity projects have some coroutines with calls to WaitForEndOfFrame in their code, or in plugins, and sometimes that problem can be deeply nested instead of being in the first layer of the test, making debugging extremely hard.