or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

assertions-matchers.mdasync-testing.mdindex.mdscalactic-utilities.mdtest-execution.mdtest-styles.md

assertions-matchers.mddocs/

0

# Assertions and Matchers

1

2

ScalaTest provides comprehensive assertion capabilities with macro-enhanced error messages and a rich natural language matcher DSL. The framework includes both basic assertions and sophisticated matcher expressions for clear, readable test code.

3

4

## Capabilities

5

6

### Core Assertions

7

8

Basic assertion methods available in all ScalaTest suites through the `Assertions` trait.

9

10

```scala { .api }

11

import org.scalatest.Assertions

12

13

trait Assertions {

14

// Basic assertions

15

def assert(condition: Boolean)(implicit prettifier: Prettifier, pos: source.Position): Assertion

16

def assert(condition: Boolean, clue: Any)(implicit prettifier: Prettifier, pos: source.Position): Assertion

17

18

// Expected result assertions

19

def assertResult(expected: Any)(actual: Any)(implicit prettifier: Prettifier, pos: source.Position): Assertion

20

def assertResult(expected: Any, clue: Any)(actual: Any)(implicit prettifier: Prettifier, pos: source.Position): Assertion

21

22

// Exception assertions

23

def assertThrows[T <: AnyRef](code: => Any)(implicit classTag: ClassTag[T], pos: source.Position): Assertion

24

def intercept[T <: AnyRef](code: => Any)(implicit classTag[T], pos: source.Position): T

25

26

// Assumptions (skips test if false)

27

def assume(condition: Boolean)(implicit prettifier: Prettifier, pos: source.Position): Assertion

28

def assume(condition: Boolean, clue: Any)(implicit prettifier: Prettifier, pos: source.Position): Assertion

29

30

// Test control

31

def fail()(implicit pos: source.Position): Nothing

32

def fail(message: String)(implicit pos: source.Position): Nothing

33

def cancel()(implicit pos: source.Position): Nothing

34

def cancel(message: String)(implicit pos: source.Position): Nothing

35

def pending: Assertion with PendingStatement

36

37

// Contextual information

38

def withClue[T](clue: Any)(fun: => T): T

39

40

// Success value

41

val succeed: Assertion

42

}

43

```

44

45

**Basic Assertion Examples:**

46

```scala

47

import org.scalatest.funsuite.AnyFunSuite

48

49

class AssertionExamples extends AnyFunSuite {

50

test("basic assertions") {

51

assert(2 + 2 == 4)

52

assert(2 + 2 == 4, "addition should work")

53

54

assertResult(4) {

55

2 + 2

56

}

57

58

assertThrows[ArithmeticException] {

59

1 / 0

60

}

61

62

val exception = intercept[IllegalArgumentException] {

63

throw new IllegalArgumentException("test")

64

}

65

assert(exception.getMessage == "test")

66

}

67

68

test("assumptions and test control") {

69

assume(System.getProperty("env") == "test", "Only run in test environment")

70

71

// This will mark test as pending

72

pending

73

74

// Add contextual information to failures

75

withClue("When testing division") {

76

assert(10 / 2 == 5)

77

}

78

}

79

}

80

```

81

82

### Triple Equals (===)

83

84

Enhanced equality assertion with better error messages.

85

86

```scala { .api }

87

trait TripleEquals {

88

def ===(right: Any): TripleEqualsInvocation[Any]

89

def !==(right: Any): TripleEqualsInvocation[Any]

90

}

91

92

// Usage in assertions

93

assert(left === right)

94

assert(left !== right)

95

```

96

97

**Triple Equals Examples:**

98

```scala

99

test("triple equals") {

100

val list = List(1, 2, 3)

101

assert(list === List(1, 2, 3)) // Better error messages than ==

102

assert(list !== List(1, 2, 4))

103

104

val map = Map("a" -> 1, "b" -> 2)

105

assert(map === Map("a" -> 1, "b" -> 2))

106

}

107

```

108

109

### Should Matchers DSL

110

111

Natural language matcher expressions for readable test assertions.

112

113

```scala { .api }

114

import org.scalatest.matchers.should.Matchers

115

116

trait Matchers {

117

// Implicit conversion to enable "should" syntax

118

implicit def convertToAnyShouldWrapper[T](o: T): AnyShouldWrapper[T]

119

120

// Core matcher words

121

val be: BeWord

122

val not: NotWord

123

val have: HaveWord

124

val contain: ContainWord

125

val startWith: StartWithWord

126

val endWith: EndWithWord

127

val include: IncludeWord

128

val matchPattern: MatchPatternWord

129

}

130

131

// Basic equality and identity

132

value should equal(expected)

133

value should be(expected)

134

value should not equal(unexpected)

135

value should not be(unexpected)

136

137

// Comparison matchers

138

value should be > 5

139

value should be >= 5

140

value should be < 10

141

value should be <= 10

142

143

// Type matchers

144

value should be a [String]

145

value should be an [Integer]

146

147

// Boolean matchers

148

condition should be(true)

149

condition should be(false)

150

```

151

152

**Should Matcher Examples:**

153

```scala

154

import org.scalatest.flatspec.AnyFlatSpec

155

import org.scalatest.matchers.should.Matchers

156

157

class MatcherExamples extends AnyFlatSpec with Matchers {

158

"Basic matchers" should "work with equality" in {

159

val result = 2 + 2

160

result should equal(4)

161

result should be(4)

162

result should not equal(5)

163

}

164

165

"Comparison matchers" should "work with numbers" in {

166

val score = 85

167

score should be > 80

168

score should be >= 85

169

score should be < 90

170

score should be <= 85

171

}

172

173

"Type matchers" should "check types" in {

174

val value: Any = "hello"

175

value should be a [String]

176

177

val number: Any = 42

178

number should be an [Integer]

179

}

180

}

181

```

182

183

### String Matchers

184

185

Specialized matchers for string operations.

186

187

```scala { .api }

188

// String content matchers

189

string should startWith("prefix")

190

string should endWith("suffix")

191

string should include("substring")

192

string should not include("unwanted")

193

194

// Regular expression matchers

195

string should fullyMatch regex "\\d+".r

196

string should startWith regex "\\w+".r

197

string should endWith regex "\\d+".r

198

string should include regex "\\w+@\\w+".r

199

200

// Length matchers

201

string should have length 10

202

string should not have length(5)

203

```

204

205

**String Matcher Examples:**

206

```scala

207

test("string matchers") {

208

val email = "user@example.com"

209

210

email should startWith("user")

211

email should endWith(".com")

212

email should include("@")

213

email should not include("password")

214

215

email should fullyMatch regex "\\w+@\\w+\\.\\w+".r

216

email should have length 16

217

}

218

```

219

220

### Collection Matchers

221

222

Matchers for various collection operations and properties.

223

224

```scala { .api }

225

// Element presence

226

collection should contain(element)

227

collection should contain oneOf(elem1, elem2, elem3)

228

collection should contain noneOf(elem1, elem2, elem3)

229

collection should contain allOf(elem1, elem2, elem3)

230

collection should contain only(elem1, elem2, elem3)

231

collection should contain theSameElementsAs(otherCollection)

232

233

// Collection properties

234

collection should be(empty)

235

collection should not be empty

236

collection should have length 5

237

collection should have size 5

238

239

// Sequence-specific matchers

240

sequence should contain inOrder(elem1, elem2, elem3)

241

sequence should contain inOrderOnly(elem1, elem2, elem3)

242

sequence should contain theSameElementsInOrderAs(otherSequence)

243

244

// Key-value matchers (for Maps)

245

map should contain key("key")

246

map should contain value("value")

247

map should contain entry("key" -> "value")

248

```

249

250

**Collection Matcher Examples:**

251

```scala

252

test("collection matchers") {

253

val numbers = List(1, 2, 3, 4, 5)

254

255

numbers should contain(3)

256

numbers should contain oneOf(2, 7, 9)

257

numbers should contain noneOf(6, 7, 8)

258

numbers should contain allOf(1, 2, 3)

259

numbers should have length 5

260

numbers should not be empty

261

262

val fruits = List("apple", "banana", "cherry")

263

fruits should contain inOrder("apple", "banana")

264

fruits should contain only("cherry", "apple", "banana")

265

266

val scores = Map("alice" -> 85, "bob" -> 92)

267

scores should contain key("alice")

268

scores should contain value(92)

269

scores should contain entry("alice" -> 85)

270

}

271

```

272

273

### Exception Matchers

274

275

Matchers for testing exception behavior.

276

277

```scala { .api }

278

// Exception type matchers

279

a [ExceptionType] should be thrownBy { code }

280

an [ExceptionType] should be thrownBy { code }

281

noException should be thrownBy { code }

282

283

// Exception message matchers

284

the [ExceptionType] thrownBy { code } should have message "expected message"

285

the [ExceptionType] thrownBy { code } should have message that startsWith("prefix")

286

the [ExceptionType] thrownBy { code } should have message that endsWith("suffix")

287

the [ExceptionType] thrownBy { code } should have message that include("substring")

288

```

289

290

**Exception Matcher Examples:**

291

```scala

292

test("exception matchers") {

293

a [ArithmeticException] should be thrownBy {

294

10 / 0

295

}

296

297

an [IllegalArgumentException] should be thrownBy {

298

require(false, "Invalid argument")

299

}

300

301

the [IllegalArgumentException] thrownBy {

302

require(false, "Invalid argument")

303

} should have message "requirement failed: Invalid argument"

304

305

noException should be thrownBy {

306

val result = 10 / 2

307

assert(result == 5)

308

}

309

}

310

```

311

312

### Property Matchers

313

314

Matchers for object properties and custom validations.

315

316

