A game framework written with osu! in mind.
at master 5.5 kB view raw
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. 2// See the LICENCE file in the repository root for full licence text. 3 4using System.Linq; 5using NUnit.Framework; 6using osu.Framework.Development; 7using osu.Framework.Testing; 8using osu.Framework.Testing.Drawables.Steps; 9 10namespace osu.Framework.Tests.Visual.Testing 11{ 12 public class TestSceneTest : FrameworkTestScene 13 { 14 private int setupRun; 15 private int setupStepsRun; 16 private int setupStepsDummyRun; 17 private int teardownStepsRun; 18 private int teardownStepsDummyRun; 19 private int testRunCount; 20 private int testRunCountDummyRun; 21 22 [SetUp] 23 public virtual void SetUp() 24 { 25 // Under nUnit, [SetUp] is run once for the base TestScene.TestConstructor() method. Our own test method has not run yet by this point, so this is ignored. 26 // The test browser does _not_ invoke [SetUp] for the constructor, and the TestScene.TestConstructor() method is skipped. 27 if (DebugUtils.IsNUnitRunning && TestContext.CurrentContext.Test.MethodName == nameof(TestConstructor)) 28 return; 29 30 setupRun++; 31 } 32 33 [SetUpSteps] 34 public virtual void SetUpSteps() 35 { 36 // Under nUnit, [SetUpSteps] is run once for the base TestScene.TestConstructor() method. Our own test method has not run yet by this point, so this is ignored. 37 // The test browser does _not_ invoke [SetUpSteps] for the constructor, and the TestScene.TestConstructor() method is skipped. 38 if (DebugUtils.IsNUnitRunning && TestContext.CurrentContext.Test.MethodName == nameof(TestConstructor)) 39 return; 40 41 AddStep(new SingleStepButton(true) 42 { 43 Name = "set up dummy", 44 Action = () => setupStepsDummyRun++ 45 }); 46 47 AddStep("set up second step", () => { }); 48 setupStepsRun++; 49 } 50 51 [TearDownSteps] 52 public virtual void TearDownSteps() 53 { 54 // Under nUnit, [TearDownSteps] is run once for the base TestScene.TestConstructor() method. Our own test method has not run yet by this point, so this is ignored. 55 // The test browser does _not_ invoke [TearDownSteps] for the constructor, and the TestScene.TestConstructor() method is skipped. 56 if (DebugUtils.IsNUnitRunning && TestContext.CurrentContext.Test.MethodName == nameof(TestConstructor)) 57 return; 58 59 AddStep("tear down dummy", () => teardownStepsDummyRun++); 60 teardownStepsRun++; 61 } 62 63 public TestSceneTest() 64 { 65 // A dummy test used to pad the setup steps for visual testing purposes. 66 AddStep("dummy test", () => { }); 67 } 68 69 [Test, Repeat(2)] 70 public void TestTest() 71 { 72 AddStep("increment run count", () => testRunCountDummyRun++); 73 74 // Under nUnit, the test steps for each method are run during [TearDown], meaning setup count == test run count. 75 // The test browser immediately invokes all test methods _before_ any test steps are run, meaning test run count == total number of tests, 76 // so the dummy value is used instead to track the true test run count inside the test browser. 77 // 78 // nUnit: 79 // [SetUp] -> [Test] -> [TearDown] -> {{ Run steps }} -> [SetUp] -> [Test] -> [TearDown] -> {{ Run steps }} ... 80 // Test browser: 81 // [SetUp] -> [Test] -> [TearDown] -> [SetUp] -> [Test] -> [TearDown] -> ... -> {{ Run steps }} 82 // 83 AddAssert("correct [SetUp] run count", () => setupRun == (DebugUtils.IsNUnitRunning ? testRunCount : testRunCountDummyRun)); 84 85 // Under both nUnit and the test browser, this should be invoked once for all test methods _before_ any test steps are run. 86 AddAssert("correct [SetUpSteps] run count", () => setupStepsRun == testRunCount); 87 88 // Under both nUnit and the test browser, this should be invoked once before each test method. 89 AddAssert("correct setup step run", () => setupStepsDummyRun == testRunCountDummyRun); 90 91 // Under both nUnit and the test browser, this should be invoked once for all test methods _before_ any test steps are run. 92 AddAssert("correct [TearDownSteps] run count", () => teardownStepsRun == testRunCount); 93 94 // Under both nUnit and the test browser, this should be invoked once _after_ each test method. 95 AddAssert("correct teardown step run", () => teardownStepsDummyRun == testRunCountDummyRun - 1); 96 97 AddAssert("setup step marked as such", () => StepsContainer.OfType<StepButton>().First(s => s.Text.ToString() == "set up second step").IsSetupStep); 98 99 testRunCount++; 100 } 101 102 [TestCase(1)] 103 [TestCase(2)] 104 [Repeat(2)] 105 public void TestTestCase(int _) => TestTest(); 106 107 protected override ITestSceneTestRunner CreateRunner() => new TestRunner(); 108 109 private class TestRunner : TestSceneTestRunner 110 { 111 public override void RunTestBlocking(TestScene test) 112 { 113 base.RunTestBlocking(test); 114 115 // This will only ever trigger via NUnit 116 Assert.That(test.StepsContainer, Has.Count.GreaterThan(0)); 117 } 118 } 119 } 120}