Unit Testing with MSTest
50 minUnit testing is essential for code quality and maintainability, enabling you to verify that individual units of code work correctly. Unit tests are fast, isolated, and repeatable. They catch bugs early, enable refactoring with confidence, and document expected behavior. Understanding unit testing enables professional development. Unit testing is essential for reliable software.
MSTest is Microsoft's testing framework for .NET, providing attributes, assertions, and test execution infrastructure. MSTest is integrated with Visual Studio and supports parallel test execution. Test classes use [TestClass] attribute. Test methods use [TestMethod] attribute. Understanding MSTest enables writing tests. MSTest is one of several .NET testing frameworks.
Test methods are marked with [TestMethod] attribute and contain test logic with assertions. Test methods should be public, void, and parameterless. Tests follow Arrange-Act-Assert pattern: set up data, execute code, verify results. Understanding test structure enables effective testing. Test structure is important for maintainability.
Assertions verify expected behavior and outcomes, using methods like Assert.AreEqual, Assert.IsTrue, Assert.IsNull, etc. Assertions fail tests when conditions aren't met. Multiple assertions can be used in a single test. Understanding assertions enables verifying behavior. Assertions are the core of testing.
Test organization includes test classes, test methods, setup/teardown methods ([TestInitialize], [TestCleanup]), and test data. Good organization makes tests maintainable. Setup methods prepare test environment. Teardown methods clean up. Understanding test organization enables maintainable test suites. Test organization is important for large projects.
Best practices include writing tests before or alongside code (TDD), keeping tests independent, using meaningful test names, testing edge cases, and maintaining high test coverage. Understanding unit testing enables reliable, maintainable code. Unit testing is essential for professional development.
Key Concepts
- Unit testing is essential for code quality and maintainability.
- MSTest is Microsoft's testing framework for .NET.
- Test methods are marked with [TestMethod] attribute.
- Assertions verify expected behavior and outcomes.
- Tests follow Arrange-Act-Assert pattern.
Learning Objectives
Master
- Writing unit tests with MSTest
- Using test attributes and assertions
- Organizing test classes and methods
- Following testing best practices
Develop
- Test-driven development thinking
- Understanding testing strategies
- Writing maintainable test suites
Tips
- Write tests before or alongside code (TDD).
- Keep tests independent—don't rely on test execution order.
- Use meaningful test names that describe what's being tested.
- Test edge cases and error conditions.
Common Pitfalls
- Not writing tests, making refactoring risky.
- Writing tests that depend on each other.
- Not testing edge cases, missing bugs.
- Not maintaining tests, causing them to become outdated.
Summary
- Unit testing is essential for code quality.
- MSTest provides testing framework for .NET.
- Test methods verify expected behavior.
- Understanding unit testing enables reliable code.
- Unit testing is essential for professional development.
Exercise
Write unit tests for a simple calculator class using MSTest.
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
public class Calculator
{
public int Add(int a, int b) => a + b;
public int Subtract(int a, int b) => a - b;
public int Multiply(int a, int b) => a * b;
public double Divide(int a, int b)
{
if (b == 0)
throw new DivideByZeroException("Cannot divide by zero");
return (double)a / b;
}
}
[TestClass]
public class CalculatorTests
{
private Calculator _calculator;
[TestInitialize]
public void Setup()
{
_calculator = new Calculator();
}
[TestMethod]
public void Add_TwoPositiveNumbers_ReturnsCorrectSum()
{
// Arrange
int a = 5, b = 3;
// Act
int result = _calculator.Add(a, b);
// Assert
Assert.AreEqual(8, result);
}
[TestMethod]
public void Subtract_TwoNumbers_ReturnsCorrectDifference()
{
// Arrange
int a = 10, b = 4;
// Act
int result = _calculator.Subtract(a, b);
// Assert
Assert.AreEqual(6, result);
}
[TestMethod]
public void Multiply_TwoNumbers_ReturnsCorrectProduct()
{
// Arrange
int a = 6, b = 7;
// Act
int result = _calculator.Multiply(a, b);
// Assert
Assert.AreEqual(42, result);
}
[TestMethod]
public void Divide_TwoNumbers_ReturnsCorrectQuotient()
{
// Arrange
int a = 10, b = 2;
// Act
double result = _calculator.Divide(a, b);
// Assert
Assert.AreEqual(5.0, result);
}
[TestMethod]
[ExpectedException(typeof(DivideByZeroException))]
public void Divide_ByZero_ThrowsException()
{
// Arrange
int a = 10, b = 0;
// Act
_calculator.Divide(a, b);
// Assert is handled by ExpectedException
}
}
// Note: This would typically be in a separate test project
// and would require MSTest NuGet package
class Program
{
static void Main(string[] args)
{
// Manual test execution
var calculator = new Calculator();
Console.WriteLine($"5 + 3 = {calculator.Add(5, 3)}");
Console.WriteLine($"10 - 4 = {calculator.Subtract(10, 4)}");
Console.WriteLine($"6 * 7 = {calculator.Multiply(6, 7)}");
Console.WriteLine($"10 / 2 = {calculator.Divide(10, 2)}");
try
{
calculator.Divide(10, 0);
}
catch (DivideByZeroException ex)
{
Console.WriteLine($"Exception caught: {ex.Message}");
}
}
}