Training
Module
C# testing in Visual Studio - Training
Start testing your C# apps by using the testing tools in Visual Studio. Learn to write tests, use Test Explorer, create test suites, and apply the red, green, refactor pattern to write code.
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Create unit tests to help keep your code working correctly through incremental code changes. There are several frameworks that you can use to write unit tests, including some developed by third parties. Some test frameworks are specialized for testing in different languages or platforms. Test Explorer provides a single interface for unit tests in any of these frameworks. For more information about Test Explorer, see Run unit tests with Test Explorer and Test Explorer FAQ.
This walkthrough demonstrates how to develop a tested method in C# using Microsoft Test Framework (MSTest). You can easily adapt it for other languages or other test frameworks, such as NUnit. For more information, see Install third-party unit test frameworks.
Create a C# Class Library project for .NET or .NET Standard. This project will contain the code that we want to test. Name the project MyMath.
In the same solution, add a new MSTest test project for .NET.
In Visual Studio 2019 version 16.9, the MSTest project template name is Unit Test Project.
Name the test project MathTests.
Write a simple test method that verifies the result obtained for a specific input. Add the following code to the UnitTest1
class:
[TestMethod]
public void BasicRooterTest()
{
// Create an instance to test:
Rooter rooter = new Rooter();
// Define a test input and output value:
double expectedResult = 2.0;
double input = expectedResult * expectedResult;
// Run the method under test:
double actualResult = rooter.SquareRoot(input);
// Verify the result:
Assert.AreEqual(expectedResult, actualResult, delta: expectedResult / 100);
}
Generate a type from the test code.
Place the cursor on Rooter
, and then from the light bulb menu, choose Generate type 'Rooter' > Generate new type.
In the Generate Type dialog box, set Project to MyMath, the class library project, and then choose OK.
Generate a method from the test code. Place the cursor on SquareRoot
, and then from the light bulb menu, choose Generate method 'Rooter.SquareRoot'.
Run the unit test.
Open Test Explorer.
To open Test Explorer from the Test menu, choose Test Explorer.
To open Test Explorer from the Test menu, choose Windows > Test Explorer.
In Test Explorer, choose the Run All button to run the test.
The solution builds, and the test runs and fails.
Select the name of the test.
The details of the test appear in the Test Detail Summary pane.
Select the top link under Stack Trace to jump to the location where the test failed.
At this point, you've created a test and a stub that you can modify so that the test passes.
In the Class1.cs file, improve the code of SquareRoot
:
public double SquareRoot(double input)
{
return input / 2;
}
In Test Explorer, choose Run All.
The solution builds, and the test runs and passes.
To improve our confidence that the code works in all cases, add tests that try a broader range of input values.
Tip
Avoid altering existing tests that pass. Instead, add new tests. Change existing tests only when the user requirements change. This policy helps to make sure that you don't lose existing functionality as you work to extend the code.
In the test class, add the following test, which tries a range of input values:
[TestMethod]
public void RooterValueRange()
{
// Create an instance to test.
Rooter rooter = new Rooter();
// Try a range of values.
for (double expected = 1e-8; expected < 1e+8; expected *= 3.2)
{
RooterOneValue(rooter, expected);
}
}
private void RooterOneValue(Rooter rooter, double expectedResult)
{
double input = expectedResult * expectedResult;
double actualResult = rooter.SquareRoot(input);
Assert.AreEqual(expectedResult, actualResult, delta: expectedResult / 1000);
}
In Test Explorer, choose Run All.
The new test fails (although the first test still passes). To find the point of failure, select the failing test, and then look at the details in the Test Detail Summary pane.
Inspect the method under test to see what might be wrong. Alter the SquareRoot
code as follows:
public double SquareRoot(double input)
{
double result = input;
double previousResult = -input;
while (Math.Abs(previousResult - result) > result / 1000)
{
previousResult = result;
result = result - (result * result - input) / (2 * result);
}
return result;
}
In Test Explorer, choose Run All.
Both tests now pass.
Add a new test for negative inputs:
[TestMethod]
public void RooterTestNegativeInput()
{
Rooter rooter = new Rooter();
Assert.ThrowsException<ArgumentOutOfRangeException>(() => rooter.SquareRoot(-1));
}
In Test Explorer, choose Run All.
The method under test loops and must be canceled manually.
Choose Cancel on the toolbar of Test Explorer.
The test stops executing.
Fix the SquareRoot
code by adding the following if
statement at the beginning of the method:
public double SquareRoot(double input)
{
if (input <= 0.0)
{
throw new ArgumentOutOfRangeException();
}
...
In Test Explorer, choose Run All.
All the tests pass.
Refactor the code, but do not change the tests.
Tip
A refactoring is a change that is intended to make the code perform better or easier to understand. It is not intended to alter the behavior of the code, and therefore the tests are not changed.
We recommend that you perform refactoring steps separately from steps that extend functionality. Keeping the tests unchanged gives you confidence that you have not accidentally introduced bugs while refactoring.
Change the line that calculates result
in the SquareRoot
method as follows:
public double SquareRoot(double input)
{
if (input <= 0.0)
{
throw new ArgumentOutOfRangeException();
}
double result = input;
double previousResult = -input;
while (Math.Abs(previousResult - result) > result / 1000)
{
previousResult = result;
result = (result + input / result) / 2;
//was: result = result - (result * result - input) / (2*result);
}
return result;
}
Choose Run All, and verify that all the tests still pass.
Training
Module
C# testing in Visual Studio - Training
Start testing your C# apps by using the testing tools in Visual Studio. Learn to write tests, use Test Explorer, create test suites, and apply the red, green, refactor pattern to write code.
Documentation
Create, run, and customize C# unit tests - Visual Studio (Windows)
Learn how to create, run, and customize a series of unit tests using the Microsoft unit test framework for managed code and Visual Studio Test Explorer.
Run unit tests by using Test Explorer - Visual Studio (Windows)
Learn how Visual Studio Test Explorer provides a flexible and efficient way to run your unit tests and view their results.
Create a unit test project - Visual Studio (Windows)
Learn how to create a unit test project. The test project can be in the same solution as the production code, or it can be in a separate solution.