or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

content.mdhelpers.mdindex.mdmatchers.mdtest-cases.mdtest-execution.mdtest-results.mdtwisted-support.md

matchers.mddocs/

0

# Matchers System

1

2

Sophisticated assertion system with 46 matchers for complex comparisons and validations. Matchers provide a composable, expressive way to specify test expectations beyond simple equality checks.

3

4

## Capabilities

5

6

### Core Matcher Infrastructure

7

8

Base classes and exceptions for the matcher system.

9

10

```python { .api }

11

class Matcher:

12

"""

13

Abstract base class for all matchers.

14

15

Defines the protocol that all matchers must implement

16

for composable assertion logic.

17

"""

18

19

def match(self, other):

20

"""

21

Try to match other with this matcher.

22

23

Args:

24

other: Object to match against

25

26

Returns:

27

None if match succeeds, Mismatch object if it fails

28

"""

29

30

def describe(self):

31

"""

32

Describe what this matcher matches.

33

34

Returns:

35

str: Human-readable description

36

"""

37

38

class Mismatch:

39

"""

40

Represents a matcher mismatch with detailed description.

41

"""

42

43

def __init__(self, description):

44

"""

45

Create a mismatch.

46

47

Args:

48

description (str): Description of the mismatch

49

"""

50

51

def describe(self):

52

"""

53

Get the mismatch description.

54

55

Returns:

56

str: Detailed mismatch information

57

"""

58

59

class MismatchError(Exception):

60

"""

61

Exception raised when matcher assertion fails.

62

"""

63

```

64

65

### Basic Value Matchers

66

67

Fundamental matchers for comparing values, strings, and basic data types.

68

69

```python { .api }

70

def Equals(expected):

71

"""

72

Match if objects are equal using == operator.

73

74

Args:

75

expected: Expected value

76

77

Returns:

78

Matcher: Equality matcher

79

"""

80

81

def NotEquals(expected):

82

"""

83

Match if objects are not equal using != operator.

84

85

Args:

86

expected: Value that should not match

87

88

Returns:

89

Matcher: Inequality matcher

90

"""

91

92

def Is(expected):

93

"""

94

Match using identity comparison (is operator).

95

96

Args:

97

expected: Expected object identity

98

99

Returns:

100

Matcher: Identity matcher

101

"""

102

103

def IsInstance(class_or_tuple):

104

"""

105

Match if object is instance of specified type(s).

106

107

Args:

108

class_or_tuple: Class or tuple of classes

109

110

Returns:

111

Matcher: Instance type matcher

112

"""

113

114

def Contains(contained):

115

"""

116

Match if object contains specified item.

117

118

Args:

119

contained: Item that should be contained

120

121

Returns:

122

Matcher: Containment matcher

123

"""

124

125

def StartsWith(expected):

126

"""

127

Match if string starts with specified substring.

128

129

Args:

130

expected (str): Expected prefix

131

132

Returns:

133

Matcher: String prefix matcher

134

"""

135

136

def EndsWith(expected):

137

"""

138

Match if string ends with specified substring.

139

140

Args:

141

expected (str): Expected suffix

142

143

Returns:

144

Matcher: String suffix matcher

145

"""

146

147

def MatchesRegex(pattern, flags=0):

148

"""

149

Match string against regular expression pattern.

150

151

Args:

152

pattern (str): Regular expression pattern

153

flags (int): Regex flags (re.IGNORECASE, etc.)

154

155

Returns:

156

Matcher: Regular expression matcher

157

"""

158

159

def GreaterThan(expected):

160

"""

161

Match if value is greater than expected value.

162

163

Args:

164

expected: Value to compare against

165

166

Returns:

167

Matcher: Greater than comparison matcher

168

"""

169

170

def LessThan(expected):

171

"""

172

Match if value is less than expected value.

173

174

Args:

175

expected: Value to compare against

176

177

Returns:

178

Matcher: Less than comparison matcher

179

"""

180

181

def HasLength(expected):

182

"""

183

Match if object has expected length.

184

185

Args:

186

expected (int): Expected length

187

188

Returns:

189

Matcher: Length matcher

190

"""

191

192

def SameMembers(expected):

193

"""

194

Match if iterables have same members regardless of order.

195

196

Args:

197

expected: Iterable with expected members

198

199

Returns:

200

Matcher: Set membership matcher

201

"""

202

```

