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

integration-features.mddocs/

0

# Integration Features

1

2

Specs2 provides comprehensive integration modules for popular testing frameworks and tools including JUnit, ScalaCheck for property-based testing, Mockito for mocking, and analysis tools for code dependencies.

3

4

## JUnit Integration

5

6

### SpecificationWithJUnit

7

8

JUnit-compatible specification class that can be run by JUnit runners.

9

10

```scala { .api }

11

@RunWith(classOf[JUnitRunner])

12

abstract class SpecificationWithJUnit extends Specification

13

```

14

15

**Usage Example:**

16

```scala

17

import org.specs2._

18

import org.specs2.runner.JUnitRunner

19

import org.junit.runner.RunWith

20

21

@RunWith(classOf[JUnitRunner])

22

class CalculatorJUnitSpec extends SpecificationWithJUnit { def is = s2"""

23

Calculator specification for JUnit

24

add two numbers $add

25

subtract numbers $subtract

26

"""

27

28

def add = Calculator.add(2, 3) must beEqualTo(5)

29

def subtract = Calculator.subtract(5, 2) must beEqualTo(3)

30

}

31

```

32

33

### SpecWithJUnit

34

35

Lightweight JUnit-compatible specification.

36

37

```scala { .api }

38

@RunWith(classOf[JUnitRunner])

39

abstract class SpecWithJUnit extends Spec

40

```

41

42

**Usage Example:**

43

```scala

44

@RunWith(classOf[JUnitRunner])

45

class SimpleJUnitSpec extends SpecWithJUnit { def is = s2"""

46

Simple JUnit specification

47

basic test ${ 1 + 1 must beEqualTo(2) }

48

"""

49

}

50

```

51

52

### JUnitRunner

53

54

JUnit test runner implementation for executing specs2 specifications.

55

56

```scala { .api }

57

class JUnitRunner(klass: Class[_]) extends Runner {

58

def run(notifier: RunNotifier): Unit

59

def getDescription: Description

60

def testCount(): Int

61

}

62

```

63

64

**IDE Integration:**

65

- IntelliJ IDEA: Automatically recognizes `@RunWith(classOf[JUnitRunner])` specifications

66

- Eclipse: Supports JUnit runner integration

67

- NetBeans: Compatible with JUnit test execution

68

69

**Maven Integration:**

70

```xml

71

<plugin>

72

<groupId>org.apache.maven.plugins</groupId>

73

<artifactId>maven-surefire-plugin</artifactId>

74

<version>2.22.2</version>

75

<configuration>

76

<includes>

77

<include>**/*Spec.java</include>

78

<include>**/*Test.java</include>

79

</includes>

80

</configuration>

81

</plugin>

82

```

83

84

## ScalaCheck Integration

85

86

### ScalaCheckProperty

87

88

Integration trait for property-based testing with ScalaCheck.

89

90

```scala { .api }

91

trait ScalaCheckProperty {

92

def prop[T: Arbitrary](f: T => Boolean): Prop

93

def prop[T1: Arbitrary, T2: Arbitrary](f: (T1, T2) => Boolean): Prop

94

def prop[T1: Arbitrary, T2: Arbitrary, T3: Arbitrary](f: (T1, T2, T3) => Boolean): Prop

95

def forAll[T: Arbitrary](f: T => Boolean): Prop

96

def forAll[T: Arbitrary](gen: Gen[T])(f: T => Boolean): Prop

97

}

98

```

99

100

**Usage Example:**

101

```scala

102

import org.specs2._

103

import org.specs2.scalacheck.ScalaCheckProperty

104

import org.scalacheck.{Arbitrary, Gen}

105

106

class PropertySpec extends Specification with ScalaCheckProperty { def is = s2"""

107

String properties

108

concatenation is associative $concatenationAssoc

109

reverse twice is identity $reverseTwice

110

length is preserved $lengthPreserved

111

"""

112

113

def concatenationAssoc = prop { (s1: String, s2: String, s3: String) =>

114

(s1 + s2) + s3 must beEqualTo(s1 + (s2 + s3))

115

}

116

117

def reverseTwice = prop { (s: String) =>

118

s.reverse.reverse must beEqualTo(s)

119

}

120

121

def lengthPreserved = prop { (s: String) =>

122

s.reverse.length must beEqualTo(s.length)

123

}

124

}

125

```

126

127

### ScalaCheckParameters

128

129

Configuration parameters for ScalaCheck property testing.

130

131

