As hoped, my framework allows easy testing of events in forms. I added a CheckBox and a Button to a form, set the Button’s Enabled property to False, and added an event handler (to the form) for the CheckBox’s CheckedChanged event. The event handler simply sets Button1.Enabled = CheckBox1.Checked.
This is very common practice in Windows.Forms. You prevent the user performing an action until a condition is met. I often forget to take account of some control’s state, so I’d like to be able to write tests to ensure that I have covered all the controls I should. Here goes, then:
<AsyncTest()> Public Sub TestCheckBoxChangesButtonEnabled()
AddEventHandler(Me.TheForm.CheckBox1, "CheckedChanged", "CheckedChangedCallback")
Me.TheForm.CheckBox1.Checked = True
End Sub
Public Sub CheckedChangedCallback(ByVal sender As System.Object, ByVal e As System.EventArgs)
AssertEqual(Me.TheForm.CheckBox1.Checked, Me.TheForm.Button1.Enabled)
End Sub
Nice and simple, and it works!
I thought that this might not work, as there are two event handlers added to the checkbox: one by the form itself and one by the test code. The test code comes second, though, and events are handled synchronously, so the test code’s callback is called second. I need to figure out whether this will always be true. If not, I can hack around it with a 1-millisecond timer, but then there’s another possibility: the ‘real’ callback also does something similar with a timer.
I hope delaying action with a timer is not too common. I know I have used something similar in Qt code, though, so perhaps others use it with Windows.Forms and I’ll have to find a way to make it work.
For now, I’m happy that I can test Windows.Forms code using normal-looking code and only one wrapper function.
I really should look at NUnit.Forms, to see if it provides the same functionality with less of a hack (compiling code at runtime) and a similar cleanliness of test code.