# 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]]