ppy / osu-framework

A game framework written with osu! in mind.
MIT License
1.67k stars 419 forks source link

Some tests fail when ran individually because it is is executed before depenency is injected #4444

Open ekrctb opened 3 years ago

ekrctb commented 3 years ago

Consider a test scene like this:

public class TestSceneExample : TestScene
{
    [Resolved]
    private ResolvedValue resolvedValue { get; set; }

    [Test]
    public void TestUsingResolvedValue() {
        Assert.NonNull(resolvedValue);
    }
}

When TestSceneExample (the test scene) is tested, it passes. However, the test TestUsingResolvedValue is tested individually, it fails. The dependencies are resolved only after the first test method is executed. When a test scene is tested as a whole, the issue is masked because the test TestConstructor is executed first and then dependencies are loaded, and then the rest of the tests are executed.

An example of failing tests are osu! TestSceneLegacyBeatmapSkin tests (there are two TestSceneLegacyBeatmapSkin in Rulesets.Osu.Tests and Rulesets.Catch.Tests, and this issue applies to the both) (unrelated: audio property is not needed as there is Audio in OsuTestScene base class, but the result is the same). But I guess there are more failing tests, as I found the example only by an accident.

I think this issue should be fixed in the framework as the issue is hard-to-find and confusing when occurs. All dependencies should be loaded in a setup step before test methods are executed.

smoogipoo commented 3 years ago

This is known - it's actually quite hard to make this work, which is why Setup methods always use a schedule, and why we have AddStep() and all other test methods instead of using nunit assertions. It's not related to dependencies - it's the same with any framework component - drawables/etc - the method's code isn't running inside the gamehost.

If it can be worked to use the correct thread context, that'd be great, but it's very involved.