Coding Standards

Test Code Standards

Foundational

Tests are production code. We read them, maintain them, and rely on them as much as the code they cover. This is our reference for writing tests that are clear, fast, deterministic, and trustworthy: how to name them, how to structure them, what to assert, how to use test doubles, and what makes a test suite people trust. It works with Testing Strategy (what to test) and covers how to write the tests themselves.

A test suite is only useful if people trust it. Green should mean good, red should mean a real problem, and a failure message should tell you what broke. Flaky, slow, over-mocked, or unreadable tests destroy that trust. These standards keep tests an asset, not a cost. We use xUnit for .NET and the standard JS/TS test tools. The principles are the same for both.

Write the test to describe the behaviour. Make it fail for the right reason. Keep it independent of every other test.

Naming & structure

Vague, multi-behaviour, brittle [Fact] public void Test1() {
var s = new Service();
Assert.NotNull(s.Do(1)); // what behaviour?
Assert.True(s.Do(2).Ok); // unrelated case
mock.Verify(m => m.Save(), Times.Once); // implementation detail
}

The name says nothing, it tests two unrelated behaviours, it has a weak not-null assertion, and it checks how the code is implemented. When it fails you learn nothing, and any refactor breaks it.

Named, AAA, behaviour-focused [Fact] public void Onboard_WhenScreeningTimesOut_BlocksAndEscalates() {
// Arrange
screening.Setup(s => s.CheckAsync(any)).Throws<TimeoutException>();
// Act
var result = sut.Onboard(customer);
// Assert
Assert.Equal(Decision.BlockAndEscalate, result); // never Approved
}

The name states the rule, the structure is clear, and it asserts the AML-critical outcome (fail closed). It survives refactoring, and a failure tells you exactly what broke.

Assertions

Test doubles (mocks, fakes, stubs)

Determinism, speed & data

Self-review checklist

Why it matters: Tests only protect us if we trust them, and trust comes from tests that are clear, deterministic, behaviour-focused, and fast. Well-written tests document the system, catch regressions with useful messages, and give us the confidence to refactor. Poorly written ones that are flaky, over-mocked, or unreadable get ignored and give false comfort, which is worse than no tests at all.