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

test-execution.mddocs/

0

# Test Execution

1

2

ScalaTest provides comprehensive test execution capabilities including programmatic execution, command-line runners, build tool integration, and extensive configuration options. The framework supports parallel execution, filtering, reporting, and integration with various development environments.

3

4

## Capabilities

5

6

### Programmatic Test Execution

7

8

Execute tests directly from Scala code with full control over configuration.

9

10

```scala { .api }

11

import org.scalatest._

12

13

// Main execution entry point

14

object run {

15

def main(args: Array[String]): Unit

16

def apply(

17

suite: Suite,

18

testName: String = null,

19

configMap: ConfigMap = ConfigMap.empty,

20

color: Boolean = true,

21

durations: Boolean = false,

22

shortstacks: Boolean = false,

23

fullstacks: Boolean = false,

24

stats: Boolean = false

25

): Unit

26

}

27

28

// Suite execution methods

29

trait Suite {

30

def run(testName: Option[String], args: Args): Status

31

def execute(

32

testName: Option[String] = None,

33

configMap: ConfigMap = ConfigMap.empty,

34

color: Boolean = true,

35

durations: Boolean = false,

36

shortstacks: Boolean = false,

37

fullstacks: Boolean = false,

38

stats: Boolean = false,

39

reporter: Reporter = new StandardOutReporter,

40

stopper: Stopper = Stopper.default,

41

filter: Filter = Filter(),

42

tracker: Tracker = new Tracker,

43

chosenStyles: Set[String] = Set.empty,

44

runTestInNewInstance: Boolean = false,

45

distributor: Option[Distributor] = None,

46

summaryCounter: SummaryCounter = new SummaryCounter

47

): Status

48

}

49

```

50

51

**Programmatic Execution Examples:**

52

```scala

53

import org.scalatest._

54

import org.scalatest.funsuite.AnyFunSuite

55

56

class MySuite extends AnyFunSuite {

57

test("example test") {

58

assert(1 + 1 === 2)

59

}

60

}

61

62

// Simple execution

63

run(new MySuite)

64

65

// Execution with configuration

66

val suite = new MySuite

67

suite.execute(

68

configMap = ConfigMap("env" -> "test"),

69

color = true,

70

durations = true,

71

stats = true

72

)

73

74

// Execute specific test

75

suite.execute(testName = Some("example test"))

76

```

77

78

### Command-Line Runner

79

80

Execute tests from the command line with extensive configuration options.

81

82

```scala { .api }

83

import org.scalatest.tools._

84

85

object Runner {

86

def main(args: Array[String]): Unit

87

def run(args: Array[String]): Boolean

88

}

89

90

// Common command-line arguments:

91

// -o : StandardOutReporter

92

// -e : StandardErrReporter

93

// -f <filename> : FileReporter

94

// -u <directory> : JunitXmlReporter

95

// -h <filename> : HtmlReporter

96

// -n <tag> : Include only tests with tag

97

// -l <tag> : Exclude tests with tag

98

// -s <classname> : Run specific suite

99

// -j <classname> : Run with JUnitRunner

100

// -m <classname> : Run specific member (test)

101

// -w <package> : Wildcard package discovery

102

// -q : Suppress reminder message

103

// -S : Enable short stack traces

104

// -F : Enable full stack traces

105

// -T : Show durations

106

// -C : Disable ANSI color

107

// -D : Show all durations

108

```

109

110

**Command-Line Examples:**

111

```bash

112

# Run all tests with console output

113

scala -cp <classpath> org.scalatest.tools.Runner -o

114

115

# Run specific suite

116

scala -cp <classpath> org.scalatest.tools.Runner -s com.example.MySuite -o

117

118

# Run tests with HTML report

119

scala -cp <classpath> org.scalatest.tools.Runner -o -h reports/test-results.html

120

121

# Run tests with JUnit XML output

122

scala -cp <classpath> org.scalatest.tools.Runner -o -u target/test-reports

123

124

# Run tests with specific tags

125

scala -cp <classpath> org.scalatest.tools.Runner -n FastTest -l SlowTest -o

126

127

# Run with parallel execution and durations

128

scala -cp <classpath> org.scalatest.tools.Runner -P -T -o

129

```

130

131

### Test Configuration

132

133

Configure test execution behavior through Args and ConfigMap.

134

135

