From cbbd43d6dea50fb7e8a4728952a45b92f811f3ba Mon Sep 17 00:00:00 2001 From: xiaoy312 Date: Wed, 5 Apr 2023 12:57:35 -0400 Subject: [PATCH] test: stabilize When_RepeatForever_ShouldLoop --- .../Given_DoubleAnimation.cs | 41 +++++++++++++------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Media_Animation/Given_DoubleAnimation.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Media_Animation/Given_DoubleAnimation.cs index 1c97feaf6d..9a8a74af6e 100644 --- a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Media_Animation/Given_DoubleAnimation.cs +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Media_Animation/Given_DoubleAnimation.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -121,10 +121,20 @@ namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Media_Animation [RunsOnUIThread] public async Task When_RepeatForever_ShouldLoop() { + // On CI, the measurement at 100ms seem to be too unreliable on Android & MacOS. + // Stretch the test by 5x greatly improve the stability. When testing locally, we can used 1x to save time (5s vs 25s). + const int TimeResolutionScaling = +#if !DEBUG && (__ANDROID__ || __MACOS__) + 5; +#else + 1; +#endif + var target = new Windows.UI.Xaml.Shapes.Rectangle { Stretch = Stretch.Fill, Fill = new SolidColorBrush(Colors.SkyBlue), + Width = 50, Height = 50, }; WindowHelper.WindowContent = target; @@ -137,19 +147,16 @@ namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Media_Animation From = 0, To = 50, RepeatBehavior = RepeatBehavior.Forever, - Duration = TimeSpan.FromMilliseconds(500), - }; - Storyboard.SetTarget(animation, target); - Storyboard.SetTargetProperty(animation, nameof(Rectangle.Width)); - - var storyboard = new Storyboard { Children = { animation } }; - storyboard.Begin(); + Duration = TimeSpan.FromMilliseconds(500 * TimeResolutionScaling), + }.BindTo(target, nameof(Rectangle.Width)); + animation.Begin(); + // In an ideal world, the measurements would be [0 or 50,10,20,30,40] repeated 10 times. var list = new List(); for (int i = 0; i < 50; i++) { - list.Add(target.Width); - await Task.Delay(100); + list.Add(NanToZero(target.Width)); + await Task.Delay(100 * TimeResolutionScaling); } var delta = list.Zip(list.Skip(1), (a, b) => b - a).ToArray(); @@ -160,10 +167,20 @@ namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Media_Animation .ToArray(); var incrementSizes = drops.Zip(drops.Skip(1), (a, b) => b - a - 1).ToArray(); // -1 to exclude the drop itself + var context = new StringBuilder() + .AppendLine("list: " + string.Join(", ", list.Select(x => x.ToString("0.#")))) + .AppendLine("delta: " + string.Join(", ", delta.Select(x => x.ToString("+0.#;-0.#;0")))) + .AppendLine("averageIncrement: " + averageIncrement) + .AppendLine("drops: " + string.Join(", ", drops.Select(x => x.ToString("0.#")))) + .AppendLine("incrementSizes: " + string.Join(", ", incrementSizes.Select(x => x.ToString("0.#")))) + .ToString(); + // This 500ms animation is expected to climb from 0 to 50, reset to 0 instantly, and repeat forever. // Given that we are taking 5measurements per cycle, we can expect the followings: - Assert.AreEqual(10d, averageIncrement, 1.5, "an rough average of increment (exluding the drop) of 10 (+-15% error margin)"); - Assert.IsTrue(incrementSizes.Count(x => x > 3) > 8, $"at least 10 (-2 error margin: might miss first and/or last) sets of continuous increments that size of 4 (+-1 error margin: sliding slot): {string.Join(",", incrementSizes)}"); + Assert.AreEqual(10d, averageIncrement, 2.5, $"Expected an rough average of increment (excluding the drop) of 10 (+-25% error margin).\n" + context); + Assert.IsTrue(incrementSizes.Count(x => x >= 3) >= 8, $"Expected at least 10sets (-2 error margin: might miss first and/or last) of continuous increments in size of 4 (+-1 error margin: sliding slot).\n" + context); + + double NanToZero(double value) => double.IsNaN(value) ? 0 : value; } [TestMethod] -- GitLab