or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application.mdasync-io.mdauth.mddistributed.mddns.mdemail.mdhttp.mdindex.mdlogging.mdprotocols.mdssh.mdtesting.md

testing.mddocs/

0

# Testing Framework

1

2

Comprehensive unit testing framework with asynchronous test support and specialized test runners. Twisted Trial extends Python's unittest with Deferred support, making it ideal for testing asynchronous code.

3

4

## Capabilities

5

6

### Test Cases

7

8

Base test case classes with support for asynchronous operations and Twisted-specific testing patterns.

9

10

```python { .api }

11

class trial.unittest.TestCase:

12

"""

13

Asynchronous-capable test case for testing Twisted code.

14

Extends unittest.TestCase with Deferred support.

15

16

Attributes:

17

- timeout: Default test timeout in seconds

18

"""

19

timeout = 120.0

20

21

def setUp(self):

22

"""

23

Set up test fixture. Can return Deferred for async setup.

24

25

Returns:

26

None or Deferred: Completion indicator

27

"""

28

29

def tearDown(self):

30

"""

31

Clean up test fixture. Can return Deferred for async cleanup.

32

33

Returns:

34

None or Deferred: Completion indicator

35

"""

36

37

def addCleanup(self, function, *args, **kwargs):

38

"""

39

Add cleanup function to run after test.

40

41

Args:

42

function: Cleanup function

43

*args, **kwargs: Arguments for function

44

"""

45

46

def doCleanups(self):

47

"""

48

Run all registered cleanup functions.

49

50

Returns:

51

None or Deferred: Completion indicator

52

"""

53

54

def assertFailure(self, deferred, *expectedFailures):

55

"""

56

Assert that a Deferred will fail with specific exception types.

57

58

Args:

59

deferred (Deferred): Deferred to test

60

*expectedFailures: Expected exception types

61

62

Returns:

63

Deferred[Failure]: Fires with failure when deferred fails

64

"""

65

66

def successResultOf(self, deferred):

67

"""

68

Get successful result of already-fired Deferred.

69

70

Args:

71

deferred (Deferred): Deferred that should have succeeded

72

73

Returns:

74

Result value of the Deferred

75

"""

76

77

def failureResultOf(self, deferred, *expectedFailures):

78

"""

79

Get failure result of already-failed Deferred.

80

81

Args:

82

deferred (Deferred): Deferred that should have failed

83

*expectedFailures: Expected exception types

84

85

Returns:

86

Failure: The failure

87

"""

88

89

def assertNoResult(self, deferred):

90

"""

91

Assert that Deferred has not yet fired.

92

93

Args:

94

deferred (Deferred): Deferred to check

95

"""

96

97

class trial.unittest.SynchronousTestCase:

98

"""

99

Synchronous test case that cannot handle Deferreds.

100

Use for tests that don't involve any asynchronous operations.

101

Faster than TestCase but cannot return Deferreds from test methods.

102

"""

103

def setUp(self):

104

"""Set up test fixture synchronously."""

105

106

def tearDown(self):

107

"""Clean up test fixture synchronously."""

108

109

# Test decorators and markers

110

class trial.unittest.Todo:

111

"""

112

Mark a test as expected to fail (todo item).

113

"""

114

def __init__(self, reason, errors=None):

115

"""

116

Args:

117

reason (str): Reason for expected failure

118

errors: Expected error types

119

"""

120

121

def trial.unittest.skip(reason):

122

"""

123

Skip a test with given reason.

124

125

Args:

126

reason (str): Skip reason

127

128

Returns:

129

Decorator function

130

"""

131

132

def trial.unittest.skipIf(condition, reason):

133

"""

134

Skip test if condition is true.

135

136

Args:

137

condition (bool): Skip condition

138

reason (str): Skip reason

139

140

Returns:

141

Decorator function

142

"""

143

144

class trial.unittest.SkipTest(Exception):

145

"""

146

Exception raised to skip a test.

147

"""

148

149

class trial.unittest.FailTest(Exception):

150

"""

151

Exception raised to fail a test.

152

"""

153

```

154

155

**Test Case Usage Example**:

156

157

```python

158

from twisted.trial import unittest

159

from twisted.internet import defer, reactor, task

160

161

class AsyncTestCase(unittest.TestCase):

162

163

def setUp(self):

164

# Async setup

165

self.service = MyService()

166

return self.service.start()

167

168

def tearDown(self):

169

# Async cleanup

170

return self.service.stop()

171

172

def test_async_operation(self):

173

"""Test that returns a Deferred."""

174

d = self.service.processData("test")

175

d.addCallback(self.assertEqual, "expected_result")

176

return d

177

178

def test_failure_case(self):

179

"""Test expected failure."""

180

d = self.service.badOperation()

181

return self.assertFailure(d, ValueError, TypeError)

182

183

@defer.inlineCallbacks

184

def test_inline_callbacks(self):

185

"""Test using inlineCallbacks for cleaner async code."""

186

result1 = yield self.service.step1()

187

result2 = yield self.service.step2(result1)

188

self.assertEqual(result2, "expected")

189

190

def test_synchronous_result(self):

191

"""Test already-completed Deferred."""

192

d = defer.succeed("immediate")

193

result = self.successResultOf(d)

194

self.assertEqual(result, "immediate")

195

196

class SyncTestCase(unittest.SynchronousTestCase):

197

198

def test_pure_sync(self):

199

"""Test that doesn't involve any async operations."""

200

result = self.service.sync_method()

201

self.assertEqual(result, "expected")

202

```

203

204

### Test Suites and Discovery

205

206

Test suite management and test discovery mechanisms.

207

208

```python { .api }

209

class trial.unittest.TestSuite:

210

"""

211

Container for multiple test cases.

212

"""

213

def __init__(self, tests=()):

214

"""

215

Args:

216

tests: Sequence of test cases

217

"""

218

219

def addTest(self, test):

220

"""

221

Add a test to the suite.

222

223

Args:

224

test: Test case or suite to add

225

"""

226

227

def addTests(self, tests):

228

"""

229

Add multiple tests to the suite.

230

231

Args:

232

tests: Sequence of tests to add

233

"""

234

235

def countTestCases(self):

236

"""

237

Count total number of test cases.

238

239

Returns:

240

int: Number of test cases

241

"""

242

243

class runner.TestLoader:

244

"""

245

Test discovery and loading.

246

"""

247

def loadTestsFromTestCase(self, testCaseClass):

248

"""

249

Load tests from a test case class.

250

251

Args:

252

testCaseClass: Test case class

253

254

Returns:

255

TestSuite: Suite containing tests

256

"""

257

258

def loadTestsFromModule(self, module):

259

"""

260

Load tests from a module.

261

262

Args:

263

module: Python module containing tests

264

265

Returns:

266

TestSuite: Suite containing tests

267

"""

268

269

def loadTestsFromName(self, name):

270

"""

271

Load tests from dotted name.

272

273

Args:

274

name (str): Dotted test name

275

276

Returns:

277

TestSuite: Suite containing tests

278

"""

279

280

def unittest.decorate(testClass, classDecorator):

281

"""

282

Apply decorator to all test methods in a class.

283

284

Args:

285

testClass: Test case class

286

classDecorator: Decorator function

287

288

Returns:

289

Decorated test class

290

"""

291

```

292

293

### Test Runners

294

295

Test execution engines with various output formats and reporting options.

296

297

```python { .api }

298

class runner.TrialRunner:

299

"""

300

Main test runner for executing trial tests.

301

302

Attributes:

303

- stream: Output stream for results

304

- tbformat: Traceback format ('default', 'brief', 'verbose')

305

- args: Command line arguments

306

"""

307

stream = None

308

tbformat = 'default'

309

310

def __init__(self, reporterFactory, mode=None, logfile='-', stream=None, profile=False, tracebackFormat='default', realTimeErrors=False, uncleanWarnings=False, workingDirectory=None, tests=None):

311

"""

312

Args:

313

reporterFactory: Factory for creating result reporters

314

mode: Test mode ('debug', etc.)

315

logfile: Path for log output

316

stream: Output stream

317

profile: Whether to enable profiling

318

tracebackFormat: Format for tracebacks

319

realTimeErrors: Show errors in real time

320

uncleanWarnings: Show cleanup warnings

321

workingDirectory: Working directory for tests

322

tests: Test suite to run

323

"""

324

325

def run(self, test):

326

"""

327

Run tests with this runner.

328

329

Args:

330

test: Test case or suite to run

331

332

Returns:

333

TestResult: Test execution results

334

"""

335

336

class runner.LoggedSuite:

337

"""

338

Test suite that logs test execution.

339

"""

340

def __init__(self, tests=(), logfile=None):

341

"""

342

Args:

343

tests: Test cases to include

344

logfile: File for logging output

345

"""

346

```

347

348

### Test Reporters

349

350

Result reporting and output formatting for test runs.

351

352

```python { .api }

353

class reporter.TestResult:

354

"""

355

Test result collector and reporter base class.

356

357

Attributes:

358

- successes: Number of successful tests

359

- errors: List of test errors

360

- failures: List of test failures

361

- skips: List of skipped tests

362

- expectedFailures: List of expected failures

363

- unexpectedSuccesses: List of unexpected successes

364

"""

365

successes = 0

366

errors = None

367

failures = None

368

skips = None

369

expectedFailures = None

370

unexpectedSuccesses = None

371

372

def startTest(self, test):

373

"""

374

Called when test starts.

375

376

Args:

377

test: Test case being started

378

"""

379

380

def stopTest(self, test):

381

"""

382

Called when test ends.

383

384

Args:

385

test: Test case that ended

386

"""

387

388

def addError(self, test, error):

389

"""

390

Add test error.

391

392

Args:

393

test: Test case

394

error: Error tuple (type, value, traceback)

395

"""

396

397

def addFailure(self, test, failure):

398

"""

399

Add test failure.

400

401

Args:

402

test: Test case

403

failure: Failure tuple (type, value, traceback)

404

"""

405

406

def addSuccess(self, test):

407

"""

408

Add successful test.

409

410

Args:

411

test: Test case

412

"""

413

414

def addSkip(self, test, reason):

415

"""

416

Add skipped test.

417

418

Args:

419

test: Test case

420

reason (str): Skip reason

421

"""

422

423

class reporter.TreeReporter:

424

"""

425

Tree-style test reporter showing hierarchical test structure.

426

"""

427

def __init__(self, stream, tbformat='default', realtime=False, publisher=None):

428

"""

429

Args:

430

stream: Output stream

431

tbformat (str): Traceback format

432

realtime (bool): Show results in real time

433

publisher: Log publisher

434

"""

435

436

class reporter.VerboseTextReporter:

437

"""

438

Verbose text reporter with detailed output.

439

"""

440

def __init__(self, stream, tbformat='default', realtime=False, publisher=None):

441

"""

442

Args:

443

stream: Output stream

444

tbformat (str): Traceback format

445

realtime (bool): Show results in real time

446

publisher: Log publisher

447

"""

448

449

class reporter.MinimalReporter:

450

"""

451

Minimal test reporter with concise output.

452

"""

453

def __init__(self, stream, tbformat='default', realtime=False, publisher=None):

454

"""

455

Args:

456

stream: Output stream

457

tbformat (str): Traceback format

458

realtime (bool): Show results in real time

459

publisher: Log publisher

460

"""

461

462

class reporter.TimingTextReporter:

463

"""

464

Text reporter that includes timing information.

465

"""

466

def __init__(self, stream, tbformat='default', realtime=False, publisher=None):

467

"""

468

Args:

469

stream: Output stream

470

tbformat (str): Traceback format

471

realtime (bool): Show results in real time

472

publisher: Log publisher

473

"""

474

475

class reporter.SubunitReporter:

476

"""

477

Reporter that outputs results in Subunit format.

478

"""

479

def __init__(self, stream, tbformat='default', realtime=False, publisher=None):

480

"""

481

Args:

482

stream: Output stream

483

tbformat (str): Traceback format

484

realtime (bool): Show results in real time

485

publisher: Log publisher

486

"""

487

```

488

489

### Testing Utilities

490

491

Helper functions and utilities for writing and running tests.

492

493

```python { .api }

494

class util.TestCase:

495

"""Additional testing utilities."""

496

497

def patch(self, obj, attribute, value):

498

"""

499

Patch an object attribute for the duration of the test.

500

501

Args:

502

obj: Object to patch

503

attribute (str): Attribute name

504

value: New attribute value

505

"""

506

507

def mktemp(self):

508

"""

509

Create a temporary file path unique to this test.

510

511

Returns:

512

str: Temporary file path

513

"""

514

515

def util.suppress(action=None, *suppressedWarnings):

516

"""

517

Context manager/decorator to suppress warnings during tests.

518

519

Args:

520

action: Warning action ('ignore', 'error', etc.)

521

*suppressedWarnings: Warning categories to suppress

522

"""

523

524

def util.acquireAttribute(objects, attr, default=None):

525

"""

526

Get attribute from first object that has it.

527

528

Args:

529

objects: Sequence of objects to check

530

attr (str): Attribute name

531

default: Default value if not found

532

533

Returns:

534

Attribute value or default

535

"""

536

537

# Test constants

538

util.DEFAULT_TIMEOUT_DURATION = 120.0 # Default test timeout

539

```

540

541

**Testing Utilities Example**:

542

543

```python

544

from twisted.trial import unittest, util

545

546

class UtilityTestCase(unittest.TestCase):

547

548

def setUp(self):

549

self.temp_file = self.mktemp() # Unique temp file path

550

self.original_value = MyClass.class_attribute

551

552

def test_with_patch(self):

553

# Temporarily patch an attribute

554

self.patch(MyClass, 'class_attribute', 'test_value')

555

self.assertEqual(MyClass.class_attribute, 'test_value')

556

# Attribute restored automatically after test

557

558

@util.suppress('ignore', DeprecationWarning)

559

def test_with_suppressed_warnings(self):

560

# This test won't show deprecation warnings

561

deprecated_function()

562

563

def tearDown(self):

564

# Clean up temp file if created

565

if os.path.exists(self.temp_file):

566

os.unlink(self.temp_file)

567

```

568

569

### Mock Objects and Test Doubles

570

571

Utilities for creating mock objects and test doubles in Twisted tests.

572

573

```python { .api }

574

class proto_helpers.StringTransport:

575

"""

576

Transport that stores written data in memory for testing.

577

578

Attributes:

579

- value: Data written to transport (bytes)

580

- disconnected: Whether transport is disconnected

581

"""

582

value = b''

583

disconnected = False

584

585

def write(self, data):

586

"""

587

Write data to in-memory buffer.

588

589

Args:

590

data (bytes): Data to write

591

"""

592

593

def writeSequence(self, data):

594

"""

595

Write sequence of data chunks.

596

597

Args:

598

data: Sequence of bytes objects

599

"""

600

601

def loseConnection(self):

602

"""Mark transport as disconnected."""

603

604

def clear(self):

605

"""Clear stored data."""

606

607

def value(self):

608

"""

609

Get all written data.

610

611

Returns:

612

bytes: All data written to transport

613

"""

614

615

class proto_helpers.StringTransportWithDisconnection:

616

"""

617

StringTransport that notifies protocol of disconnection.

618

"""

619

620

def loseConnection(self):

621

"""Disconnect and notify protocol."""

622

623

class proto_helpers.AccumulatingProtocol:

624

"""

625

Protocol that accumulates all received data.

626

627

Attributes:

628

- data: All received data (bytes)

629

- transport: Connected transport

630

"""

631

data = b''

632

transport = None

633

634

def dataReceived(self, data):

635

"""

636

Accumulate received data.

637

638

Args:

639

data (bytes): Received data

640

"""

641

```

642

643

**Protocol Testing Example**:

644

645

```python

646

from twisted.trial import unittest

647

from twisted.test import proto_helpers

648

649

class ProtocolTestCase(unittest.TestCase):

650

651

def setUp(self):

652

self.protocol = MyProtocol()

653

self.transport = proto_helpers.StringTransport()

654

self.protocol.makeConnection(self.transport)

655

656

def test_data_handling(self):

657

# Send data to protocol

658

self.protocol.dataReceived(b"test data")

659

660

# Check what protocol wrote back

661

sent_data = self.transport.value()

662

self.assertEqual(sent_data, b"expected response")

663

664

def test_disconnection(self):

665

# Test protocol disconnection

666

self.transport.loseConnection()

667

self.assertTrue(self.transport.disconnected)

668

669

# Protocol should handle disconnection gracefully

670

self.assertFalse(self.protocol.connected)

671

```

672

673

### Required Imports

674

675

Complete import statements for testing with Twisted Trial:

676

677

```python

678

# Core testing framework

679

from twisted.trial import unittest, runner, reporter

680

from twisted.trial.unittest import TestCase, SynchronousTestCase

681

from twisted.python.failure import Failure

682

from twisted.internet import defer

683

684

# Test decorators and utilities

685

from twisted.trial.unittest import skip, skipIf, Todo, SkipTest

686

from twisted.test import proto_helpers # For StringTransport

687

688

# Common patterns

689

from twisted.trial.unittest import TestCase as TrialTestCase

690

from twisted.internet.defer import succeed, fail, inlineCallbacks, returnValue

691

692

# Running tests

693

# Command line: trial mypackage.test.test_module

694

# In code: trial.unittest.main()

695

```