```scala { .api }

136

// Test execution arguments

137

case class Args(

138

reporter: Reporter,

139

stopper: Stopper,

140

filter: Filter,

141

configMap: ConfigMap,

142

distributor: Option[Distributor],

143

tracker: Tracker,

144

chosenStyles: Set[String],

145

runTestInNewInstance: Boolean,

146

distributedTestSorter: Option[DistributedTestSorter],

147

summaryCounter: SummaryCounter

148

)

149

150

// Configuration map for passing data to tests

151

type ConfigMap = Map[String, Any]

152

object ConfigMap {

153

def empty: ConfigMap = Map.empty

154

def apply(entries: (String, Any)*): ConfigMap = Map(entries: _*)

155

}

156

157

// Test filtering

158

class Filter(

159

tagsToInclude: Option[Set[String]] = None,

160

tagsToExclude: Set[String] = Set.empty,

161

excludeNestedSuites: Boolean = false,

162

dynaTags: DynaTags = DynaTags(Map.empty, Map.empty)

163

)

164

165

// Execution control

166

trait Stopper {

167

def stopRequested: Boolean

168

def requestStop(): Unit

169

}

170

```

171

172

**Configuration Examples:**

173

```scala

174

import org.scalatest._

175

176

// Custom configuration map

177

val config = ConfigMap(

178

"db.url" -> "jdbc:h2:mem:test",

179

"timeout" -> 30,

180

"env" -> "test"

181

)

182

183

// Custom filter - include FastTest, exclude SlowTest

184

val filter = Filter(

185

tagsToInclude = Some(Set("FastTest")),

186

tagsToExclude = Set("SlowTest")

187

)

188

189

// Custom args with configuration

190

val args = Args(

191

reporter = new StandardOutReporter,

192

stopper = Stopper.default,

193

filter = filter,

194

configMap = config,

195

distributor = None,

196

tracker = new Tracker,

197

chosenStyles = Set.empty,

198

runTestInNewInstance = false,

199

distributedTestSorter = None,

200

summaryCounter = new SummaryCounter

201

)

202

203

// Use configuration in test

204

class ConfigurableTest extends AnyFunSuite {

205

test("uses configuration") {

206

val dbUrl = testOptions.configMap.getOrElse("db.url", "default-url")

207

assert(dbUrl === "jdbc:h2:mem:test")

208

}

209

}

210

```

211

212

### Test Reporters

213

214

Various output formats for test results.

215

216

```scala { .api }

217

import org.scalatest.tools._

218

219

// Base reporter trait

220

trait Reporter {

221

def apply(event: Event): Unit

222

}

223

224

// Built-in reporters

225

class StandardOutReporter extends Reporter

226

class StandardErrReporter extends Reporter

227

class FileReporter(fileName: String) extends Reporter

228

class HtmlReporter(directory: String) extends Reporter

229

class JunitXmlReporter(directory: String) extends Reporter

230

class XmlReporter(fileName: String) extends Reporter

231

class MemoryReporter extends Reporter {

232

def eventsReceived: IndexedSeq[Event]

233

}

234

235

// Composite reporter for multiple outputs

236

class MultipleReporter(reporters: Reporter*) extends Reporter

237

238

// Graphic reporter for GUI output

239

class GraphicReporter extends Reporter

240

```

241

242

**Reporter Examples:**

243

```scala

244

import org.scalatest.tools._

245

246

// Multiple reporters

247

val reporters = List(

248

new StandardOutReporter,

249

new HtmlReporter("target/test-reports"),

250

new JunitXmlReporter("target/junit-reports"),

251

new FileReporter("test-results.txt")

252

)

253

254

val multiReporter = new MultipleReporter(reporters: _*)

255

256

// Memory reporter for programmatic access to results

257

val memoryReporter = new MemoryReporter

258

suite.execute(reporter = memoryReporter)

259

260

// Access collected events

261

val events = memoryReporter.eventsReceived

262

val failures = events.collect { case tf: TestFailed => tf }

263

val successes = events.collect { case ts: TestSucceeded => ts }

264

```

265

266

### Test Events

267

268

Events generated during test execution for reporting and monitoring.

269

270

