0
# Matchers and Assertions
1
2
ScalaTest provides a powerful matcher system that enables readable test code and informative failure messages. The matcher system includes basic assertions, should/must matchers, and specialized matchers for different data types.
3
4
## Capabilities
5
6
### Basic Assertions
7
8
Core assertion methods available in all test suites.
9
10
```scala { .api }
11
trait Assertions {
12
/**
13
* Assert that a condition is true
14
*/
15
def assert(condition: Boolean): Assertion
16
def assert(condition: Boolean, clue: Any): Assertion
17
18
/**
19
* Assume a condition (will cancel the test if false rather than fail)
20
*/
21
def assume(condition: Boolean): Assertion
22
def assume(condition: Boolean, clue: Any): Assertion
23
24
/**
25
* Force test failure with optional message
26
*/
27
def fail(): Nothing
28
def fail(message: String): Nothing
29
def fail(message: String, cause: Throwable): Nothing
30
31
/**
32
* Mark test as pending
33
*/
34
def pending: Assertion with PendingStatement
35
def pending(message: String): Assertion with PendingStatement
36
37
/**
38
* Cancel test execution with optional message
39
*/
40
def cancel(): Nothing
41
def cancel(message: String): Nothing
42
def cancel(message: String, cause: Throwable): Nothing
43
44
/**
45
* Assert that a code block throws a specific exception
46
*/
47
def intercept[T <: AnyRef](f: => Any)(implicit classTag: ClassTag[T]): T
48
49
/**
50
* Assert that a code block throws an exception of any type
51
*/
52
def assertThrows[T <: AnyRef](f: => Any)(implicit classTag: ClassTag[T]): Assertion
53
54
/**
55
* Assert that a code block compiles successfully
56
*/
57
def assertCompiles(code: String): Assertion
58
59
/**
60
* Assert that a code block does not compile
61
*/
62
def assertDoesNotCompile(code: String): Assertion
63
64
/**
65
* Assert that a code block produces a type error
66
*/
67
def assertTypeError(code: String): Assertion
68
69
/**
70
* Add a clue to any assertion for better error messages
71
*/
72
def withClue[T](clue: Any)(fun: => T): T
73
}
74
```
75
76
**Usage Examples:**
77
78
```scala
79
// Basic assertions
80
assert(2 + 2 == 4)
81
assert(2 + 2 == 4, "Basic math should work")
82
83
// Exception testing
84
val exception = intercept[IllegalArgumentException] {
85
throw new IllegalArgumentException("Invalid argument")
86
}
87
assert(exception.getMessage == "Invalid argument")
88
89
// Pending tests
90
pending // Mark test as pending
91
92
// Compile-time assertions (macros)
93
assertCompiles("val x: Int = 42")
94
assertDoesNotCompile("val x: String = 42")
95
assertTypeError("val x: String = 42")
96
97
// Enhanced error messages with clues
98
withClue("When testing user registration:") {
99
user.name should not be empty
100
user.email should include ("@")
101
}
102
```
103
104
### Should Matchers
105
106
Expressive matchers using "should" syntax.
107
108
```scala { .api }
109
trait Matchers extends Assertions {
110
/**
111
* Equality matcher
112
*/
113
def equal(right: Any): Matcher[Any]
114
115
/**
116
* Identity matcher (checks object identity, not equality)
117
*/
118
def be(right: Any): Matcher[Any]
119
120
/**
121
* Greater than matcher
122
*/
123
def be(resultOfGreaterThanComparison: ResultOfGreaterThanComparison[_]): Matcher[Any]
124
125
/**
126
* Less than matcher
127
*/
128
def be(resultOfLessThanComparison: ResultOfLessThanComparison[_]): Matcher[Any]
129
130
/**
131
* Collection/string containment matcher
132
*/
133
def contain(element: Any): Matcher[Any]
134
135
/**
136
* String containment matchers
137
*/
138
def startWith(right: String): Matcher[String]
139
def endWith(right: String): Matcher[String]
140
def include(substring: String): Matcher[String]
141
142
/**
143
* Size/length matchers
144
*/
145
def have(resultOfLengthWordApplication: ResultOfLengthWordApplication): Matcher[Any]
146
def have(resultOfSizeWordApplication: ResultOfSizeWordApplication): Matcher[Any]
147
148
/**
149
* Type checking matchers
150
*/
151
def be(aType: ResultOfATypeInvocation[_]): Matcher[Any]
152
def be(anType: ResultOfAnTypeInvocation[_]): Matcher[Any]
153
154
/**
155
* Pattern matching matcher
156
*/
157
def matchPattern(right: PartialFunction[Any, _]): Matcher[Any]
158
}
159
160
/**
161
* Implicit conversion to enable should syntax on any value
162
*/
163
implicit class Shouldable[T](leftSideValue: T) {
164
def should(rightMatcherX1: Matcher[T]): Assertion
165
def should(beWord: BeWord): ResultOfBeWordForAny[T]
166
def should(notExist: NotExist.type): Assertion
167
def should(exist: Exist.type): Assertion
168
}
169
```
170
171
**Usage Examples:**
172
173
```scala
174
import org.scalatest.matchers.should.Matchers
175
176
// Equality matchers
177
result should equal (42)
178
result should === (42) // Shorthand for equal
179
result should be (42)
180
181
// Comparison matchers
182
result should be > 10
183
result should be < 100
184
result should be >= 10
185
result should be <= 100
186
187
// String matchers
188
message should include ("error")
189
message should startWith ("Error:")
190
message should endWith ("failed")
191
message should fullyMatch regex "\\d+".r
192
193
// Collection matchers
194
list should contain (3)
195
list should contain oneOf (1, 2, 3)
196
list should contain allOf (1, 2, 3)
197
list should have length 3
198
list should have size 3
199
list should be (empty)
200
list should not be empty
201
202
// Type matchers
203
obj should be a [String]
204
obj should be an [IllegalArgumentException]
205
206
// Property matchers
207
obj should have (
208
Symbol("name") ("John"),
209
Symbol("age") (25)
210
)
211
```
212
213
### Must Matchers
214
215
Alternative syntax using "must" instead of "should".
216
217
```scala { .api }
218
/**
219
* Implicit conversion to enable must syntax on any value
220
*/
221
implicit class Mustable[T](leftSideValue: T) {
222
def must(rightMatcherX1: Matcher[T]): Assertion
223
def must(beWord: BeWord): ResultOfBeWordForAny[T]
224
def must(notExist: NotExist.type): Assertion
225
def must(exist: Exist.type): Assertion
226
}
227
```
228
229
**Usage Examples:**
230
231
```scala
232
import org.scalatest.matchers.must.Matchers
233
234
result must equal (42)
235
result must be > 10
236
message must include ("error")
237
list must contain (3)
238
list must have length 3
239
```
240
241
### Custom Matchers
242
243
Creating custom matchers for domain-specific testing.
244
245
```scala { .api }
246
trait Matcher[-T] extends (T => MatchResult) {
247
def apply(left: T): MatchResult
248
249
/**
250
* Compose this matcher with another using logical AND
251
*/
252
def and[U <: T](rightMatcher: Matcher[U]): Matcher[U]
253
254
/**
255
* Compose this matcher with another using logical OR
256
*/
257
def or[U <: T](rightMatcher: Matcher[U]): Matcher[U]
258
}
259
260
case class MatchResult(
261
matches: Boolean,
262
rawFailureMessage: String,
263
rawNegatedFailureMessage: String,
264
rawMidSentenceFailureMessage: String = "",
265
rawMidSentenceNegatedFailureMessage: String = ""
266
)
267
```
268
269
**Usage Examples:**
270
271
```scala
272
// Custom matcher for even numbers
273
def beEven = Matcher { (left: Int) =>
274
MatchResult(
275
left % 2 == 0,
276
s"$left was not even",
277
s"$left was even"
278
)
279
}
280
281
// Usage
282
42 should beEven
283
43 should not be even
284
285
// Composing matchers
286
def bePositiveAndEven = be > 0 and beEven
287
288
// Custom matcher with parameters
289
def beWithinTolerance(expected: Double, tolerance: Double) =
290
Matcher { (actual: Double) =>
291
val difference = Math.abs(actual - expected)
292
MatchResult(
293
difference <= tolerance,
294
s"$actual was not within $tolerance of $expected",
295
s"$actual was within $tolerance of $expected"
296
)
297
}
298
299
// Usage
300
3.14159 should beWithinTolerance(3.14, 0.01)
301
```
302
303
### Inspectors
304
305
Matchers for collections that apply assertions to all or some elements.
306
307
```scala { .api }
308
trait Inspectors {
309
/**
310
* Assert that all elements satisfy the condition
311
*/
312
def forAll[E](xs: Iterable[E])(fun: E => Unit): Unit
313
314
/**
315
* Assert that at least one element satisfies the condition
316
*/
317
def forAtLeast(min: Int, xs: Iterable[_])(fun: Any => Unit): Unit
318
319
/**
320
* Assert that at most n elements satisfy the condition
321
*/
322
def forAtMost(max: Int, xs: Iterable[_])(fun: Any => Unit): Unit
323
324
/**
325
* Assert that exactly n elements satisfy the condition
326
*/
327
def forExactly(succeededCount: Int, xs: Iterable[_])(fun: Any => Unit): Unit
328
329
/**
330
* Assert that between min and max elements satisfy the condition
331
*/
332
def forBetween(from: Int, upTo: Int, xs: Iterable[_])(fun: Any => Unit): Unit
333
334
/**
335
* Assert that every element satisfies the condition (alias for forAll)
336
*/
337
def forEvery[E](xs: Iterable[E])(fun: E => Unit): Unit
338
}
339
```
340
341
**Usage Examples:**
342
343
```scala
344
import org.scalatest.Inspectors
345
346
val numbers = List(1, 2, 3, 4, 5)
347
348
// All elements should be positive
349
forAll(numbers) { num =>
350
num should be > 0
351
}
352
353
// At least 3 elements should be even
354
forAtLeast(2, numbers) { num =>
355
num % 2 should equal (0)
356
}
357
358
// Exactly one element should equal 3
359
forExactly(1, numbers) { num =>
360
num should equal (3)
361
}
362
```
363
364
## Matcher Types
365
366
```scala { .api }
367
/**
368
* Base matcher trait
369
*/
370
trait Matcher[-T] extends (T => MatchResult)
371
372
/**
373
* Helper words and phrases for building matcher expressions
374
*/
375
trait BeWord
376
trait HaveWord
377
trait ContainWord
378
trait ExistWord
379
trait NotExist
380
381
/**
382
* Result types for matcher expressions
383
*/
384
case class ResultOfBeWordForAny[T](left: T, shouldBeTrue: Boolean)
385
case class ResultOfLengthWordApplication(expectedLength: Long)
386
case class ResultOfSizeWordApplication(expectedSize: Long)
387
case class ResultOfGreaterThanComparison[T](right: T)
388
case class ResultOfLessThanComparison[T](right: T)
389
390
/**
391
* Type checking helpers
392
*/
393
case class ResultOfATypeInvocation[T](clazz: Class[T])
394
case class ResultOfAnTypeInvocation[T](clazz: Class[T])
395
```