# Test Case Writing Patterns Structured approaches for organizing logic within individual test cases. ## Given-When-Then (GWT) Proposed by Dan North (2006) as part of BDD. Used in Cucumber's Gherkin language. ```gherkin GIVEN that the inventory contains 10 units of steel AND the inventory contains 30 units of copper WHEN we consume 2 units of steel AND we consume 10 units of copper THEN the inventory should contain 8 units of steel AND the inventory should contain 20 units of copper ``` Best for: acceptance tests, integration tests, non-technical stakeholders. ## Arrange-Act-Assert (AAA) The most common unit test pattern. From the xUnit family. ```python def test_add_two_numbers(): # Arrange calculator = Calculator() a, b = 3, 5 # Act result = calculator.add(a, b) # Assert assert result == 8 ``` Best for: unit tests across all languages (pytest, JUnit, Jest, etc.). ## Four-Phase Test (Setup-Exercise-Verify-Teardown) Extension of AAA from Gerard Meszaros' *xUnit Test Patterns*. Adds explicit cleanup. Best for: tests with external resources (databases, files, network). ## Specification-Based (Describe-It) Used by RSpec (Ruby), Mocha (JavaScript). `context()` is a Mocha/RSpec feature; Jasmine uses nested `describe()` instead. ```javascript describe('Calculator', () => { describe('add', () => { context('with positive numbers', () => { it('returns the sum', () => { expect(new Calculator().add(2, 3)).toEqual(5); }); }); }); }); ``` Best for: hierarchically organized, readable test output. ## Table-Driven Tests Common in Go. Test cases defined as data, single function iterates. ```go func TestAdd(t *testing.T) { tests := []struct { a, b, want int }{ {1, 2, 3}, {0, 0, 0}, {-1, 1, 0}, } for _, tt := range tests { got := Add(tt.a, tt.b) if got != tt.want { t.Errorf("Add(%d, %d) = %d, want %d", tt.a, tt.b, got, tt.want) } } } ``` Best for: functions with many input/output combinations. ## Property-Based Testing Define properties that should always hold; framework generates random inputs. Pioneered by QuickCheck (Haskell). ```python from hypothesis import given import hypothesis.strategies as st @given(st.integers(), st.integers()) def test_add_is_commutative(a, b): assert add(a, b) == add(b, a) ``` Tools: Hypothesis (Python), QuickCheck (Haskell), fast-check (JS), proptest (Rust). --- See also: [[Types of Software Testing]]