Now that you have your code in place you can create your
unit tests to validate your code. Your unit tests will go into a separate
project designed specifically to test your code. You have the ability to add
unit tests to your project but it is not recommended because you don't want to
deploy your tests to production. Putting them in a separate project allows you
to test your project without affecting production.
1.
Right click on the TripCalculator solution in the Solution Explorer and
select AddàNew Project… from the pop-up
menu.
2.
Click "Test" from the list of installed Visual C# templates
and choose the Test Project template.
3.
Name the project "TripCalculatorTest" and click the OK button.
1.
The TripCalculatorTest project will be added with a single class called
UnitTest1.cs. Delete this class from your project.
2.
Right click on the TripCalculatorTest project and select AddàNew Test from the pop-up menu.
3.
The Add New Test dialog should appear.
4.
Select the Unit Test Wizard template and click the OK button.
5.
The Create Unit Test Wizard will appear. The screen shows you the list
of projects in your solution that you can test. We'll first add a unit test to
test the CalculateDistance method in the TripCalculatorBLL.DistanceCalculator
class. You can expand each node on the screen by clicking the arrow next to
the name of the namespace or class that you want to test. Check the box next
to the CalculateDistance method.
6.
Click the OK button.
7.
A new class called DistanceCalculatorTest.cs will be added to your
project. The code for this class is as follows:
using TripCalculatorBLL;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
namespace TripCalculatorTest
{
/// <summary>
///This is a test class for DistanceCalculatorTest and is intended
///to contain all DistanceCalculatorTest Unit Tests
///</summary>
<span class=Bold>[TestClass()]</span>
public class DistanceCalculatorTest
{
<span class=Bold>private TestContext testContextInstance;</span>
/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///</summary>
public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}
#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 static void MyClassInitialize(TestContext testContext)
//{
//}
//
//Use ClassCleanup to run code after all tests in a class have run
//[ClassCleanup()]
//public static void MyClassCleanup()
//{
//}
//
//Use TestInitialize to run code before running each test
//[TestInitialize()]
//public void MyTestInitialize()
//{
//}
//
//Use TestCleanup to run code after each test has run
//[TestCleanup()]
//public void MyTestCleanup()
//{
//}
//
#endregion
/// <summary>
///A test for CalculateDistance
///</summary>
<span class=Bold>[TestMethod()]</span>
public void CalculateDistanceTest()
{
DistanceCalculator target = new DistanceCalculator();
// TODO: Initialize to an appropriate value
double time = 0F; // TODO: Initialize to an appropriate value
double speed = 0F; // TODO: Initialize to an appropriate value
double expected = 0F; // TODO: Initialize to an appropriate value
double actual;
actual = target.CalculateDistance(time, speed);
Assert.AreEqual(expected, actual);
Assert.Inconclusive("Verify the correctness of this test method.");
}
}
}
8.
One of the first things to notice is the use of the Microsoft.VisualStudio.TestTools.UnitTesting
namespace. This namespace contains the objects that you'll want to use to
manipulate your tests. One of the main objects used in this namespace is the
"Assert" object. This is used to validate your expected results
against your actual results. I'll demonstrate how this works soon.
9.
Notice that the class has an attribute called [TestClass()]. This tells
Visual Studio that test methods reside in this class and they should be run
when the unit tests are run.
10. There
is a private object called TestContext which is also found in the Microsoft.VisualStudio.TestTools.UnitTesting
namespace. This object is used to setup certain parameters of the testing such
as a connection to a database.
11. The
next region is called "Additional Test Attributes". This is
commented out but can be used to run specific code when the class is
initialized, destroyed, or every time a test in this class is executed or
finished. For now we'll just leave these commented out.
12. The
code that will test our CalculateDistance method is tested by the CalculateDistanceTest
method.
/// <summary>
///A test for CalculateDistance
///</summary>
<span class=Bold>[TestMethod()]</span>
public void CalculateDistanceTest()
{
DistanceCalculator target = new DistanceCalculator();
// TODO: Initialize to an appropriate value
double time = 0F; // TODO: Initialize to an appropriate value
double speed = 0F; // TODO: Initialize to an appropriate value
double expected = 0F; // TODO: Initialize to an appropriate value
double actual;
actual = target.CalculateDistance(time, speed);
Assert.AreEqual(expected, actual);
Assert.Inconclusive("Verify the correctness of this test method.");
}
13. The
wizard looked at the parameters of the CalculateDistance method and created
local variable that you should initialize with your test data to test your
method. Set the time variable to 5 and the speed variable to 6. Set the
expected variable to 30.
14. Notice
that the "actual" variable is being set to the return value of the
CalculateDistance method. The Assert.AreEqual method will validate that the
expected value is the same as the actual value. If they aren't the test will
fail and it will appear in the TestResults view.
15. Comment
out the Assert.Inconclusive line. This isn't needed.
16. To
run this test you simply need to right click anywhere in the
CalculateDistanceTest method and select "RunTests" from the pop-up
menu.
17. Visual
Studio will compile the project and run the CalculateDistanceTest method. The TestResult
view will show you whether the test passed or not.
18. Now
let's change the code to cause it to not pass so we can see the result view.
If you change the time to 7 and then run the test again it should fail.
19. Notice
in the Test Result view the Result is Fail and it has a red X next to it. You
can double click on the row in the Test Result view and it will show you more
detail about what was expected and what was the actual.
20. Now
let's test that if you pass in a negative time that the method throws an
exception. Click back to the DistanceCalculatorTest class. Add a new method
to test throwing an exception by adding the following method.
[TestMethod()]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void CalculateDistanceTest2()
{
DistanceCalculator target = new DistanceCalculator();
double time = -1;
double speed = 6;
double actual;
actual = target.CalculateDistance(time, speed);
}
21. Notice
that this method has an attribute called "ExpectedException" which
tell the unit testing framework to expect that this code will throw the
ArgumentOutOfRangeException. This is very helpful in order to fully test your
code.
22. If
you right click in this method and run the test you should also get a result of
Passed.
23. Now
that you have two test methods you may want to run all the tests at once. To
do this click on TestàRunàAll Tests In Solution from the main
menu. This will run all the tests and show you the results in the Test Result
view.
24. If
you want to step through your test code you need to run the test in debug
mode. First, put a breakpoint in the test method you want to step through.
Select TestàDebugàTests in Current Context from the main
menu. Visual Studio will start the unit testing framework and will stop at
your breakpoint. You can then debug your test code just as you would normally
debug any other code.