Skip to content

Commit 879b737

Browse files
author
Maciej Gomolka
committed
Add new post
1 parent eaa43a2 commit 879b737

3 files changed

Lines changed: 122 additions & 0 deletions

File tree

47.5 KB
Loading
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
---
2+
title: '3 Ways to Name Parameters in Swift Parametrised Tests'
3+
date: 2024-04-24
4+
tags: ['Swift', 'Swift Testing', 'Testing', 'unit testing']
5+
cover:
6+
image: 'images/cover.png'
7+
alt: '3 Ways to Name Parameters in Swift Parametrised Tests'
8+
---
9+
10+
## Option 1: First Named Tuples
11+
Only the first tuple is named, all others rely on positional matching to (a, b, result).
12+
13+
- ✅ Minimal boilerplate for small input sets
14+
- ❌ Readability drops after adding more cases
15+
- ❌ Easy to mix up arguments position
16+
- ❌ Hard to scan or extend
17+
18+
```swift
19+
func add(_ a: Int, _ b: Int) -> Int {
20+
a + b
21+
}
22+
23+
...
24+
25+
@Test(arguments: [
26+
(a: 1, b: 2, result: 3),
27+
(10, 15, 25),
28+
(1, -5, -4),
29+
(-1, -5, -6),
30+
(0, 0, 0),
31+
(1000, 1000, 2000),
32+
(10000, 50000, 60000),
33+
(-10, -3, -13)
34+
])
35+
func add_returnsCorrectSum(a: Int, b: Int, result: Int) {
36+
#expect(add(a, b) == result)
37+
}
38+
```
39+
40+
## Option 2: Named Tuples
41+
42+
Every tuple entry explicitly names all its fields (a: ..., b: ..., result: ...) for all cases.
43+
44+
- ✅ Clear - no guessing which value is which
45+
- ✅ Easy to reorder or remove individual cases
46+
- ❌ More repetitive boilerplate per line
47+
- ❌ Becomes long and repetitive with many cases
48+
49+
```swift
50+
@Test(arguments: [
51+
(a: 1, b: 2, result: 3),
52+
(a: 10, b: 15, result: 25),
53+
(a: 1, b: -5, result: -4),
54+
(a: -1, b: -5, result: -6),
55+
(a: 0, b: 0, result: 0),
56+
(a: 1000, b: 1000, result: 2000),
57+
(a: 10000, b: 50000, result: 60000),
58+
(a: -10, b: -3, result: -13)
59+
])
60+
func add_returnsCorrectSum(a: Int, b: Int, result: Int) {
61+
#expect(add(a, b) == result)
62+
}
63+
```
64+
65+
## Option 3: Struct
66+
67+
Use a TestCase struct and pass it to @Test
68+
- ✅ Perfect separation of data vs testing logic
69+
- ✅ Great readability and maintainability
70+
- ✅ Unlimited scalability
71+
- ✅ IDE driven field suggestions
72+
- ❌ More upfront work (struct definition)
73+
- ❌ Might be overkill for 2-3 test cases
74+
75+
```swift
76+
struct TestCase {
77+
let a: Int
78+
let b: Int
79+
let result: Int
80+
81+
static var all: [TestCase] {
82+
[
83+
.init(a: 1, b: 2, result: 3),
84+
.init(a: 10, b: 15, result: 25),
85+
.init(a: 1, b: -5, result: -4),
86+
.init(a: -1, b: -5, result: -6),
87+
.init(a: 0, b: 0, result: 0),
88+
.init(a: 1000, b: 1000, result: 2000),
89+
.init(a: 10000, b: 50000, result: 60000),
90+
.init(a: -10, b: -3, result: -13)
91+
]
92+
}
93+
}
94+
95+
@Test(arguments: TestCase.all)
96+
func add_returnsCorrectSum(testCase: TestCase) {
97+
#expect(add(testCase.a, testCase.b) == testCase.result)
98+
}
99+
```
100+
101+
## Options Comparison
102+
103+
| Criteria | Option 1: First Named Tuple | Option 2: Named Tuples | Option 3: Struct |
104+
|---------------------------|-----------------------------|------------------------|-----------------------|
105+
| **Readability** | Poor (at scale) | High | Highest |
106+
| **Scalability** | Poor | Fair | Excellent |
107+
| **Boilerplate** | Low | Medium | Medium (upfront) |
108+
| **Test arguments number** | 3 | 3 | 1 |
109+
110+
## My final advice
111+
112+
113+
**No One-Size-Fits-All**
114+
115+
No single strategy works for every test suite. Evaluate pros and cons of each strategy and choose the one that best fit your needs.
116+
117+
Remember - Tests are not just checks, they're living documentation of your production code. Keep them super clear and don't hesitate to ask your peers for feedback.
118+
119+
PDF version ⤵️
120+
[3 Ways to Name Parameters in Swift Parametrised Tests](resources/document.pdf)
121+
122+
{{< footer >}}
Binary file not shown.

0 commit comments

Comments
 (0)