NUnit STA Threads & Testing WPF

During the course of the WPF project we are working on at work, we decided to go down the Agile/XP/TDD/Mocks/Continuous Integration route, which means Unit tests, lots of them.

We are using NUnit, which I really like, but we are also using WPF, we are obviously using the latest/greatest patterns AKA MVVM, but from time tom time it is nice to be able to test certain things on WPF controls/windows etc etc.

So I set out to create a small NUnit test like the following:


/* Style Definitions */ table.MsoNormalTable {mso-style-name:”Table Normal”; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:””; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:11.0pt; font-family:”Calibri”,”sans-serif”; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:”Times New Roman”; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:”Times New Roman”; mso-bidi-theme-font:minor-bidi;}

diag11.jpg
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

Now to me this looked fine, but when I ran this code I got the following horror show.

STAThread

Where NUnit moaned about “The calling thread must be STA”. Oh, that’s to bad. So I had a small think, and then came up with this small idea, just pass the original code to a helper class and have it run that in a Thread using STA threading apartment state. Sounds cool, but did it work. Well yes actually it did, and here is the small helper class.

 

 diag2.jpg


.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }And here is how to use this from a NUnit test.


/* Style Definitions */ table.MsoNormalTable {mso-style-name:”Table Normal”; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:””; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:11.0pt; font-family:”Calibri”,”sans-serif”; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:”Times New Roman”; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:”Times New Roman”; mso-bidi-theme-font:minor-bidi;}

diag3.jpg

And just to prove it works, here is a screen shot of the actual test running successfully.

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }STAThreadOK

Here is a link to a small test project that you can see this working with : wpfandnunittest1.zip in case you want to use this in your own projects.

Enjoy

Advertisements

20 thoughts on “NUnit STA Threads & Testing WPF

  1. Josh Smith says:

    Nice job man. I wrote about this topic a while back, in case you’re interested: http://www.codeproject.com/KB/WPF/UnitTestDispatcherTimer.aspx

    Josh

  2. sacha says:

    Doh, I even left a comment on that article you wrote, must have forgot about that. Oh well proves we are both cool, I guess.

  3. daniel sun says:

    there is problem with this, here is an example:
    add the following to class UserControl1
    private string foo;
    public String Foo
    {
    get
    {
    return “foo”;
    }
    set
    {
    foo = value;
    }
    }
    add the following test to class UserControlTests
    [Test]
    public void TestFoo()
    {
    ThreadExecutor.RunCodeAsSTA(
    delegate
    {
    WpfAndNUnitTest.UserControl1 uc1 = new WpfAndNUnitTest.UserControl1();
    uc1.Foo = “Set the property”;
    Assert.AreEqual(“Set the property”, uc1.Foo);
    });
    }

    the test should fail, but it succeeds.

    basically the RunCodeAsSTA must not only kicks off the new Thread, it should be wait for the thead to complete before return.

  4. sacha says:

    Daniel thanks for your comments, I’ll Look into this.

  5. sacha says:

    Daniel, I have now fixed this, thanks for letting me know about that.

  6. […] Sacha Barber on NUnit STA Threads & Testing WPF […]

  7. Andrew Smith says:

    I didn’t try out the code but in reading it I’m wondering, wouldn’t the unit test pass if the assert failed or if you threw an exception since you’re eating the exception? I remember reading about nUnit cross threading issues a while back on Provost’s site – http://www.peterprovost.org/blog/post/NUnit-and-Multithreaded-Tests-CrossThreadTestRunner.aspx. I’m not sure if the same approach still applies or is required.

  8. […] NUnit STA Threads & Testing WPF (Sacha Barber) […]

  9. sacha says:

    Andrew, Having just read Provost’s site, you probably would want to store the Exception as he shows, or you could in my example log it, or re throw and catch that outside the STA codeblock call. I didn’t do that as I wanted to keep it a simple example, I figure people could throw and catch what they want.

    Oh well looks like there are lots of resources now, for people to choose from

  10. Alex says:

    Hi Sacha,
    what do you think about Pex?

    http://research.microsoft.com/Pex/

    Regards,

    Alex

  11. sacha says:

    Alex

    I haven’t heard of PEX I’ll have a look though, thanks for the link

  12. Mark Nijhof says:

    Very interesting read!

    I wrote a post about testing xaml behaviour using unit tests.

    http://blog.fohjin.com/2008/09/how-to-test-your-xaml-behavior-using.html

    -Mark

  13. sacha says:

    Mark your post is cool also. Thanks for sharing

  14. Cohen says:

    Wouldn’t it be easier to set the threading model to STA in the nunit config file.
    I also needed to do this when using WatiN for testing my web application.

    (example config:

    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    )

  15. Cohen says:

    Oops my < and > aren’t shown…
    1 <?xml version="1.0" encoding="utf-8" ?>
    2 <configuration>
    3 <configSections>
    4 <sectionGroup name="NUnit">
    5 <section name="TestRunner" type="System.Configuration.NameValueSectionHandler"/>
    6 </sectionGroup>
    7 </configSections>
    8 <NUnit>
    9 <TestRunner>
    10 <!– Valid values are STA,MTA. Others ignored. –>
    11 <add key="ApartmentState" value="STA" />
    12 </TestRunner>
    13 </NUnit>
    14 </configuration>

  16. Cohen says:

    Oeps my < and > aren’t shown…

    1 <?xml version="1.0" encoding="utf-8" ?>
    2 <configuration>
    3 <configSections>
    4 <sectionGroup name="NUnit">
    5 <section name="TestRunner" type="System.Configuration.NameValueSectionHandler"/>
    6 </sectionGroup>
    7 </configSections>
    8 <NUnit>
    9 <TestRunner>
    10 <!– Valid values are STA,MTA. Others ignored. –>
    11 <add key="ApartmentState" value="STA" />
    12 </TestRunner>
    13 </NUnit>
    14 </configuration>

  17. Cohen says:

    Sorry, sorry
    Apparently Mark Nijhof already mentoins this in his blog post!

    And Sorry Sasha for spamming your blog (it was unintentional) 🙂

  18. sacha says:

    Cohen

    Yeah thats works for me also.

  19. inTagger says:

    offtopic: sacha, did you ever try ReShaper?

  20. sacha says:

    Yeah we use Re-Sharper at work, though I have mixed feelings about it, generally I like it.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: