Unit testing
A unit test is a small method that calls one piece of code with known inputs and checks the result by itself. Follow one xUnit test through dotnet test: it arranges qty = 10 and price = 5, acts by calling Cart.Total, and asserts that the total is 45. A bug (qty > 10 instead of >= 10) returns 50, the Assert throws and the test goes red; after a one-character fix the same test goes green.
5 quick questions
Pick an answer to see why. Your score saves with your progress.
01How does xUnit know that BulkDiscount is a test?
The runner looks in the test project for methods marked [Fact] (or [Theory]). Each one is a test. Test projects have no Main for you to write: the runner calls the test methods.
02In Assert.Equal(45, total), which value is the expected one?
xUnit's Assert.Equal takes the expected value first and the actual value second. That is why the failure report says Expected: 45 and Actual: 50.
03Cart.Total(10, 5) returned 50. Why?
The rule says 10 or more items get 10% off, but > 10 leaves out exactly 10. So line 7 ran: 10 × 5 = 50. Edge values like 10 are where such bugs hide.
04The test is red. What is the right fix here?
The test states the rule correctly; the code breaks it. Fix the code. Changing the expected value to match a bug would hide it instead of fixing it.
05How does a test fail in xUnit?
A test passes when the method returns normally and fails when it throws. A failed Assert throws an exception that the runner catches and reports.
Glossary
- Unit test
- A small method that calls one unit of code (a method or class) with known inputs and checks the result automatically.
- Test project
- A separate project (for example Shop.Tests) that references the code under test and the test framework's NuGet packages.
- xUnit
- A popular open-source test framework for .NET. NUnit and MSTest are the other two main ones.
- [Fact]
- The xUnit attribute that marks a method as a test with no inputs.
- [Theory] / [InlineData]
- A test that runs once for each row of data; each [InlineData] attribute gives one row of arguments.
- Arrange, Act, Assert
- The three parts of a test: set up the inputs, call the code under test, check the result.
- Assertion
- A check such as Assert.Equal(expected, actual). If it does not hold, it throws and the test fails.
- dotnet test
- The .NET CLI command that builds a test project, runs its tests and prints the results.
Notes and sources
- .NET has three main test frameworks with Microsoft Learn guides: xUnit, NUnit and MSTest. The ideas here (a test project, test methods marked by an attribute, Arrange-Act-Assert) are the same in all three; only the attribute names differ.
- dotnet new xunit makes the test project. It brings the xunit, xunit.runner.visualstudio and Microsoft.NET.Test.Sdk packages from NuGet and a global using for Xunit, which is why CartTests.cs needs no using line. dotnet add reference connects it to Shop.
- xUnit creates a new instance of the test class for every test, so tests do not share fields by accident.
- The console is shortened. The real dotnet test output also shows the build, the test file and line, timing and Skipped/Total counts, and its exact layout depends on the SDK version and test platform.
- Microsoft's best practices suggest test names that say what is tested, the scenario and the expected result, for example Total_TenItems_GetsTenPercentOff. The short name here keeps the card readable.
- The code is real C#: put Cart.cs in a classlib project (Shop) and CartTests.cs in an xunit project (Shop.Tests) that references it. dotnet test reports 1 failed with ">" and 1 passed with ">=".
- Microsoft Learn: Unit testing C# with xUnit and dotnet test
- Microsoft Learn: Unit testing best practices for .NET
- Microsoft Learn: Testing in .NET
- Microsoft Learn: dotnet test
- Microsoft Learn: .NET default templates for dotnet new
- Microsoft Learn: dotnet add reference
- Microsoft Learn: Arithmetic operators (integer division)
- Microsoft Learn: Comparison operators
- xUnit.net: Shared context between tests (a new test class instance per test)
Quiz Unlocks after the last step.