```scala { .api }

132

case class ScalaCheckParameters(

133

minTestsOk: Int = 100,

134

maxDiscardRatio: Float = 5.0f,

135

minSize: Int = 0,

136

maxSize: Int = 100,

137

rng: java.util.Random = new java.util.Random,

138

workers: Int = 1,

139

testCallback: TestCallback = new TestCallback {},

140

maxDiscarded: Int = 500,

141

customClassLoader: Option[ClassLoader] = None

142

)

143

```

144

145

**Custom Parameters:**

146

```scala

147

class CustomPropertySpec extends Specification with ScalaCheckProperty { def is = s2"""

148

Custom property testing

149

large dataset property $largeDataset

150

"""

151

152

implicit val params = ScalaCheckParameters(

153

minTestsOk = 1000, // Run 1000 tests instead of default 100

154

maxSize = 10000, // Generate larger test data

155

workers = 4 // Use 4 parallel workers

156

)

157

158

def largeDataset = prop { (list: List[Int]) =>

159

list.sorted.reverse must beEqualTo(list.sortWith(_ > _))

160

}

161

}

162

```

163

164

### ScalaCheckPropertyCreation

165

166

Methods for creating properties from functions.

167

168

```scala { .api }

169

trait ScalaCheckPropertyCreation {

170

def property[T: Arbitrary](f: T => Prop): Property

171

def property[T: Arbitrary](name: String)(f: T => Prop): Property

172

def propertyWithSeed[T: Arbitrary](seed: Long)(f: T => Prop): Property

173

}

174

```

175

176

### ScalaCheckPropertyDsl

177

178

DSL for convenient property definition.

179

180

```scala { .api }

181

trait ScalaCheckPropertyDsl {

182

def check[T: Arbitrary](f: T => Boolean): Fragment

183

def checkAll[T: Arbitrary](f: T => Boolean): Fragment

184

def verify[T: Arbitrary](f: T => Prop): Fragment

185

}

186

```

187

188

**DSL Usage:**

189

```scala

190

class PropertyDslSpec extends Specification with ScalaCheckPropertyDsl { def is = s2"""

191

Property DSL examples

192

list concatenation ${check { (l1: List[Int], l2: List[Int]) =>

193

(l1 ++ l2).length == l1.length + l2.length

194

}}

195

196

string operations ${verify { (s: String) =>

197

(s.length >= 0) :| "length non-negative" &&

198

(s.reverse.reverse == s) :| "reverse is involution"

199

}}

200

"""

201

}

202

```

203

204

### AsResultProp

205

206

Converting ScalaCheck properties to specs2 results.

207

208

```scala { .api }

209

trait AsResultProp {

210

implicit def propAsResult(prop: Prop): AsResult[Prop]

211

implicit def propertyAsResult(property: Property): AsResult[Property]

212

implicit def genAsResult[T](gen: Gen[T]): AsResult[Gen[T]]

213

}

214

```

215

216

### Parameters and Configuration

217

218

Fine-grained control over property testing:

219

220

```scala { .api }

221

case class Parameters(

222

minTestsOk: Int,

223

maxDiscardRatio: Float,

224

minSize: Int,

225

maxSize: Int,

226

rng: scala.util.Random,

227

workers: Int

228

)

229

```

230

231

**Configuration Example:**

232

```scala

233

class ConfiguredPropertySpec extends Specification with ScalaCheckProperty {

234

// Override default parameters

235

override implicit val defaultParameters = Parameters(

236

minTestsOk = 500,

237

maxDiscardRatio = 10.0f,

238

minSize = 10,

239

maxSize = 1000,

240

workers = Runtime.getRuntime.availableProcessors

241

)

242

243

def is = s2"""

244

Configured property tests

245

expensive property $expensiveProperty

246

"""

247

248

def expensiveProperty = prop { (data: ComplexData) =>

249

expensiveValidation(data) must beTrue

250

}

251

}

252

```

253

254

### PrettyDetails

255

256

Enhanced failure reporting for property tests.

257

258

```scala { .api }

259

trait PrettyDetails {

260

def prettyFreqMap(freqMap: Map[Set[Any], Int]): String

261

def prettyTestRes(testRes: Test.Result): String

262

def prettyArgs(args: List[Arg[Any]]): String

263

}

264

```

265

266

## Mockito Integration

267

268

### Mockito

269

270

Integration with Mockito mocking framework.

271

272

