Winforms Automation Extensions

kick it on
In preparation for my talk next Saturday, I am publishing the code that I use to help drive my WinForms application via NUnit tests. The idea is simple — instantiate the form and use extension methods on the controls to find the controls and drive from there.

This is a preliminary release. I will update this file as I find more functionality s needed. It turns out that you don’t need much (besides some creativity) to automate WinForms UIs. This set of extension methods will help you get started.

Download WAX — Winforms Automation Extensions

To run your forms in NUnit, you just need create/show it in the setup and close it in the teardown:

   1: [SetUp]
   2: public void SetUp()
   3: {
   4:     _testForm = new FormToTest();
   5:     _testForm.Show();
   6: }
   8: [TearDown]
   9: public void TearDown()
  10: {
  11:     _testForm.Close();
  12: }

Here is an example of finding a button by name, clicking on it and validating that the app changed the text of the label:

   1: [Test]
   2: public void Test_That_Button_Click_Changes_Text()
   3: {
   4:    var button = _testForm.FindByName<Button>("Button1");
   5:    var label = _testForm.FindByName<Label>("Label1");
   7:    button.SimulateClick();
   8:    Assert.That(label.Text, Is.EqualTo("Hello World"));
   9: }

Note that the FindByName method is just a specialization of the Find method. The Find method takes a delegate you can use to find your controls using any method you wish. For instance, say you want to find a control with a known tag:

   1: [Test]
   2: public void Test_Find_With_Custom_Filter()
   3: {
   4:     var l1 = _testForm.Find<Control>(target => (target.Tag as string) == "FindTag");
   5:     Assert.That(l1.Name, Is.EqualTo("ListBox1"));
   6: }

In my experience, driving the controls directly is the easiest way to automate the UI. For instance, if you have a list control that you want to set, you might write code like this:

   1: [Test]
   2: public void Test_Setting_ListBox()
   3: {
   4:     var listBox = _testForm.FindByName<ListBox>("ListBox1");
   5:     listBox.SelectedIndex = 1;
   7:     Assert.That(listBox.SelectedItem.ToString(), Is.EqualTo("The Test"));
   8: }

If you have any questions or thoughts about this code, please contact me. I want to grow this code over time, and feedback is very welcome.

Leave a Reply