```scala { .api }

317

// Built-in property matchers

318

object should have(

319

'property(expectedValue),

320

'anotherProperty(anotherValue)

321

)

322

323

// Length and size properties

324

collection should have length 10

325

collection should have size 10

326

327

// Custom property matchers

328

def startWith(expectedPrefix: String) = new HavePropertyMatcher[String, String] {

329

def apply(left: String) = HavePropertyMatchResult(

330

left.startsWith(expectedPrefix),

331

"prefix",

332

expectedPrefix,

333

left

334

)

335

}

336

337

string should have(startWith("Hello"))

338

```

339

340

**Property Matcher Examples:**

341

```scala

342

test("property matchers") {

343

case class Person(name: String, age: Int)

344

val person = Person("Alice", 30)

345

346

// Using symbol-based property matching

347

person should have(

348

'name("Alice"),

349

'age(30)

350

)

351

352

val list = List(1, 2, 3)

353

list should have length 3

354

list should have size 3

355

}

356

```

357

358

### Custom Matchers

359

360

Creating custom matchers for domain-specific assertions.

361

362

```scala { .api }

363

import org.scalatest.matchers.{BeMatcher, MatchResult, Matcher}

364

365

// Custom BeMatcher

366

def beEven = BeMatcher { (left: Int) =>

367

MatchResult(

368

left % 2 == 0,

369

s"$left was not even",

370

s"$left was even"

371

)

372

}

373

374

// Custom Matcher

375

def startWith(expectedStart: String) = Matcher { (left: String) =>

376

MatchResult(

377

left.startsWith(expectedStart),

378

s"""String "$left" did not start with "$expectedStart"""",

379

s"""String "$left" started with "$expectedStart""""

380

)

381

}

382

383

// Usage

384

number should beEven

385

string should startWith("Hello")

386

```

387

388

**Custom Matcher Examples:**

389

```scala

390

import org.scalatest.matchers.{BeMatcher, MatchResult}

391

392

class CustomMatcherExamples extends AnyFlatSpec with Matchers {

393

def beEven = BeMatcher { (left: Int) =>

394

MatchResult(

395

left % 2 == 0,

396

s"$left was not even",

397

s"$left was even"

398

)

399

}

400

401

def haveDigits(expectedCount: Int) = Matcher { (left: String) =>

402

val digitCount = left.count(_.isDigit)

403

MatchResult(

404

digitCount == expectedCount,

405

s"""String "$left" had $digitCount digits, not $expectedCount""",

406

s"""String "$left" had $expectedCount digits"""

407

)

408

}

409

410

"Custom matchers" should "work correctly" in {

411

4 should beEven

412

3 should not be even

413

414

"abc123def" should haveDigits(3)

415

"hello" should haveDigits(0)

416

}

417

}

418

```

419

420

### Must Matchers

421

422

Alternative matcher syntax using "must" instead of "should".

423

424

```scala { .api }

425

import org.scalatest.matchers.must.Matchers

426

427

// Same API as should matchers but with "must"

428

value must equal(expected)

429

value must be > 5

430

collection must contain("element")

431

a [Exception] must be thrownBy { code }

432

```

433

434

## Tolerance and Equality

435

436

### Numeric Tolerance

437

438

```scala { .api }

439

import org.scalatest.TolerantNumerics

440

441

// Floating point comparisons with tolerance

442

val tolerantDoubleEquality = TolerantNumerics.tolerantDoubleEquality(0.01)

443

implicit val doubleEq = tolerantDoubleEquality

444

445

3.14159 should equal(3.14 +- 0.01)

446

3.14159 should be(3.14 +- 0.01)

447

```

448

449

### Custom Equality

450

451

```scala { .api }

452

import org.scalactic.Equality

453

454

// Custom equality for case-insensitive string comparison

455

implicit val stringEq = new Equality[String] {

456

def areEqual(left: String, right: Any): Boolean =

457

right match {

458

case str: String => left.toLowerCase == str.toLowerCase

459

case _ => false

460

}

461

}

462

463

"Hello" should equal("HELLO") // Uses custom equality

464

```

465

466

## Inspector Methods

467

468

Apply matchers to all elements of collections.

469

470

```scala { .api }

471

import org.scalatest.Inspectors

472

473

// Apply matcher to all elements

474

all(collection) should be > 0

475

all(collection) should startWith("prefix")

476

477

// Apply matcher to at least one element

478

atLeast(1, collection) should be > 10

479

atMost(3, collection) should be < 5

480

exactly(2, collection) should equal("expected")

481

482

// Apply matcher to between n and m elements

483

between(2, 4, collection) should include("substring")

484

```

485

486

**Inspector Examples:**

487

```scala

488

import org.scalatest.Inspectors

489

490

test("inspector methods") {

491

val numbers = List(1, 2, 3, 4, 5)

492

all(numbers) should be > 0

493

all(numbers) should be <= 5

494

495

atLeast(1, numbers) should be > 3

496

atMost(2, numbers) should be > 4

497

exactly(1, numbers) should equal(3)

498

499

val words = List("hello", "world", "test")

500

all(words) should have length be > 3

501

}