```scala { .api }

273

trait Mockito {

274

def mock[T: ClassTag]: T

275

def mock[T: ClassTag](name: String): T

276

def mock[T: ClassTag](defaultAnswer: Answer[_]): T

277

def spy[T](realObject: T): T

278

279

// Verification methods

280

def verify[T](mock: T): T

281

def verify[T](mock: T, mode: VerificationMode): T

282

def verifyNoMoreInteractions(mocks: AnyRef*): Unit

283

def verifyZeroInteractions(mocks: AnyRef*): Unit

284

285

// Stubbing methods

286

def when[T](methodCall: T): OngoingStubbing[T]

287

def doReturn(value: Any): Stubber

288

def doThrow(throwable: Throwable): Stubber

289

def doAnswer(answer: Answer[_]): Stubber

290

def doNothing(): Stubber

291

}

292

```

293

294

**Usage Example:**

295

```scala

296

import org.specs2._

297

import org.specs2.mock.Mockito

298

299

class MockitoSpec extends Specification with Mockito { def is = s2"""

300

Service with mocked dependencies

301

should call repository save method $callsSave

302

should handle repository exceptions $handlesException

303

"""

304

305

def callsSave = {

306

val mockRepo = mock[UserRepository]

307

val service = new UserService(mockRepo)

308

val user = User("john", "john@test.com")

309

310

when(mockRepo.save(user)).thenReturn(user.copy(id = Some(1)))

311

312

val result = service.createUser(user)

313

314

result.id must beSome(1)

315

verify(mockRepo).save(user)

316

}

317

318

def handlesException = {

319

val mockRepo = mock[UserRepository]

320

val service = new UserService(mockRepo)

321

val user = User("john", "john@test.com")

322

323

when(mockRepo.save(user)).thenThrow(new DatabaseException("Connection failed"))

324

325

service.createUser(user) must throwA[ServiceException]

326

}

327

}

328

```

329

330

### Advanced Mocking Features

331

332

**Argument Matchers:**

333

```scala

334

import org.mockito.ArgumentMatchers._

335

336

def usesArgumentMatchers = {

337

val mockService = mock[EmailService]

338

339

when(mockService.send(any[String], contains("@test.com"), anyInt()))

340

.thenReturn(true)

341

342

mockService.send("subject", "user@test.com", 1) must beTrue

343

verify(mockService).send(eq("subject"), argThat(_.contains("@test.com")), gt(0))

344

}

345

```

346

347

**Capturing Arguments:**

348

```scala

349

import org.mockito.{ArgumentCaptor, Mockito}

350

351

def capturesArguments = {

352

val mockRepo = mock[AuditRepository]

353

val service = new UserService(mockRepo)

354

val captor = ArgumentCaptor.forClass(classOf[AuditEvent])

355

356

service.deleteUser(123)

357

358

verify(mockRepo).save(captor.capture())

359

val event = captor.getValue

360

event.action must beEqualTo("DELETE")

361

event.entityId must beEqualTo(123)

362

}

363

```

364

365

### HamcrestMatcherAdapter

366

367

Integration with Hamcrest matchers for enhanced assertions.

368

369

```scala { .api }

370

trait HamcrestMatcherAdapter {

371

def adapt[T](hamcrestMatcher: org.hamcrest.Matcher[T]): Matcher[T]

372

implicit def hamcrestToSpecs2[T](hamcrestMatcher: org.hamcrest.Matcher[T]): Matcher[T]

373

}

374

```

375

376

**Usage Example:**

377

```scala

378

import org.specs2._

379

import org.specs2.mock.HamcrestMatcherAdapter

380

import org.hamcrest.Matchers._

381

382

class HamcrestSpec extends Specification with HamcrestMatcherAdapter { def is = s2"""

383

Using Hamcrest matchers

384

string contains check $stringContains

385

collection size check $collectionSize

386

"""

387

388

def stringContains = {

389

"hello world" must adapt(containsString("world"))

390

}

391

392

def collectionSize = {

393

List(1, 2, 3) must adapt(hasSize(3))

394

}

395

}

396

```

397

398

## Analysis Features

399

400

### CompilerDependencyFinder

401

402

Code analysis using Scala compiler for dependency checking.

403

404

```scala { .api }

405

class CompilerDependencyFinder {

406

def findDependencies(classNames: List[String]): List[Dependency]

407

def findPackageDependencies(packageName: String): List[PackageDependency]

408

def checkCircularDependencies(packages: List[String]): List[CircularDependency]

409

}

410

```

411

412

### DependencyFinder

413

414

General interface for dependency analysis.

415

416

```scala { .api }

417

trait DependencyFinder {

418

def getPackageDependencies(packageNames: List[String]): Operation[List[PackageDependency]]

419

def getClassDependencies(className: String): Operation[List[ClassDependency]]

420

}

421

```

422

423

### ClassycleDependencyFinder

424

425

Integration with Classycle for advanced dependency analysis.

426

427

```scala { .api }

428

class ClassycleDependencyFinder extends DependencyFinder {

429

def checkArchitectureRules(rules: List[ArchitectureRule]): List[RuleViolation]

430

def analyzeLayerDependencies(layers: List[Layer]): ArchitectureAnalysis

431

}

432

```

433

434

**Usage Example:**

435

```scala

436

import org.specs2._

437

import org.specs2.analysis._

438

439

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

440

Architecture rules

441

layers should respect dependencies $layerDependencies

442

no circular dependencies $noCircularDeps

443

"""

444

445

def layerDependencies = {

446

val finder = new ClassycleDependencyFinder

447

val rules = List(

448

ArchitectureRule("service layer", "com.example.service",

449

canDependOn = List("com.example.domain", "com.example.repository"),

450

cannotDependOn = List("com.example.web")),

451

ArchitectureRule("web layer", "com.example.web",

452

canDependOn = List("com.example.service", "com.example.domain"),

453

cannotDependOn = List("com.example.repository"))

454

)

455

456

val violations = finder.checkArchitectureRules(rules)

457

violations must beEmpty

458

}

459

460

def noCircularDeps = {

461

val finder = new CompilerDependencyFinder

462

val packages = List("com.example.service", "com.example.repository", "com.example.domain")

463

val circular = finder.checkCircularDependencies(packages)

464

circular must beEmpty

465

}

466

}

467

```

468

469

## GWT Integration

470

471

### GWT Support

472

473

Integration for Google Web Toolkit projects.

474

475

```scala { .api }

476

trait GwtSpecification {

477

def gwtSetup(): Unit

478

def gwtTeardown(): Unit

479

def runInGwtMode[T](test: => T): T

480

}

481

```

482

483

**Note**: GWT integration is provided for legacy support and may be deprecated in newer versions.

484

485

## Testing Framework Integration

486

487

### TestFramework Integration

488

489

Integration with SBT's test framework interface.

490

491

```scala { .api }

492

class Specs2Framework extends TestFramework {

493

def name: String = "specs2"

494

def fingerprints: Array[Fingerprint] = Array(

495

SubclassFingerprint("org.specs2.Specification", false, true),

496

SubclassFingerprint("org.specs2.mutable.Specification", false, true),

497

SubclassFingerprint("org.specs2.Spec", false, true),

498

SubclassFingerprint("org.specs2.mutable.Spec", false, true)

499

)

500

}

501

```

502

503

### Custom Test Interfaces

504

505

Creating custom test framework integrations:

506

507

```scala

508

class CustomRunner extends Runner2 {

509

def run(eventHandler: EventHandler, loggers: Array[Logger],

510

continuation: Array[Task] => Unit, args: Array[String]): Unit = {

511

// Custom runner implementation

512

}

513

514

def tasks(taskDefs: Array[TaskDef]): Array[Task] = {

515

// Convert task definitions to executable tasks

516

}

517

}

518

```

519

520

## Best Practices

521

522

### JUnit Integration

523

524

1. **Use `@RunWith(classOf[JUnitRunner])`** for IDE compatibility

525

2. **Combine with Maven/Gradle** for build tool integration

526

3. **Generate JUnit XML reports** for CI/CD integration

527

4. **Keep specification structure simple** for JUnit compatibility

528

529

### ScalaCheck Integration

530

531

1. **Start with simple properties** and build complexity gradually

532

2. **Use meaningful property names** for better failure reporting

533

3. **Configure appropriate test counts** based on property complexity

534

4. **Leverage custom generators** for domain-specific data

535

5. **Use labels** (`:| "label"`) for better failure diagnostics

536

537

### Mockito Integration

538

539

1. **Mock external dependencies** only, not domain objects

540

2. **Verify interactions** that are important to the business logic

541

3. **Use argument captors** for complex verification scenarios

542

4. **Reset mocks** between tests when necessary

543

5. **Prefer real objects** over mocks when possible

544

545

### Architecture Testing

546

547

1. **Define clear layer boundaries** and enforce them with analysis

548

2. **Check for circular dependencies** regularly

549

3. **Use architecture rules** to prevent regression

550

4. **Document architectural decisions** in test specifications

551

5. **Run architecture tests** as part of continuous integration

552

553

### General Integration

554

555

1. **Choose appropriate integrations** based on project needs

556

2. **Keep integration code simple** and focused

557

3. **Document integration requirements** and setup procedures

558

4. **Test integrations** in isolation when possible

559

5. **Monitor integration performance** and optimize as needed