# Adding Test Classes

Add an MSTest test project beside your app, give it a reference to the app, and add a test class for each class you test.

Apprentice · Unit Testing · C# · Updated November 3, 2026

## After this lesson you can

- Add an MSTest test project to a solution, with a reference to the project it tests
- Write a test class with \[TestClass\] and \[TestMethod\], and run it

## Key takeaways

- `dotnet new mstest -n TvRemote.Tests` makes a test project, and `dotnet add TvRemote.Tests reference TvRemote` lets its tests see the app's classes.
- `[TestClass]` marks a class that holds tests, and `[TestMethod]` marks a `public void` method that is one test.
- A method without `[TestMethod]`, or one that isn't `public`, isn't run as a test.
- Test Explorer finds tests only after the solution builds, so build it when the list is empty.

Here's the `Television` class from *Planning Unit Tests*, in a console app named **TvRemote**:

```csharp
namespace TvRemote;

public class Television
{
    public const int LowestChannel = 3;
    public const int HighestChannel = 15;

    public bool IsOn { get; private set; }
    public int CurrentChannel { get; private set; } = LowestChannel;

    public void TurnOn()
    {
        IsOn = true;
    }

    public void TurnOff()
    {
        IsOn = false;
    }

    // Goes up one channel, from the highest back to the lowest, and returns the new channel.
    // While the TV is off, nothing changes.
    public int ChannelUp()
    {
        if (IsOn)
        {
            CurrentChannel = CurrentChannel == HighestChannel ? LowestChannel : CurrentChannel + 1;
        }
        return CurrentChannel;
    }

    // Changes to the channel, if the TV is on and the channel exists. Returns whether it changed.
    public bool ChangeChannel(int channel)
    {
        if (!IsOn || channel < LowestChannel || channel > HighestChannel)
        {
            return false;
        }
        CurrentChannel = channel;
        return true;
    }
}
```

## Add a test project

From the folder that holds `TvRemote`:

```bash
dotnet new mstest -n TvRemote.Tests
dotnet add TvRemote.Tests reference TvRemote
dotnet new sln -n TvRemote
dotnet sln add TvRemote TvRemote.Tests
```

| Command | Does |
|---|---|
| `dotnet new mstest` | Makes a test project with the MSTest package |
| `dotnet add ... reference` | Lets the tests see the app's classes |
| `dotnet new sln`, `dotnet sln add` | Puts both projects in one solution, so Visual Studio opens them together |

In Visual Studio: right-click the solution in **Solution Explorer**, **Add > New Project...**, choose **MSTest Test Project**, and name it `TvRemote.Tests`. Then right-click the test project's **Dependencies**, **Add Project Reference...**, and check **TvRemote**.

The test project's `.csproj` lists the MSTest package, the reference, and one handy line: a global `using`, so every test file can use MSTest's names without its own `using` line:

```xml
<ItemGroup>
  <PackageReference Include="MSTest" Version="4.0.2" />
</ItemGroup>

<ItemGroup>
  <Using Include="Microsoft.VisualStudio.TestTools.UnitTesting" />
</ItemGroup>

<ItemGroup>
  <ProjectReference Include="..\TvRemote\TvRemote.csproj" />
</ItemGroup>
```

(The template also adds `Test1.cs`, an empty example: delete it.)

## Add a test class

Add `TelevisionTests.cs` to the test project:

```csharp
namespace TvRemote.Tests;

[TestClass]
public class TelevisionTests
{
    [TestMethod]
    public void ChannelUp_WhenOn_GoesUpOneChannel()
    {
        Television tv = new Television();
        tv.TurnOn();

        int newChannel = tv.ChannelUp();

        Assert.AreEqual(4, newChannel);
    }
}
```

Two **attributes**, in square brackets, tell the test runner what to run:

- **`[TestClass]`** marks a class that holds tests.
- **`[TestMethod]`** marks a method that is one test. It's `public` and returns `void`. (It takes no parameters, unless it gets them from `[DataRow]`, which *Writing Tests* shows.)

Methods without `[TestMethod]` are ordinary helpers: the runner doesn't run them as tests.

`Television` needs no `using`: the test class's namespace, `TvRemote.Tests`, is inside `TvRemote`, so C# finds `TvRemote.Television` by itself.

## Run it

Run **Test > Run All Tests** in Visual Studio, or in the terminal:

```bash
dotnet test
```

```text
Passed!  - Failed:     0, Passed:     1, Skipped:     0, Total:     1, Duration: 31 ms - TvRemote.Tests.dll (net10.0)
```

**Test Explorer** lists every test with a green check or a red cross. Double-click one to jump to its code, or right-click it to run just that test.

## Common problems

| What you see | What to do |
|---|---|
| `The type or namespace name 'Television' could not be found` | The test project has no reference to the app. Add it: `dotnet add TvRemote.Tests reference TvRemote`. |
| Test Explorer is empty | Build the solution (**Ctrl+Shift+B**) so the runner can find the tests, and check the class has `[TestClass]`. |
| A test you wrote isn't run | It's missing `[TestMethod]`, or it isn't `public`. |

## Check yourself

2 questions to try on the lesson page.

## So what

One command makes a test project, one more connects it to your app, and two attributes turn a class into tests. From here on, every class you write can have tests beside it.

## Key terms

- [Test Project](https://www.ask-codey.com/glossary/test-project)
- [\[TestClass\] and \[TestMethod\]](https://www.ask-codey.com/glossary/testclass-and-testmethod)
- [Attribute](https://www.ask-codey.com/glossary/attribute-c-sharp)

## Cheat sheets

- [Adding Test Classes](https://www.ask-codey.com/cheat-sheets/unit-testing-with-mstest-adding-test-classes-cheat-sheet)

Source: https://www.ask-codey.com/lessons/unit-testing-with-mstest-adding-test-classes
