Contents tagged with uitestmethod

UWP: where's [UITestMethod]?

Update Sep 17: This article is now obsolete. It presents a workaround for the missing [UITestMethod] attribute. The workaround is no longer needed, since [UITestMethod] has been re-added in the Tools for Universal Windows apps 1.1 on Sep 16, 2015.

When using the Visual Studio unit test project to create unit tests, a test method is typically decorated with [TestMethod]. This ensures the method is picked up by the unit test executor. That's all good, but if you attempt to access a XAML UI object in such method, errors do occur.

Take for instance the following test method;

[TestMethod]
public void TestMethod1()
{
  var brush = new SolidColorBrush(Colors.Red);
  Assert.AreEqual(Colors.Red, brush.Color);
}

Running this test will result in the following error;

The application called an interface that was marshalled for a different thread.
(Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD)).
If you are using UI objects in test consider using [UITestMethod] attribute instead of [TestMethod] to execute test in UI thread.

Accessing XAML UI objects require the code to run on the main UI thread. To make that happen, we just need to decorate the test method with [UITestMethod] instead of [TestMethod]. [UITestMethod] ensures the test method is executed on the UI thread, and all was good.

The problem

Unfortunately [UITestMethod] is nowhere to be found in the Win10 RTM SDK, even though it is mentioned in the error message. It was available in the Win10 Preview SDK. I do not know the rationale behind this move, is there a compelling reason not to run unit tests on the UI thread? Or did someone forget to include it? A lot of my unit tests now fail for my Win10 universal projects, and I need this fixed.

The solution

Luckily, it is very easy to implement your own TestMethod attribute. Taken from the preview SDK, here's a [UITestMethod] implementation that ensures your code is executed on the UI thread. Just include the code in your unit test project, and you should be good.

using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Windows.ApplicationModel.Core;
using Windows.UI.Core;

namespace Microsoft.VisualStudio.TestPlatform.UnitTestFramework.AppContainer
{
  public class UITestMethodAttribute : TestMethodAttribute
  {
    public override TestResult[] Execute(ITestMethod testMethod)
    {
      if (testMethod.GetAttributes<AsyncStateMachineAttribute>(false).Length != 0) {
        throw new NotSupportedException("async TestMethod with UITestMethodAttribute are not supported. Either remove async or use TestMethodAttribute.");
      }

      TestResult result = null;

      CoreApplication.MainView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {
        result = testMethod.Invoke(new object[0]);
      }).AsTask().GetAwaiter().GetResult();

      return new TestResult[] { result };
    }
  }
}

With the UITestMethodAttribute implementation in place, we can now decorate our testmethods with [UITestMethod] to ensure the test method is executed on the UI thread.




Read More >>

Latest News

RSS feed

Subscribe to the RSS feed and receive the latest news from First Floor Software in your favorite RSS reader.

Subscribe