Visual Studio Team System (VSTS) comes with many tools
integrated in it for the developers & testers and also for architects and
managers. The unit testing tool that comes with Visual Studio 2005 enables the
developers to generate the test classes and methods. Team Test does not provide
tools only for developers but it provides tools for testers as well. The other
feature of Team Test is the ability to load data from the database to test the
methods. Here we will see an example of creating unit tests as well as how to
deal with exceptions.
Let me walk through how to create unit tests. Let’s take an
example of creating an assembly with an Employee class, with a method for
adding an Employee with his/her First Name, Last Name and Date of Birth. Create
a new class library project named "VSTSEmp". You can see the checkbox
option "Create directory for solution". This checkbox is checked by
default. This enables us to create the test project in a separate directory. If
the checkbox is deselected, the test project will get created in the VSTSEmp
project directory itself. Let's leave the checkbox option selected. For this
article I will be using C#, but you could easily do the same in Visual Basic.
Figure 1
The new project contains a class file with the default name
as “Class1.cs”. Let’s rename the class file as “Employees.cs” which will also
rename the class name to Employees. Include the constructor for the Employee
class with three parameters as firstName as string, lastName as string and dateOfBirth
as DateTime.
Figure 2
Now we will see how to create the test class and test method
for the employee class and its constructor. Anywhere on the employee class
right click and choose the option “Create Unit Tests…”, as shown in Figure 3.
Figure 3
Selecting the menu option “Create Unit Tests…” will display
a dialog for generating the unit tests as a different project. Let's give the
name for the test project as “VSTSEmp.Test”. Enter this value in the dialog
box. Make sure “Create a new Visual C# test project…” option is selected in the
output project options as we are using C# for our test.
Figure 4
The test project is created with 2 default files:
“AuthoringTests.txt” and “EmployeesTest.cs”.
·
The “AuthoringTests.txt” file gives information about authoring
the tests and different types of tests that we can perform using VS 2005 team
test.
·
The EmployeeTest.cs is the generated test class file for the
Employee class by which we can include or generate test methods for all the
methods of the Employee class
The generated test project contains references to “VSTSEmp”
project against which the test project is created and the
Microsoft.VisualStudio.QualityTools.UnitTestFramework which is the testing
framework assembly for the test engine to execute the test project. Following
is the generated test class and the test method for the constructor with the
default implementation.
Listing 1
usingMicrosoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Text;
using System.Collections.Generic;
using VSTSEmp;
namespace VSTSEmp.Test
{
[TestClass()]
public class EmployeesTest
{
private TestContext testContextInstance;
public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}
[TestMethod()]
public void ConstructorTest()
{
string firstName = null; // TODO:Initialize to an appropriate value
string lastName = null; // TODO:Initialize to an appropriate value
DateTime dateOfBirth = new DateTime();
Employees target = newEmployees(firstName, lastName, dateOfBirth);
Assert.Inconclusive("TODO: Implementcode to verify target");
}
}
}
There are two important attributes which indentify the Test
class and test methods. The test class is identified with the attribute
“TestClassAttribute” attribute. The test methods in the test class are
identified with the “TestMethodAttribute” attribute. Both of these attributes
are available in the Microsoft.VisualStudio.QualityTools.UnitTestFramework
namespace. Team test uses reflection to find the test assembly and then finds
all the test classes using the test class attribute. After finding the test
class the team test finds all the test methods using the Test Method attribute.
The test method (ConstructorTest()) instantiates the target Employee class
before asserting that the test is inconclusive (Assert.Inconclusive()). The
Assert.Inconclusive() indicates that the correct implementation of the method
is missing. Let's update the ConstructorTest() method so that it checks the
initialization of the employee firstName and dateofBirth. We have not yet
created the fields or properties for the FirstName, LastName and DateofBirth.
Before updating the test method we have to create these properties in the
Employee class to avoid compile errors.
Listing 2
private string _firstName;
public string FirstName
{
get
{
return _firstName;
}
set
{
_firstName = value;
}
}
private string _lastName;
public string LastName
{
get
{
return _lastName;
}
set
{
_lastName = value;
}
}
private DateTime _dateOfBirth;
public DateTime DateOfBirth
{
get
{
return _dateOfBirth;
}
set
{
_dateOfBirth = value;
}
}
Asserts
Look at the listing given below
Listing 3
[TestMethod()]
public void ConstructorTest()
{
string firstName = "Satheesh";
string lastName = "Kumar";
DateTime dateOfBirth = new DateTime();
dateOfBirth = System.DateTime.Today;
Employees Employee = new Employees(firstName,lastName, dateOfBirth);
Assert.AreEqual < string > (firstName,Employee.FirstName,
"The Employee firstname was notcorrectly initialized");
Assert.AreEqual < DateTime >(dateOfBirth, Employee.DateOfBirth,
"The Employee Date of Birth was notcorrectly initialized");
}
Here the checks are done using the
Assert.AreEqual<T>() method. The assert method also supports an
AreEqual() method without Generics. The generic version is
always preferred because it will verify at compile time that the types match.
Let’s run the test with whatever implementation we have. The
implementations are not yet over but let’s proceed to testing. We need to run
the test project to run all the tests. Just right click the test project and make
it the Startup project. Using the Debug-> Start (F5) menu item begin running
the test project.
After running the project the Test Result window appears.
The result shows one failed and nothing else because we have only one method
for testing. Initially the result will be shown as “pending” then “In progress”
and then it will display “Failed”. You can add/remove the default columns in
the test result window using the menu options
Figure 5
To see additional details on the Constructor test result,
just double click on the error message. The ConstructorTest[Results] widow
opens up with more information on the error.
Figure 6
Now let's test for an exception using the “ExpectedExceptionAttribute”.
Listing 4 shows two methods that check for null or empty string value for the
employee First Name. This value null or empty value to the constructor throws
the exception of type “ArgumentException”.
Listing 4
[TestMethod]
[ExpectedException(typeof(ArgumentException),
"Null value for Employee First Name isnot allowed")]
public void EmployeeFirstNameNullInConstructor()
{
Employees Employee = new Employees(null,
"Kumar", System.DateTime.Today());
}
[TestMethod]
[ExpectedException(typeof(ArgumentException),
"Empty value for Employee First Name isnot allowed")]
public void EmployeeFirstNameNullInConstructor()
{
Employees Employee =
new Employees("", "Kumar", System.DateTime.Today());
}
Notice that the above code does not have any try catch block
like normal exception handling. The code contains one attribute
ExpectedException which includes one parameter for the type of exception and
the other parameter for the error message. Now when you execute the test
project, the framework will expect an argument exception to be thrown. If not,
the test will fail. Now update the Employee class to provide the functionality
the tests are checking for. Below is the updated code.
Listing 5
private string _firstName;
public string FirstName
{
get
{
return _firstName;
}
set
{
if (value == null || value.Trim() ==string.Empty())
{
throw new ArgumentException("EmployeeFirst Name cannot be null or Empty");
}
_firstName = value;
}
}
Now run the test and make sure the implementation is
correct.
Summary
In this article, you have learned how to perform Unit
Testing using Visual Studio 2005.
Resources
TeamSystemRocks.com
- Visual Studio Team System Community