Lesson Sunday

Let's create a Leap Year program that uses the TDD workflow and automated MSTest tests. We'll set up our first test in this lesson.

Practicing TDD with Leap Year


Project Structure - Code

Create a Models subdirectory in the Calendar project. Add LeapYear.cs inside the Models directory. Our project structure looks like this:

Calendar.Solution
├── Calendar
│   ├── Calendar.csproj
│   ├── Models
│   │   └── LeapYear.cs
│   └── obj
│       └── (omitted for brevity)
└── Calendar.Tests
    ├── Calendar.Tests.csproj
    └── obj
        └── (omitted for brevity)

We'll start with the following code:

Calendar/Models/LeapYear.cs
namespace Calendar
{
  public class LeapYear
  {
    public bool IsLeapYear(int year)
    {
      // logic will go here
      return false;
    }
  }
}
  • We place our logic in the Calendar namespace.

  • We create a class called LeapYear that contains the method IsLeapYear(), which returns a bool.

  • For now, the method simply returns false. Remember, we must identify a behavior and write a corresponding test before adding any application logic. We simply return false as a placeholder so the application can compile properly. If our method returned nothing, we'd receive errors because the method has declared it will return a bool.

Project Structure - Tests

Let’s set up our test file. We'll create a new directory called ModelTests within the existing Calendar.Solution/Calendar.Tests directory. Add a LeapYearTest.cs file to this directory. Our directory structure now looks like this:

Calendar.Solution
├── Calendar
│   ├── Calendar.csproj
│   ├── Models
│   │   └── LeapYear.cs
│   └── obj
│        └── (omitted for brevity)
└── Calendar.Tests
    ├── Calendar.Tests.csproj
    ├── ModelTests
    │   └── LeapYearTests.cs
    └── obj
        └── (omitted for brevity)

In this file, we'll place the following:

Calendar.Tests/ModelTests/LeapYearTests.cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Calendar;

namespace Calendar.Tests
{
  [TestClass]
  public class LeapYearTests
  {
    [TestMethod]
    // Test method will go here
  }
}
  • using Microsoft.VisualStudio.TestTools.UnitTesting imports the MSTest framework that we installed with the $ dotnet restore command.

  • using Calendar; imports the Calendar namespace from the Calendar project for use in our tests.

  • [TestClass] tells MSTest that the following class contains tests to be run.

  • [TestMethod] tells the compiler that the following code block is an individual test that MSTest will run.

Writing Test Methods

Now we can write our first test. Let's add a new method declaration:

Calendar.Tests/ModelTests/LeapYearTests.cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Calendar;

namespace Calendar.Tests
{
  [TestClass]
  public class LeapYearTests
  {
    [TestMethod]
    public void IsLeapYear_NumberDivisibleByFour_True()
    {
      //testing code will go here
    }
  }
}

We declare our test method with the line public void IsLeapYear_NumberDivisibleByFour_True(). MSTest tests are actually methods! Also, they always begin with public void. They are public, which allows the tools running our tests to access them. We add void because they don't explicitly return anything.

The naming convention used above is public void NameOfMethodWeAreTesting_DescriptionOfBehavior_ExpectedReturnValue(). You can read more about the naming convention here.

  • We call our test method IsLeapYear_NumberDivisibleByFour_True because IsLeapYear() will be our method's name.
  • NumberDivisibleByFour is the behavior this first test will test.
  • True is the expected return value.

Running Tests

Even though our new test method doesn't contain logic yet, let's try running it to ensure we don't receive compiler errors. We'll navigate to the Calendar.Tests project in the command line and run the following command:

$ dotnet test

If everything is set up correctly, we'll see something like this:

Build started, please wait...
Build completed.

Test run for /Users/epicodus_student/Desktop/Calendar.Solution/Calendar.Tests/bin/Debug/net5.0/Calendar.Tests.dll(.net,Version=v5.0)
Microsoft (R) Test Execution Command Line Tool Version 15.0.0.0
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...

Total tests: 1. Passed: 1. Failed: 0. Skipped: 0.
Test Run Successful.
Test execution time: 1.1577 Seconds

We see 1 total test, and 1 test passed. Our test isn't actually testing anything yet. The test passes because it threw no errors for the test runner to consider a failure.

Now that we've confirmed everything is configured correctly, we'll start writing more tests in the next lesson.

Sample Test


using Microsoft.VisualStudio.TestTools.UnitTesting;
using Class_Name;

namespace Class_Name.Tests
{
  [TestClass]
  public class Class_Name_Tests
  {
    [TestMethod]
    public void Test_Name()
    {
      //testing code will go here
    }
  }
}

Run tests with the following command:

$ dotnet test

Lesson 6 of 20
Last updated April 14, 2022