```scala { .api }

271

import org.scalatest.events._

272

273

// Base event types

274

sealed abstract class Event {

275

val ordinal: Ordinal

276

val presenter: Option[Presenter]

277

val location: Option[Location]

278

val message: String

279

val formatter: Option[Formatter]

280

val payload: Option[Any]

281

val threadName: String

282

val timeStamp: Long

283

}

284

285

// Test lifecycle events

286

case class RunStarting(

287

testCount: Int,

288

configMap: ConfigMap,

289

formatter: Option[Formatter],

290

location: Option[Location],

291

payload: Option[Any],

292

threadName: String,

293

timeStamp: Long

294

) extends Event

295

296

case class SuiteStarting(

297

suiteName: String,

298

suiteId: String,

299

suiteClassName: Option[String],

300

formatter: Option[Formatter],

301

location: Option[Location],

302

rerunnable: Option[String],

303

payload: Option[Any],

304

threadName: String,

305

timeStamp: Long

306

) extends Event

307

308

case class TestStarting(

309

suiteName: String,

310

suiteId: String,

311

suiteClassName: Option[String],

312

testName: String,

313

testText: String,

314

formatter: Option[Formatter],

315

location: Option[Location],

316

rerunnable: Option[String],

317

payload: Option[Any],

318

threadName: String,

319

timeStamp: Long

320

) extends Event

321

322

// Test result events

323

case class TestSucceeded(

324

suiteName: String,

325

suiteId: String,

326

suiteClassName: Option[String],

327

testName: String,

328

testText: String,

329

recordedEvents: IndexedSeq[RecordableEvent],

330

duration: Option[Long],

331

formatter: Option[Formatter],

332

location: Option[Location],

333

rerunnable: Option[String],

334

payload: Option[Any],

335

threadName: String,

336

timeStamp: Long

337

) extends Event

338

339

case class TestFailed(

340

message: String,

341

suiteName: String,

342

suiteId: String,

343

suiteClassName: Option[String],

344

testName: String,

345

testText: String,

346

recordedEvents: IndexedSeq[RecordableEvent],

347

throwable: Option[Throwable],

348

duration: Option[Long],

349

formatter: Option[Formatter],

350

location: Option[Location],

351

rerunnable: Option[String],

352

payload: Option[Any],

353

threadName: String,

354

timeStamp: Long

355

) extends Event

356

357

case class TestIgnored(

358

suiteName: String,

359

suiteId: String,

360

suiteClassName: Option[String],

361

testName: String,

362

testText: String,

363

formatter: Option[Formatter],

364

location: Option[Location],

365

payload: Option[Any],

366

threadName: String,

367

timeStamp: Long

368

) extends Event

369

370

case class TestPending(

371

suiteName: String,

372

suiteId: String,

373

suiteClassName: Option[String],

374

testName: String,

375

testText: String,

376

recordedEvents: IndexedSeq[RecordableEvent],

377

duration: Option[Long],

378

formatter: Option[Formatter],

379

location: Option[Location],

380

payload: Option[Any],

381

threadName: String,

382

timeStamp: Long

383

) extends Event

384

385

case class TestCanceled(

386

message: String,

387

suiteName: String,

388

suiteId: String,

389

suiteClassName: Option[String],

390

testName: String,

391

testText: String,

392

recordedEvents: IndexedSeq[RecordableEvent],

393

throwable: Option[Throwable],

394

duration: Option[Long],

395

formatter: Option[Formatter],

396

location: Option[Location],

397

payload: Option[Any],

398

threadName: String,

399

timeStamp: Long

400

) extends Event

401

```

402

403

### Status and Results

404

405

Track test execution progress and results.

406

407

```scala { .api }

408

// Execution status

409

sealed trait Status {

410

def isCompleted: Boolean

411

def succeeds(): Boolean

412

def unreportedException: Option[Throwable]

413

def whenCompleted(f: Boolean => Unit): Unit

414

def waitUntilCompleted(): Unit

415

}

416

417

// Status implementations

418

case object SucceededStatus extends Status {

419

val isCompleted = true

420

def succeeds() = true

421

val unreportedException = None

422

}

423

424

case class FailedStatus(ex: Throwable) extends Status {

425

val isCompleted = true

426

def succeeds() = false

427

val unreportedException = Some(ex)

428

}

429

430

class StatefulStatus extends Status {

431

def setCompleted(): Unit

432

def setFailed(ex: Throwable): Unit

433

def waitUntilCompleted(): Unit

434

}

435

436

// Result counting

437

class SummaryCounter {

438

def testsSucceededCount: Int

439

def testsFailedCount: Int

440

def testsIgnoredCount: Int

441

def testsPendingCount: Int

442

def testsCanceledCount: Int

443

def suitesCompletedCount: Int

444

def suitesAbortedCount: Int

445

def scopesPendingCount: Int

446

}

447

```

448

449

### Parallel Execution

450

451

Execute tests in parallel for better performance.

452

453

