C#: testing values and exceptions with a small harness

A unit test calls a small piece of code with chosen input and checks the output or the error. Frameworks such as xUnit, NUnit, and MSTest do this at scale. The core is small: a function that compares an expected value with an actual one and reports the result.

C#
using System;

class Program {
  static int failures = 0;

  static int Percent(string text) {
    int value = int.Parse(text);
    if (value < 0 || value > 100) {
      throw new ArgumentOutOfRangeException("text", "percent out of range");
    }
    return value;
  }

  static void AssertEqual(string name, int expected, int actual) {
    if (expected == actual) {
      Console.WriteLine("PASS " + name);
    } else {
      failures++;
      Console.WriteLine("FAIL " + name + ": expected " + expected + " but was " + actual);
    }
  }

  static void AssertThrows<T>(string name, Action code) where T : Exception {
    try {
      code();
      failures++;
      Console.WriteLine("FAIL " + name + ": nothing was thrown");
    } catch (T) {
      Console.WriteLine("PASS " + name);
    }
  }

  static void Main() {
    AssertEqual("parses 42", 42, Percent("42"));
    AssertEqual("parses 0", 0, Percent("0"));
    AssertThrows<ArgumentOutOfRangeException>("rejects 101", () => Percent("101"));
    AssertThrows<FormatException>("rejects text", () => Percent("abc"));
    Console.WriteLine("failures: " + failures);
  }
}
Read the full lesson