Automation Testing · Unit & API Tests

Unit Testing with xUnit

Unit tests are the base of the pyramid: fast checks of small pieces of logic. xUnit is the most popular .NET framework.

Intermediate 5 min Lesson 12 of 24
Before you start:C#: Methods
0/24 in Automation Testing
On this page · 5 min · Intermediate

Learning objectives#

  • Write [Fact] and [Theory] tests
  • Structure tests with Arrange-Act-Assert
  • Test edge cases and exceptions
  • Run tests and read results

Explanation#

[Fact] is a single test; [Theory] with [InlineData] runs the same test with several inputs.

Arrange the inputs, Act by calling the method, Assert the outcome — one behaviour per test.

Test edges and errors: Assert.Throws<ArgumentException>(() => …).

Name tests by behaviour: Method_Scenario_ExpectedResult.

Code example: Testing a price calculator#

C#PriceCalculatorTests.cs Illustrative
public static class PriceCalculator
{
    public static decimal Total(decimal subtotal, string? coupon)
    {
        if (subtotal < 0) throw new ArgumentOutOfRangeException(nameof(subtotal));
        var discount = coupon == "SAVE10" ? subtotal * 0.10m : 0m;
        var delivery = subtotal - discount >= 999 ? 0m : 49m;
        return subtotal - discount + delivery;
    }
}


public class PriceCalculatorTests
{
    [Theory]
    [InlineData(500, null, 549)]        // below free-delivery threshold
    [InlineData(999, null, 999)]        // exactly at threshold
    [InlineData(1000, "SAVE10", 949)]   // 900 after discount → delivery charged
    [InlineData(2000, "SAVE10", 1800)]
    public void Total_applies_coupon_and_delivery(decimal subtotal, string? coupon, decimal expected)
        => Assert.Equal(expected, PriceCalculator.Total(subtotal, coupon));


    [Fact]
    public void Total_negative_subtotal_throws()
        => Assert.Throws<ArgumentOutOfRangeException>(() => PriceCalculator.Total(-1, null));
}
Expected output
Passed!  - Failed: 0, Passed: 5, Skipped: 0, Total: 5, Duration: 21 ms

This example is illustrative. Copy or download it and run it in your own environment; the expected output is shown above.

Step-by-step explanation#

  1. The Theory runs four data rows, including boundaries.
  2. Each row asserts one expected total.
  3. The Fact checks invalid input throws.
  4. Five tests run in about 20 ms.

Real-world use case#

Pricing rules are fully covered by fast unit tests, so UI tests only check one purchase journey.

Common mistakes#

Testing many behaviours in one test

Failures become hard to diagnose. One behaviour per test.

Unit tests that hit the database

Those are integration tests. Keep unit tests in memory.

Best practices#

  • Arrange-Act-Assert
  • Theories for data variations
  • Cover boundaries and errors
  • Descriptive test names

Remember this#

[Fact] = one case. [Theory] = many cases.

Arrange · Act · Assert.

Fast, isolated, deterministic.

Practice exercise#

Your task: Add a test row proving an unknown coupon gives no discount.

Show solution
C# Illustrative
[InlineData(2000, "BOGUS", 2000)]

Mini quiz#

Unit Testing with xUnit quizMultiple choice Question 1 of 1

Which attribute runs a test with several data rows?

Score so far: 0/0

Want more? Practise all Automation Testing MCQs · Automation Testing interview questions

My notes#

Saved in this browser.

Progress is saved in this browser. Sign in to sync.