```scala { .api }

454

// Distributor for parallel execution

455

trait Distributor {

456

def apply(suite: Suite, args: Args): Status

457

def apply(suite: Suite, tracker: Tracker): Unit

458

}

459

460

// Parallel execution configuration

461

class ParallelTestExecution extends Distributor

462

463

// Suite-level parallel execution

464

trait ParallelTestExecution { this: Suite =>

465

// Mixed into suite to enable parallel test execution

466

}

467

468

// Async execution for Future-based tests

469

trait AsyncTestExecution { this: Suite =>

470

// Mixed into suite to enable async test execution

471

}

472

```

473

474

**Parallel Execution Examples:**

475

```scala

476

import org.scalatest._

477

import org.scalatest.funsuite.AnyFunSuite

478

479

// Enable parallel execution for suite

480

class ParallelSuite extends AnyFunSuite with ParallelTestExecution {

481

test("parallel test 1") {

482

// This test can run in parallel with others

483

Thread.sleep(100)

484

assert(true)

485

}

486

487

test("parallel test 2") {

488

// This test can run in parallel with others

489

Thread.sleep(100)

490

assert(true)

491

}

492

}

493

494

// Command-line parallel execution

495

// scala -cp <classpath> org.scalatest.tools.Runner -P -o

496

```

497

498

### Build Tool Integration

499

500

Integration with SBT, Maven, and other build tools.

501

502

```scala { .api }

503

// SBT Framework implementation

504

class Framework extends sbt.testing.Framework {

505

def name(): String = "ScalaTest"

506

def fingerprints(): Array[sbt.testing.Fingerprint]

507

def runner(args: Array[String], remoteArgs: Array[String], testClassLoader: ClassLoader): sbt.testing.Runner

508

}

509

510

// JUnit integration

511

class JUnitRunner(clazz: Class[_ <: Suite]) extends org.junit.runner.Runner {

512

def run(notifier: RunNotifier): Unit

513

def getDescription: Description

514

}

515

516

// TestNG integration

517

class TestNGSuite extends Suite with TestNGSuiteLike

518

```

519

520

**SBT Integration Example:**

521

```scala

522

// build.sbt

523

libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.19" % Test

524

525

// SBT test command runs ScalaTest

526

// sbt test

527

528

// SBT test configuration

529

Test / testOptions += Tests.Argument(TestFrameworks.ScalaTest, "-o")

530

Test / testOptions += Tests.Argument(TestFrameworks.ScalaTest, "-h", "target/test-reports")

531

532

// Parallel execution in SBT

533

Test / parallelExecution := true

534

```

535

536

### Custom Test Discovery

537

538

Discover and run tests dynamically.

539

540

```scala { .api }

541

// Suite discovery

542

object SuiteDiscoveryHelper {

543

def discoverSuiteNames(

544

loader: ClassLoader,

545

packageNames: List[String],

546

accessibleSuites: Set[String],

547

wildcard: Boolean,

548

runpathClassLoader: ClassLoader

549

): Set[String]

550

}

551

552

// Dynamic suite creation

553

trait Suite {

554

def nestedSuites: IndexedSeq[Suite]

555

def run(testName: Option[String], args: Args): Status

556

}

557

```

558

559

### Shell Integration

560

561

Interactive shell for running tests in REPL environments.

562

563

```scala { .api }

564

// Shell configuration objects (JVM only)

565

lazy val color: Shell // Enable colored output

566

lazy val durations: Shell // Show test durations

567

lazy val shortstacks: Shell // Show short stack traces

568

lazy val fullstacks: Shell // Show full stack traces

569

lazy val stats: Shell // Show statistics

570

lazy val nocolor: Shell // Disable colored output

571

lazy val nodurations: Shell // Hide test durations

572

lazy val nostacks: Shell // Hide stack traces

573

lazy val nostats: Shell // Hide statistics

574

575

// Shell trait

576

trait Shell {

577

def run(testName: String, reporter: Reporter, stopper: Stopper,

578

filter: Filter, configMap: ConfigMap, distributor: Option[Distributor],

579

tracker: Tracker): Unit

580

}

581

```

582

583

**Shell Examples:**

584

```scala

585

// In Scala REPL

586

import org.scalatest._

587

588

// Run with colored output and durations

589

color.durations.run(new MySuite)

590

591

// Run specific test

592

run(new MySuite, "specific test name")

593

594

// Run with custom configuration

595

run(new MySuite, configMap = ConfigMap("env" -> "test"))

596

```