Movatterモバイル変換


[0]ホーム

URL:


Skip to main content

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Download Microsoft EdgeMore info about Internet Explorer and Microsoft Edge
Table of contentsExit focus mode

Unit testing C# with MSTest and .NET

  • 2025-03-27
Feedback

In this article

This tutorial takes you through an interactive experience building a sample solution step-by-step to learn unit testing concepts. If you prefer to follow the tutorial using a pre-built solution,view or download the sample code before you begin. For download instructions, seeSamples and Tutorials.

This article is about testing a .NET Core project. If you're testing an ASP.NET Core project, seeIntegration tests in ASP.NET Core.

Prerequisites

Create the source project

Open a shell window. Create a directory calledunit-testing-using-mstest to hold the solution. Inside this new directory, rundotnet new sln to create a new solution file for the class library and the test project. Create aPrimeService directory. The following outline shows the directory and file structure thus far:

/unit-testing-using-mstest    unit-testing-using-mstest.sln    /PrimeService

MakePrimeService the current directory and rundotnet new classlib to create the source project. RenameClass1.cs toPrimeService.cs. Replace the code in the file with the following code to create a failing implementation of thePrimeService class:

using System;namespace Prime.Services{    public class PrimeService    {        public bool IsPrime(int candidate)        {            throw new NotImplementedException("Please create a test first.");        }    }}

Change the directory back to theunit-testing-using-mstest directory. Rundotnet sln add to add the class library project to the solution:

dotnet sln add PrimeService/PrimeService.csproj

Create the test project

Create thePrimeService.Tests directory. The following outline shows the directory structure:

/unit-testing-using-mstest    unit-testing-using-mstest.sln    /PrimeService        Source Files        PrimeService.csproj    /PrimeService.Tests

Make thePrimeService.Tests directory the current directory and create a new project usingdotnet new mstest. The dotnet new command creates a test project that uses MSTest as the test library. The template configures the test runner in thePrimeServiceTests.csproj file:

<ItemGroup>  <PackageReference Include="MSTest" Version="3.2.0" />  <PackageReference Include="Microsoft.Testing.Extensions.CodeCoverage" Version="17.10.1" /></ItemGroup>

The test project requires other packages to create and run unit tests.dotnet new in the previous step added the necessary MSTest packages and tools for code coverage reporting.

Add thePrimeService class library as another dependency to the project. Use thedotnet reference add command:

dotnet reference add ../PrimeService/PrimeService.csproj

You can see the entire file in thesamples repository on GitHub.

The following outline shows the final solution layout:

/unit-testing-using-mstest    unit-testing-using-mstest.sln    /PrimeService        Source Files        PrimeService.csproj    /PrimeService.Tests        Test Source Files        PrimeServiceTests.csproj

Change to theunit-testing-using-mstest directory, and rundotnet sln add:

dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj

Create the first test

Write a failing test, make it pass, then repeat the process. RemoveUnitTest1.cs from thePrimeService.Tests directory and create a new C# file namedPrimeService_IsPrimeShould.cs with the following content:

using Microsoft.VisualStudio.TestTools.UnitTesting;using Prime.Services;namespace Prime.UnitTests.Services{    [TestClass]    public class PrimeService_IsPrimeShould    {        private readonly PrimeService _primeService;        public PrimeService_IsPrimeShould()        {            _primeService = new PrimeService();        }        [TestMethod]        public void IsPrime_InputIs1_ReturnFalse()        {            bool result = _primeService.IsPrime(1);            Assert.IsFalse(result, "1 should not be prime");        }    }}

TheTestClass attribute denotes a class that contains unit tests. TheTestMethod attribute indicates a method is a test method.

Save this file and executedotnet test to build the tests and the class library and then run the tests. The MSTest test runner contains the program entry point to run your tests.dotnet test starts the test runner using the unit test project you've created.

Your test fails. You haven't created the implementation yet. Make this test pass by writing the simplest code in thePrimeService class that works:

public bool IsPrime(int candidate){    if (candidate == 1)    {        return false;    }    throw new NotImplementedException("Please create a test first.");}

In theunit-testing-using-mstest directory, rundotnet test again. Thedotnet test command runs a build for thePrimeService project and then for thePrimeService.Tests project. After building both projects, it runs this single test. It passes.

Add more features

Now that you've made one test pass, it's time to write more. There are a few other simple cases for prime numbers: 0, -1. You could add new tests with theTestMethod attribute, but that quickly becomes tedious. There are other MSTest attributes that enable you to write a suite of similar tests. A test method can execute the same code but have different input arguments. You can use theDataRow attribute to specify values for those inputs.

Instead of creating new tests, apply these two attributes to create a single data driven test. The data driven test is a method that tests several values less than two, which is the lowest prime number. Add a new test method inPrimeService_IsPrimeShould.cs:

[TestMethod][DataRow(-1)][DataRow(0)][DataRow(1)]public void IsPrime_ValuesLessThan2_ReturnFalse(int value){    var result = _primeService.IsPrime(value);    Assert.IsFalse(result, $"{value} should not be prime");}

Rundotnet test, and two of these tests fail. To make all of the tests pass, change theif clause at the beginning of theIsPrime method in thePrimeService.cs file:

if (candidate < 2)

Continue to iterate by adding more tests, more theories, and more code in the main library. You have thefinished version of the tests and thecomplete implementation of the library.

You've built a small library and a set of unit tests for that library. You've structured the solution so that adding new packages and tests is part of the normal workflow. You've concentrated most of your time and effort on solving the goals of the application.

See also

Collaborate with us on GitHub
The source for this content can be found on GitHub, where you can also create and review issues and pull requests. For more information, seeour contributor guide.

Feedback

Was this page helpful?

YesNo

In this article

Was this page helpful?

YesNo