203

204

### Data Structure Matchers

205

206

Matchers for complex data structures like lists, dictionaries, and objects.

207

208

```python { .api }

209

def MatchesDict(d):

210

"""

211

Match dictionary structure with value matchers.

212

213

Args:

214

d (dict): Dictionary mapping keys to matchers

215

216

Returns:

217

Matcher: Dictionary structure matcher

218

"""

219

220

def ContainsDict(d):

221

"""

222

Match if dictionary contains expected key-value pairs.

223

224

Args:

225

d (dict): Expected key-value pairs

226

227

Returns:

228

Matcher: Dictionary containment matcher

229

"""

230

231

def ContainedByDict(d):

232

"""

233

Match if dictionary is contained within another dictionary.

234

235

Args:

236

d (dict): Container dictionary

237

238

Returns:

239

Matcher: Dictionary containment checker

240

"""

241

242

def KeysEqual(expected):

243

"""

244

Match if dictionary keys equal expected set of keys.

245

246

Args:

247

expected: Expected keys (iterable)

248

249

Returns:

250

Matcher: Dictionary keys matcher

251

"""

252

253

def MatchesListwise(matchers):

254

"""

255

Match lists element by element with corresponding matchers.

256

257

Args:

258

matchers (list): List of matchers for each element

259

260

Returns:

261

Matcher: Element-wise list matcher

262

"""

263

264

def MatchesSetwise(matchers):

265

"""

266

Match sets ignoring order with corresponding matchers.

267

268

Args:

269

matchers: Iterable of matchers

270

271

Returns:

272

Matcher: Unordered set matcher

273

"""

274

275

def MatchesStructure(**kwargs):

276

"""

277

Match object attributes against specified matchers.

278

279

Args:

280

**kwargs: Attribute names mapped to matchers

281

282

Returns:

283

Matcher: Object structure matcher

284

"""

285

286

def ContainsAll(items):

287

"""

288

Match if object contains all specified items.

289

290

Args:

291

items: Iterable of items that should be contained

292

293

Returns:

294

Matcher: Multiple containment matcher

295

"""

296

```

297

298

### Exception Matchers

299

300

Matchers for testing exception behavior and error conditions.

301

302

```python { .api }

303

def Raises(exception_matcher):

304

"""

305

Match if callable raises expected exception.

306

307

Args:

308

exception_matcher: Matcher for the expected exception

309

310

Returns:

311

Matcher: Exception raising matcher

312

"""

313

314

def MatchesException(exception, value_re=None):

315

"""

316

Match exception instances or types with optional attribute matching.

317

318

Args:

319

exception: Exception class or instance to match

320

value_re (str): Optional regex for exception message

321

322

Returns:

323

Matcher: Exception matcher

324

"""

325

326

def raises(exception_matcher):

327

"""

328

Context manager version of Raises matcher.

329

330

Args:

331

exception_matcher: Matcher for expected exception

332

333

Returns:

334

Context manager for exception testing

335

"""

336

```

337

338

### Filesystem Matchers

339

340

Matchers for filesystem operations and file content verification.

341

342

```python { .api }

343

def PathExists():

344

"""

345

Match if filesystem path exists.

346

347

Returns:

348

Matcher: Path existence matcher

349

"""

350

351

def FileExists():

352

"""

353

Match if path exists and is a regular file.

354

355

Returns:

356

Matcher: File existence matcher

357

"""

358

359

def DirExists():

360

"""

361

Match if path exists and is a directory.

362

363

Returns:

364

Matcher: Directory existence matcher

365

"""

366

367

def FileContains(matcher):

368

"""

369

Match file contents against expected content.

370

371

Args:

372

matcher: Matcher for file contents

373

374

Returns:

375

Matcher: File content matcher

376

"""

377

378

def DirContains(filenames):

379

"""

380

Match if directory contains specified files.

381

382

Args:

383

filenames: Expected filenames (iterable)

384

385

Returns:

386

Matcher: Directory content matcher

387

"""

388

389

def HasPermissions(expected):

390

"""

391

Match file permissions against expected permissions.

392

393

Args:

394

expected: Expected permission bits

395

396

Returns:

397

Matcher: File permissions matcher

398

"""

399

400

def SamePath(expected):

401

"""

402

Match if paths refer to the same filesystem location.

403

404

Args:

405

expected: Expected path

406

407

Returns:

408

Matcher: Path equivalence matcher

409

"""

410

411

def TarballContains(filenames):

412

"""

413

Match contents of tarball archives.

414

415

Args:

416

filenames: Expected filenames in tarball

417

418

Returns:

419

Matcher: Tarball content matcher

420

"""

421

```

422

423

### Higher-Order Matchers

424

425

Matcher combinators for building complex matching logic.

426

427

```python { .api }

428

def MatchesAll(*matchers):

429

"""

430

Match against multiple matchers (logical AND).

431

432

Args:

433

*matchers: Matchers that must all succeed

434

435

Returns:

436

Matcher: Conjunction matcher

437

"""

438

439

def MatchesAny(*matchers):

440

"""

441

Match against any of multiple matchers (logical OR).

442

443

Args:

444

*matchers: Matchers, at least one must succeed

445

446

Returns:

447

Matcher: Disjunction matcher

448

"""

449

450

def Not(matcher):

451

"""

452

Negate/invert the result of another matcher.

453

454

Args:

455

matcher: Matcher to negate

456

457

Returns:

458

Matcher: Negated matcher

459

"""

460

461

def AllMatch(matcher):

462

"""

463

Match if all items in iterable match the given matcher.

464

465

Args:

466

matcher: Matcher to apply to each item

467

468

Returns:

469

Matcher: Universal quantification matcher

470

"""

471

472

def AnyMatch(matcher):

473

"""

474

Match if any item in iterable matches the given matcher.

475

476

Args:

477

matcher: Matcher to apply to items

478

479

Returns:

480

Matcher: Existential quantification matcher

481

"""

482

483

def AfterPreprocessing(preprocessor, matcher):

484

"""

485

Apply preprocessing function before matching.

486

487

Args:

488

preprocessor: Function to transform input

489

matcher: Matcher to apply to transformed data

490

491

Returns:

492

Matcher: Preprocessing matcher

493

"""

494

495

def Annotate(annotation, matcher):

496

"""

497

Add annotation/description to existing matcher.

498

499

Args:

500

annotation (str): Additional description

501

matcher: Matcher to annotate

502

503

Returns:

504

Matcher: Annotated matcher

505

"""

506

507

def MatchesPredicate(predicate, message=None):

508

"""

509

Match using predicate function.

510

511

Args:

512

predicate: Function returning bool

513

message (str): Optional description

514

515

Returns:

516

Matcher: Predicate-based matcher

517

"""

518

519

def MatchesPredicateWithParams(predicate, message=None, **params):

520

"""

521

Match using predicate function with additional parameters.

522

523

Args:

524

predicate: Function accepting value and params

525

message (str): Optional description

526

**params: Additional parameters for predicate

527

528

Returns:

529

Matcher: Parameterized predicate matcher

530

"""

531

```

532

533

### Constant Matchers

534

535

Matchers with fixed behavior for testing and composition.

536

537

```python { .api }

538

def Always():

539

"""

540

Matcher that always succeeds (never fails).

541

542

Returns:

543

Matcher: Always-succeeding matcher

544

"""

545

546

def Never():

547

"""

548

Matcher that never succeeds (always fails).

549

550

Returns:

551

Matcher: Always-failing matcher

552

"""

553

```

554

555

### DocTest Integration

556

557

Matcher for integrating with Python's doctest module.

558

559

```python { .api }

560

def DocTestMatches(expected, flags=0):

561

"""

562

Match string against doctest expected output format.

563

564

Args:

565

expected (str): Expected doctest output

566

flags (int): Doctest option flags

567

568

Returns:

569

Matcher: DocTest output matcher

570

"""

571

```

572

573

### Warning System Matchers

574

575

Matchers for testing warning emissions and deprecation behavior.

576

577

```python { .api }

578

def Warnings(matchers):

579

"""

580

Match warnings emitted during code execution.

581

582

Args:

583

matchers: Matchers for expected warnings

584

585

Returns:

586

Matcher: Warning emission matcher

587

"""

588

589

def WarningMessage(category=None, message=None, filename=None, lineno=None):

590

"""

591

Match specific warning message details.

592

593

Args:

594

category: Warning category class

595

message: Warning message matcher

596

filename: Source filename matcher

597

lineno: Line number matcher

598

599

Returns:

600

Matcher: Warning message matcher

601

"""

602

603

def IsDeprecated():

604

"""

605

Match deprecated functionality warnings.

606

607

Returns:

608

Matcher: Deprecation warning matcher

609

"""

610

```

611

612

## Usage Examples

613

614

### Basic Matcher Usage

615

616

```python

617

import testtools

618

from testtools.matchers import *

619

620

class TestMatchers(testtools.TestCase):

621

622

def test_basic_matchers(self):

623

# String matchers

624

self.assertThat("Hello World", Contains("World"))

625

self.assertThat("test.py", EndsWith(".py"))

626

self.assertThat("function_name", MatchesRegex(r'\w+_\w+'))

627

628

# Numeric matchers

629

self.assertThat(42, GreaterThan(40))

630

self.assertThat([1, 2, 3], HasLength(3))

631

632

# Type matchers

633

self.assertThat([], IsInstance(list))

634

self.assertThat("test", Not(IsInstance(int)))

635

```

636

637

### Complex Data Structure Matching

638

639

```python

640

def test_complex_structures(self):

641

data = {

642

'users': [

643

{'name': 'Alice', 'age': 30},

644

{'name': 'Bob', 'age': 25}

645

],

646

'status': 'active',

647

'count': 2

648

}

649

650

# Match dictionary structure

651

self.assertThat(data, MatchesDict({

652

'users': HasLength(2),

653

'status': Equals('active'),

654

'count': GreaterThan(0)

655

}))

656

657

# Match list elements

658

self.assertThat(data['users'], MatchesListwise([

659

MatchesDict({'name': StartsWith('A'), 'age': GreaterThan(25)}),

660

MatchesDict({'name': StartsWith('B'), 'age': LessThan(30)})

661

]))

662

```

663

664

### Exception Testing

665

666

```python

667

def test_exceptions(self):

668

# Test specific exception

669

self.assertThat(

670

lambda: int('not_a_number'),

671

Raises(MatchesException(ValueError))

672

)

673

674

# Test exception message

675

with raises(MatchesException(ValueError, "invalid literal.*")):

676

int('not_a_number')

677

```

678

679

### Filesystem Testing

680

681

```python

682

def test_filesystem(self):

683

# Test file operations

684

self.assertThat('/etc/passwd', FileExists())

685

self.assertThat('/tmp', DirExists())

686

self.assertThat('config.txt', FileContains(Contains('version')))

687

```

688

689

### Combining Matchers

690

691

```python

692

def test_matcher_combinations(self):

693

# Logical combinations

694

self.assertThat(42, MatchesAll(

695

GreaterThan(40),

696

LessThan(50),

697

IsInstance(int)

698

))

699

700

# Check all list items

701

numbers = [2, 4, 6, 8]

702

self.assertThat(numbers, AllMatch(

703

MatchesAll(IsInstance(int), lambda x: x % 2 == 0)

704

))

705

706

# Preprocessing

707

self.assertThat(" trimmed ", AfterPreprocessing(

708

str.strip,

709

Equals("trimmed")

710

))

711

```