Introduction
I normally use Nunit for all my unittesting with VB.Net but for winforms testing MS-test is so much easier to use. And I know that in the past there have been attempts to make some frameworks to make this easer but MS-test just makes it trivial to do.
MS-test
What we want to test is if our textbox selects all text when we enter it.
Now let’s try this.
First create a form and then add a textbox to it. Then we add an eventhandler to the Enter event.
Imports System.Threading
Public Class Form1
Private Sub TextBox1_Enter(sender As System.Object, e As System.EventArgs) Handles TextBox1.Enter
End Sub
End Class
So whatever unittest we no create to test if it selectsall text when we enter the textbox should fail.
Creating a unittest for this in MS-test is trivial. Just rightclick the method and hit create unit tests.
Just select the method you want to test and click enter.
You will then get a new project and this class.
Imports System
Imports Microsoft.VisualStudio.TestTools.UnitTesting
Imports WindowsApplication1
'''<summary>
'''This is a test class for Form1Test and is intended
'''to contain all Form1Test Unit Tests
'''</summary>
<TestClass()> _
Public Class Form1Test
Private testContextInstance As TestContext
'''<summary>
'''Gets or sets the test context which provides
'''information about and functionality for the current test run.
'''</summary>
Public Property TestContext() As TestContext
Get
Return testContextInstance
End Get
Set(value As TestContext)
testContextInstance = Value
End Set
End Property
#Region "Additional test attributes"
'
'You can use the following additional attributes as you write your tests:
'
'Use ClassInitialize to run code before running the first test in the class
'<ClassInitialize()> _
'Public Shared Sub MyClassInitialize(ByVal testContext As TestContext)
'End Sub
'
'Use ClassCleanup to run code after all tests in a class have run
'<ClassCleanup()> _
'Public Shared Sub MyClassCleanup()
'End Sub
'
'Use TestInitialize to run code before running each test
'<TestInitialize()> _
'Public Sub MyTestInitialize()
'End Sub
'
'Use TestCleanup to run code after each test has run
'<TestCleanup()> _
'Public Sub MyTestCleanup()
'End Sub
'
#End Region
'''<summary>
'''A test for TextBox1_Enter
'''</summary>
<TestMethod(), _
DeploymentItem("WindowsApplication1.exe")> _
Public Sub TextBox1_EnterTest()
Dim target As Form1_Accessor = New Form1_Accessor() ' TODO: Initialize to an appropriate value
Dim sender As Object = Nothing ' TODO: Initialize to an appropriate value
Dim e As EventArgs = Nothing ' TODO: Initialize to an appropriate value
target.TextBox1_Enter(sender, e)
Assert.Inconclusive("A method that does not return a value cannot be verified.")
End Sub
End Class
You can delete most of that because most of it is rubbish. All you need is this.
Imports System
Imports Microsoft.VisualStudio.TestTools.UnitTesting
Imports WindowsApplication1
'''<summary>
'''This is a test class for Form1Test and is intended
'''to contain all Form1Test Unit Tests
'''</summary>
<TestClass()> _
Public Class Form1Test
'''<summary>
'''A test for TextBox1_Enter
'''</summary>
<TestMethod(), DeploymentItem("WindowsApplication1.exe")> _
Public Sub Test_If_Enter_Of_TextBox1_Does_a_selectAll_On_its_Text()
Dim target As Form1_Accessor = New Form1_Accessor()
Dim sender As Object = target.TextBox1
Dim e As EventArgs = Nothing
target.TextBox1.Text = "test"
target.TextBox1_Enter(sender, e)
Assert.AreEqual("test", target.TextBox1.SelectedText)
End Sub
End Class
If you now run this test, you will get this.
Now we change our code to this.
Imports System.Threading
Public Class Form1
Private Sub TextBox1_Enter(sender As System.Object, e As System.EventArgs) Handles TextBox1.Enter
CType(sender, TextBox).SelectAll()
End Sub
End Class
And we run the test again to see the result.
Conclusion
As you may well know a winform is normally hard to test because you will have to do a show to have it initialize properly. MS-test does this for you. MS-test also lets you invoke private methods as we have seen above, which in this case is not so bad because it prevents us from showing the form to just run our tests. And of course you can abuse just about anything with this kind of testing so use wisely. For me this is a nice way to test your view. And we all know how hard it is to test a view.