Running xUnit.net Tests on Specific Threads for WPF and Other UI Tests
source link: http://dontcodetired.com/blog/post/Running-xUnitnet-Tests-on-Specific-Threads-for-WPF-and-Other-UI-Tests
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Sometimes when you write a test with xUnit.net (or other testing frameworks) you may run into problems if UI technologies are involved. This usually relates to the fact that the test must execute using a specific threading model such as single-threaded apartment (STA).
For example suppose you had a WPF app that you wanted to add tests for.
The XAML looks like:
<
Window
x:Class
=
"WpfApp1.MainWindow"
xmlns:local
=
"clr-namespace:WpfApp1"
mc:Ignorable
=
"d"
Title
=
"MainWindow"
Height
=
"450"
Width
=
"800"
>
<
Grid
>
<
TextBlock
FontSize
=
"42"
Text
=
"{Binding Path=Greeting}"
/>
</
Grid
>
</
Window
>
And the simple quick and dirty view model class looks like:
namespace
WpfApp1
{
public
class
MainWindowViewModel
{
public
string
Greeting {
get
;
set
; }
}
}
And in the MainWindow constructor we set the data context:
public
MainWindow()
{
InitializeComponent();
var
vm =
new
MainWindowViewModel { Greeting =
"Hi there!"
};
DataContext = vm;
}
(This is a very simple demo code with no change notifications etc.)
If you wanted to write an xUnit.net test that instantiates an instance of MainWindow, such as:
[Fact]
[UseReporter(
typeof
(DiffReporter))]
public
void
RenderWithViewModel()
{
var
sut =
new
MainWindow();
var
vm =
new
MainWindowViewModel { Greeting =
"Good day!"
};
sut.DataContext = vm;
// Test rendering, e.g. using Approval Tests
WpfApprovals.Verify(sut);
}
If you run this, the test will fail with: System.InvalidOperationException : The calling thread must be STA, because many UI components require this.
Note: this test is using Approval Tests (e.g. [UseReporter(typeof(DiffReporter))]) to render the UI into an image file for approval, you can learn more about Approval Tests with my Pluralsight course. Approval Tests is no related to the threading model requirements.
To enable this test to run you need to instruct xUnit to run the test using an apartment model process (“STA thread”).
Luckily Andrew Arnott has done all the hard work for us and created some custom xUnit.net attributes that allow us to specify what thread/synchronization context to use for a test.
Once the Xunit.StaFact NuGet package has been installed into the test project you can replace the standard [Fact] attribute with [StaFact]. The test will now execute without error:
using
ApprovalTests.Reporters;
using
ApprovalTests.Wpf;
using
Xunit;
namespace
WpfApp1.Tests
{
public
class
MainWindowShould
{
[StaFact]
[UseReporter(
typeof
(DiffReporter))]
public
void
RenderWithViewModel()
{
var
sut =
new
MainWindow();
var
vm =
new
MainWindowViewModel { Greeting =
"Good day!"
};
sut.DataContext = vm;
// Test rendering, e.g. using Approval Tests
WpfApprovals.Verify(sut);
}
}
}
There are also a number of other attributes such as [WinFormsFact] for use with Windows Forms apps, check out the entire list of attributes in the docs.
If you use this library make sure to say a thankyou to Andrew on Twitter :)
SHARE:
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK