mercredi 27 mai 2015

Unit test view rendering time in WPF

I have a requirement on my project that all views should render themselves in under 500 milliseconds which does not take into account the time spent filling the data on the view, doing calls to the backend and so on.

Just the control rendering time should be measured.

I saw many similar questions here in SO and other places but none that truly helps me with the problem.

What I have so far is the following unit test:

[TestMethod]
public void View_WaitForLoadedEvent_ElapsedTimeDoesNotExceedAllowedLimit()
{
    // Arrange.
    var dispatcherAction =
        new System.Action(() =>
            {
                this.stopWatch.Stop();
                this.elapsedMilliseconds = this.stopWatch.ElapsedMilliseconds;

                Dispatcher.ExitAllFrames();
            });

    this.stopWatch.Start();
    Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Loaded, dispatcherAction);

    // Act.
    var view = new HomeView();

    Dispatcher.Run();

    // Assert.
    Assert.IsTrue(this.elapsedMilliseconds < RenderTimeTests.MaxAllowedRenderingMilliseconds,
                  RenderTimeTests.GetFormattedErrorMessage(view.ToString(), this.elapsedMilliseconds));
}

Now, after executing this test 10 times in a row I got the following values for the this.elapsedMilliseconds variable:

153, 140, 109, 144, 131, 116, 124, 127, 139, 106. So on average it takes 128.9 milliseconds to load.

The values are fairly constant, but when doing the test recommended in most of the answers for the similar questions here in StackOverflow the values are different.

The recommended test is as follows:

public HomeView()
{
    var sw = new Stopwatch();
    sw.Start();

    this.Dispatcher.BeginInvoke(
        DispatcherPriority.Loaded,
        new System.Action(() =>
        {
            sw.Stop();
            MessageBox.Show("Took " + sw.ElapsedMilliseconds + " ms");
        }));

    this.InitializeComponent();
}

And this gives me the following values on the message box:

206, 213, 218, 203, 210, 209, 210, 210, 222, 230. On average this is 213.1.

It may not seems as much but these values tell me that the actual rendering time is 60% higher than what the automated test tells me!

Finally, I decided to remove the MessageBox.Show(...) method and replace it with Debug.WriteLine(...) just to see if there was any difference (although the watch should not be counting anymore at this point) and I got the following values:

207, 194, 212, 207, 211, 201, 217, 215, 214, 214. Giving an average of 209.2, much closer to the other execution than to the unit test results.

And so this brings me to the question, how reliable are these tests in reality?

Aucun commentaire:

Enregistrer un commentaire