C# Testing with MSTest In-Depth

2025/10/152 min read
bookmark this

C# Testing with MSTest In-Depth


MSTest — Test Framework

  • [TestMethod] — a test with no parameters

    [TestClass]
    public class CalculatorTests
    {
        [TestMethod]
        public void Add_TwoPositiveNumbers_ReturnsSum()
        {
            // Arrange
            var calculator = new Calculator();
    
            // Act
            int result = calculator.Add(3, 4);
    
            // Assert
            Assert.AreEqual(7, result);
        }
    }
    
  • [DataTestMethod] + [DataRow] — parameterized tests

    [TestClass]
    public class CalculatorTests
    {
        [DataTestMethod]
        [DataRow(1, 2, 3)]
        [DataRow(0, 0, 0)]
        [DataRow(-1, 1, 0)]
        [DataRow(int.MaxValue, 0, int.MaxValue)]
        public void Add_VariousInputs_ReturnsExpectedSum(int a, int b, int expected)
        {
            var calculator = new Calculator();
            int result = calculator.Add(a, b);
            Assert.AreEqual(expected, result);
        }
    }
    
  • [DynamicData] — complex or external test data

    public static IEnumerable<object[]> DiscountTestData =>
        new List<object[]>
        {
            new object[] { new Customer { OrderCount = 0, IsActive = true }, 0.00m },
            new object[] { new Customer { OrderCount = 5, IsActive = true }, 0.05m },
            new object[] { new Customer { OrderCount = 15, IsActive = true }, 0.15m },
            new object[] { new Customer { OrderCount = 15, IsActive = false }, 0.00m },
        };
    
    [TestClass]
    public class DiscountCalculatorTests
    {
        [DataTestMethod]
        [DynamicData(nameof(DiscountTestData), DynamicDataSourceType.Property)]
        public void GetDiscount_VariousCustomers_ReturnsExpectedRate(Customer customer, decimal expectedDiscount)
        {
            var calculator = new DiscountCalculator();
            decimal discount = calculator.GetDiscount(customer);
            Assert.AreEqual(expectedDiscount, discount);
        }
    }
    
  • [TestCategory] — organize tests by category

    [TestClass]
    public class EmailValidatorTests
    {
        [DataTestMethod]
        [DataRow("user@example.com", true)]
        [DataRow("user@sub.domain.com", true)]
        [DataRow("invalid", false)]
        [DataRow("@no-local.com", false)]
        [DataRow("", false)]
        [TestCategory("Validation")]
        public void IsValidEmail_VariousInputs_ReturnsExpected(string email, bool expected)
        {
            bool result = EmailValidator.IsValid(email);
            Assert.AreEqual(expected, result);
        }
    }
    

MSTest Best Practices

  • Always decorate test classes with [TestClass].
  • Use [TestInitialize] and [TestCleanup] for setup/teardown logic.
  • Prefer [DataTestMethod] and [DataRow] for parameterized tests.
  • Use [ExpectedException] for exception testing.
  • Organize tests with [TestCategory] for filtering.

References: