or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-specifications.mddsl-components.mdindex.mdintegration-features.mdmatcher-system.mdmutable-specifications.mdreporting.mdtest-execution.md

test-execution.mddocs/

0

# Test Execution and Configuration

1

2

Specs2 provides comprehensive test execution capabilities with flexible configuration options, multiple runners for different environments, and detailed control over test execution behavior.

3

4

## Core Execution

5

6

### Runner

7

8

Main execution utility for running specifications.

9

10

```scala { .api }

11

object Runner {

12

def execute(actions: Action[Unit], arguments: Arguments, exit: Boolean): Unit

13

def execute(specs: Seq[SpecificationStructure], arguments: Arguments, exit: Boolean): Unit

14

def run(specs: SpecificationStructure*): Unit

15

}

16

```

17

18

### Executor

19

20

Core execution engine that processes specification fragments using stream-based processing.

21

22

```scala { .api }

23

trait Executor {

24

def execute(env: Env): Process[Task, Fragment] => Process[Task, Fragment]

25

def execute1(env: Env): Process1[Fragment, Task[Fragment]]

26

}

27

```

28

29

The executor is responsible for:

30

- Converting fragments into executable tasks

31

- Managing parallel vs sequential execution

32

- Handling fragment dependencies and ordering

33

- Coordinating step and action execution

34

35

### DefaultExecutor

36

37

Default implementation of the Executor trait using scalaz-stream processing.

38

39

```scala { .api }

40

trait DefaultExecutor extends Executor {

41

def execute1(env: Env): Process1[Fragment, Task[Fragment]]

42

def sequencedExecution(env: Env): Process1[Fragment, Task[Fragment]]

43

def isolatedExecution(env: Env): Process1[Fragment, Task[Fragment]]

44

}

45

```

46

47

**Execution Strategies:**

48

- **Sequenced**: Examples run one after another

49

- **Isolated**: Each example runs in complete isolation

50

- **Parallel**: Examples run concurrently (default)

51

52

### Env (Environment)

53

54

Execution environment that holds configuration and resources for test execution.

55

56

```scala { .api }

57

case class Env(

58

arguments: Arguments,

59

systemLogger: Logger,

60

printers: List[Printer] = Nil,

61

statisticsRepository: StatisticsRepository = StatisticsRepository.memory,

62

random: scala.util.Random = new scala.util.Random,

63

fileSystem: FileSystem = FileSystem,

64

executionContext: ExecutionContext = ExecutionContext.global

65

) {

66

def setArguments(args: Arguments): Env

67

def setPrinters(ps: List[Printer]): Env

68

def addPrinter(p: Printer): Env

69

}

70

```

71

72

The environment provides:

73

- Execution arguments and configuration

74

- Logging infrastructure

75

- Output printers for reporting

76

- Statistics collection

77

- File system access

78

- Execution context for concurrent operations

79

80

## Fragment Execution Lifecycle

81

82

### Process-Based Execution Model

83

84

Specs2 uses scalaz-stream `Process[Task, Fragment]` for fragment processing, enabling:

85

86

- **Lazy evaluation**: Fragments are processed on-demand

87

- **Stream composition**: Fragment streams can be combined and transformed

88

- **Resource management**: Automatic cleanup of resources

89

- **Backpressure handling**: Controlled memory usage for large test suites

90

91

```scala { .api }

92

// Core execution pipeline

93

trait SpecificationExecution {

94

def executeFragments(env: Env): Process[Task, Fragment] => Process[Task, Fragment]

95

def executeBodies(env: Env): Process1[Fragment, Fragment]

96

def executeActions(env: Env): Process1[Fragment, Fragment]

97

}

98

```

99

100

### Fragment Processing Pipeline

101

102

1. **Fragment Creation**: Specification `is` method creates fragment stream

103

2. **Body Execution**: Example bodies are executed to produce results

104

3. **Action Processing**: Steps and actions are executed at appropriate times

105

4. **Result Collection**: Results are collected for reporting

106

5. **Statistics Gathering**: Execution statistics are accumulated

107

108

### Synchronization and Ordering

109

110

```scala { .api }

111

trait SpecificationStructure {

112

def fragments: Process[Task, Fragment]

113

def linked: Process[Task, Fragment]

114

def contents: Process[Task, Fragment]

115

}

116

```

117

118

**Fragment Ordering:**

119

- **Steps**: Executed immediately during fragment stream processing

120

- **Examples**: Executed according to execution strategy (parallel/sequential)

121

- **Actions**: Executed after example completion

122

- **Text/Formatting**: Processed for output formatting

123

124

**Usage Example:**

125

```scala

126

// Run a single specification

127

Runner.run(new MySpec)

128

129

// Run multiple specifications

130

Runner.run(new UserSpec, new OrderSpec, new PaymentSpec)

131

132

// Run with custom arguments

133

Runner.execute(

134

List(new IntegrationSpec),

135

Arguments(sequential = true, stopOnFail = true),

136

exit = false

137

)

138

```

139

140

## Test Runners

141

142

### ClassRunner

143

144

Runs specifications from fully qualified class names.

145

146

```scala { .api }

147

class ClassRunner {

148

def run(className: String): Unit

149

def run(className: String, arguments: Arguments): Unit

150

def run(classNames: List[String], arguments: Arguments): Unit

151

}

152

```

153

154

**Usage:**

155

```bash

156

# Command line execution

157

scala -cp "classpath" org.specs2.runner.ClassRunner com.example.UserSpec

158

159

# With arguments

160

scala -cp "classpath" org.specs2.runner.ClassRunner com.example.UserSpec -- sequential

161

```

162

163

### FilesRunner

164

165

Discovers and runs specification files from filesystem.

166

167

```scala { .api }

168

class FilesRunner {

169

def run(path: String): Unit

170

def run(path: String, pattern: String): Unit

171

def run(paths: List[String], arguments: Arguments): Unit

172

}

173

```

174

175

**Usage:**

176

```bash

177

# Run all specs in directory

178

scala -cp "classpath" org.specs2.runner.FilesRunner src/test/scala

179

180

# Run specs matching pattern

181

scala -cp "classpath" org.specs2.runner.FilesRunner src/test/scala ".*UserSpec.*"

182

```

183

184

### SbtRunner

185

186

Integration with SBT test framework.

187

188

```scala { .api }

189

class SbtRunner extends TestFramework {

190

def name: String = "specs2"

191

def fingerprints: Array[Fingerprint]

192

def runner(args: Array[String], remoteArgs: Array[String], testClassLoader: ClassLoader): Runner2

193

}

194

```

195

196

**SBT Configuration:**

197

```scala

198

// build.sbt

199

libraryDependencies += "org.specs2" %% "specs2-core" % "3.3.1" % "test"

200

testFrameworks += TestFrameworks.Specs2

201

202

// Run all tests

203

sbt test

204

205

// Run specific test

206

sbt "testOnly com.example.UserSpec"

207

208

// Run with arguments

209

sbt "testOnly * -- sequential stopOnFail"

210

```

211

212

### NotifierRunner

213

214

Integration with test framework notifiers for IDE support.

215

216

```scala { .api }

217

class NotifierRunner {

218

def run(specs: List[SpecificationStructure], notifier: EventHandler): Unit

219

def run(className: String, notifier: EventHandler): Unit

220

}

221

```

222

223

## Configuration System

224

225

### Arguments

226

227

Main configuration object controlling test execution behavior.

228

229

```scala { .api }

230

case class Arguments(

231

// Execution control

232

plan: Boolean = false,

233

skipAll: Boolean = false,

234

stopOnFail: Boolean = false,

235

sequential: Boolean = false,

236

isolated: Boolean = false,

237

threadsNb: Int = Runtime.getRuntime.availableProcessors,

238

239

// Filtering

240

include: String = "",

241

exclude: String = "",

242

243

// Output control

244

colors: Boolean = true,

245

noindent: Boolean = false,

246

showTimes: Boolean = false,

247

offset: Int = 0,

248

249

// Reporting

250

console: Boolean = true,

251

html: Boolean = false,

252

markdown: Boolean = false,

253

junitxml: Boolean = false,

254

255

// File paths

256

outdir: String = "target/specs2-reports",

257

srcdir: String = "src/test/scala"

258

)

259

```

260

261

### ArgumentsArgs

262

263

Command-line argument parsing for Arguments object.

264

265

```scala { .api }

266

trait ArgumentsArgs {

267

def parse(args: Array[String]): Arguments

268

def parseArguments(args: String*): Arguments

269

}

270

```

271

272

**Command Line Usage:**

273

```bash

274

# Basic arguments

275

--sequential # Run examples sequentially

276

--stopOnFail # Stop on first failure

277

--plan # Show execution plan only

278

--skipAll # Skip all examples

279

280

# Filtering

281

--include "unit" # Include examples tagged with "unit"

282

--exclude "slow" # Exclude examples tagged with "slow"

283

284

# Output control

285

--colors # Enable colors (default)

286

--noColors # Disable colors

287

--showTimes # Show execution times

288

--offset 2 # Indent output by 2 spaces

289

290

# Reporting formats

291

--console # Console output (default)

292

--html # Generate HTML reports

293

--markdown # Generate Markdown reports

294

--junitxml # Generate JUnit XML reports

295

296

# File paths

297

--outdir target/reports # Output directory

298

--srcdir src/test/scala # Source directory

299

```

300

301

### ArgumentsShortcuts

302

303

Convenient methods for creating common argument combinations.

304

305

```scala { .api }

306

trait ArgumentsShortcuts {

307

def sequential: Arguments

308

def isolated: Arguments

309

def stopOnFail: Arguments

310

def plan: Arguments

311

def skipAll: Arguments

312

def noColors: Arguments

313

def showTimes: Arguments

314

def html: Arguments

315

def markdown: Arguments

316

def junitxml: Arguments

317

}

318

```

319

320

**Usage in Specifications:**

321

```scala

322

class ConfiguredSpec extends Specification { def is =

323

args(sequential, stopOnFail, showTimes) ^ s2"""

324

Configured specification

325

test 1 $test1

326

test 2 $test2

327

test 3 $test3

328

"""

329

}

330

```

331

332

## Execution Control

333

334

### Execute

335

336

Execution lifecycle control and coordination.

337

338

```scala { .api }

339

trait Execute {

340

def execute[T](action: Action[T]): T

341

def execute[T](action: Action[T], timeout: FiniteDuration): T

342

def executeAll[T](actions: List[Action[T]]): List[T]

343

def executeSequentially[T](actions: List[Action[T]]): List[T]

344

def executeConcurrently[T](actions: List[Action[T]]): List[T]

345

}

346

```

347

348

### Action[T]

349

350

Monadic action type for composable operations with error handling.

351

352

```scala { .api }

353

case class Action[T](run: () => T) {

354

def map[S](f: T => S): Action[S]

355

def flatMap[S](f: T => Action[S]): Action[S]

356

def filter(p: T => Boolean): Action[T]

357

def recover(f: Throwable => T): Action[T]

358

def timeout(duration: FiniteDuration): Action[T]

359

}

360

```

361

362

**Usage Example:**

363

```scala

364

val setupAction = Action { () =>

365

Database.createTables()

366

Database.seedTestData()

367

}

368

369

val testAction = Action { () =>

370

Database.query("SELECT * FROM users") must not(beEmpty)

371

}

372

373

val cleanupAction = Action { () =>

374

Database.cleanup()

375

}

376

377

val composedAction = for {

378

_ <- setupAction

379

result <- testAction

380

_ <- cleanupAction

381

} yield result

382

```

383

384

## Specification Discovery

385

386

### SpecificationsFinder

387

388

Discovers specification classes dynamically.

389

390

```scala { .api }

391

trait SpecificationsFinder {

392

def find(pattern: String): List[String]

393

def find(classLoader: ClassLoader, pattern: String): List[String]

394

def findSpecifications(packages: List[String]): List[SpecificationStructure]

395

}

396

```

397

398

**Usage:**

399

```scala

400

val finder = new SpecificationsFinder {}

401

val specClasses = finder.find("com.example.*Spec")

402

val specifications = finder.findSpecifications(List("com.example"))

403

```

404

405

### Specification Path Discovery

406

407

Automatic discovery patterns:

408

409

```scala

410

// File-based discovery

411

val fileSpecs = FilesRunner.findSpecifications("src/test/scala")

412

413

// Package-based discovery

414

val packageSpecs = ClassRunner.findSpecifications("com.example")

415

416

// Pattern-based discovery

417

val patternSpecs = SpecificationsFinder.find(".*IntegrationSpec.*")

418

```

419

420

## Execution Modes

421

422

### Sequential Execution

423

424

Run examples one after another:

425

426

```scala

427

class SequentialSpec extends Specification { def is = sequential ^ s2"""

428

Sequential execution (examples run in order)

429

setup step $setup

430

test operation $testOp

431

verify result $verify

432

cleanup step $cleanup

433

"""

434

}

435

```

436

437

### Parallel Execution

438

439

Run examples concurrently (default):

440

441

```scala

442

class ParallelSpec extends Specification { def is = s2"""

443

Parallel execution (examples run concurrently)

444

independent test 1 $test1

445

independent test 2 $test2

446

independent test 3 $test3

447

"""

448

}

449

```

450

451

### Isolated Execution

452

453

Run each example in isolation:

454

455

```scala

456

class IsolatedSpec extends Specification { def is = isolated ^ s2"""

457

Isolated execution (examples in separate classloaders)

458

test with global state 1 $testGlobal1

459

test with global state 2 $testGlobal2

460

"""

461

}

462

```

463

464

## Filtering and Selection

465

466

### Tag-Based Filtering

467

468

Filter examples by tags:

469

470

```bash

471

# Include specific tags

472

sbt "testOnly * -- include unit,fast"

473

474

# Exclude specific tags

475

sbt "testOnly * -- exclude slow,integration"

476

477

# Complex filtering

478

sbt "testOnly * -- include unit exclude broken"

479

```

480

481

### Pattern-Based Filtering

482

483

Filter by specification or example names:

484

485

```bash

486

# Run specifications matching pattern

487

sbt "testOnly *UserSpec*"

488

489

# Run examples matching description

490

sbt "testOnly * -- ex create.*user"

491

```

492

493

### Conditional Execution

494

495

Skip examples based on conditions:

496

497

```scala

498

class ConditionalSpec extends Specification { def is = s2"""

499

Conditional execution

500

${if (System.getProperty("integration") == "true")

501

"integration test" ! integrationTest

502

else

503

"integration test (skipped)" ! skipped

504

}

505

unit test $unitTest

506

"""

507

}

508

```

509

510

## Error Handling and Recovery

511

512

### StopOnFail

513

514

Stop execution on first failure:

515

516

```scala

517

class StopOnFailSpec extends Specification { def is =

518

args(stopOnFail = true) ^ s2"""

519

Stop on fail behavior

520

test 1 (will pass) $test1

521

test 2 (will fail) $test2

522

test 3 (won't run) $test3

523

"""

524

```

525

526

### Exception Handling

527

528

Handle exceptions during execution:

529

530

```scala

531

class ExceptionHandlingSpec extends Specification { def is = s2"""

532

Exception handling

533

recoverable error $recoverableError

534

fatal error $fatalError

535

"""

536

537

def recoverableError = {

538

try {

539

riskyOperation()

540

success

541

} catch {

542

case _: RecoverableException =>

543

fallbackOperation() must beEqualTo(expected)

544

}

545

}

546

547

def fatalError = {

548

fatalOperation() must throwA[FatalException]

549

}

550

}

551

```

552

553

## Performance and Monitoring

554

555

### Execution Timing

556

557

Track execution performance:

558

559

```bash

560

# Show execution times

561

sbt "testOnly * -- showTimes"

562

563

# Show times with colors

564

sbt "testOnly * -- showTimes colors"

565

```

566

567

### Thread Configuration

568

569

Control concurrent execution:

570

571

```scala

572

// Limit concurrent threads

573

Arguments(threadsNb = 4)

574

575

// Use all available processors (default)

576

Arguments(threadsNb = Runtime.getRuntime.availableProcessors)

577

```

578

579

### Memory Management

580

581

Control memory usage during execution:

582

583

```scala

584

// Run with isolated classloaders (higher memory)

585

Arguments(isolated = true)

586

587

// Run sequentially (lower memory)

588

Arguments(sequential = true)

589

```

590

591

## Integration Patterns

592

593

### Continuous Integration

594

595

CI-friendly configuration:

596

597

```scala

598

class CISpec extends Specification { def is =

599

args(

600

stopOnFail = true, // Fail fast

601

noColors = true, // No ANSI colors

602

junitxml = true, // Generate XML reports

603

html = false // Skip HTML for CI

604

) ^ s2"""

605

CI-optimized specification

606

critical test 1 $test1

607

critical test 2 $test2

608

"""

609

```

610

611

### IDE Integration

612

613

IDE-friendly execution:

614

615

```scala

616

// IntelliJ IDEA runner support

617

@RunWith(classOf[JUnitRunner])

618

class IDESpec extends Specification { def is = s2"""

619

IDE-compatible specification

620

test 1 $test1

621

test 2 $test2

622

"""

623

}

624

```

625

626

### Build Tool Integration

627

628

Maven integration:

629

630

```xml

631

<plugin>

632

<groupId>org.scalatest</groupId>

633

<artifactId>scalatest-maven-plugin</artifactId>

634

<configuration>

635

<reportsDirectory>${project.build.directory}/surefire-reports</reportsDirectory>

636

<junitxml>.</junitxml>

637

<filereports>WDF TestSuite.txt</filereports>

638

</configuration>

639

</plugin>

640

```

641

642

## Best Practices

643

644

1. **Use appropriate execution mode**: Sequential for dependent tests, parallel for independent tests

645

2. **Configure for environment**: Different arguments for development vs CI

646

3. **Filter strategically**: Use tags and patterns for selective test execution

647

4. **Handle failures gracefully**: Use `stopOnFail` judiciously and handle exceptions properly

648

5. **Monitor performance**: Use timing information to identify slow tests

649

6. **Optimize resource usage**: Balance parallelism with available resources

650

7. **Integrate with tools**: Configure for CI/CD and IDE support

651

8. **Document execution requirements**: Clearly specify any special execution needs