0
# Core Specifications
1
2
Core specification classes and traits provide the foundation for creating immutable (functional-style) test specifications in specs2. These are the main entry points for acceptance-style testing where the specification structure is defined declaratively.
3
4
## Specification Classes
5
6
### Specification
7
8
Main specification class for immutable specifications.
9
10
```scala { .api }
11
abstract class Specification extends SpecificationLike
12
```
13
14
**Usage Example:**
15
```scala
16
class MySpec extends Specification { def is = s2"""
17
This is my specification
18
example 1 $e1
19
example 2 $e2
20
"""
21
22
def e1 = 1 + 1 must beEqualTo(2)
23
def e2 = "test" must have size(4)
24
}
25
```
26
27
### SpecificationLike
28
29
Core trait that provides all specification functionality.
30
31
```scala { .api }
32
trait SpecificationLike extends ImmutableSpecificationStructure
33
with SpecificationCreation
34
with SpecificationFeatures
35
```
36
37
This trait combines:
38
- `ImmutableSpecificationStructure`: Basic structure definition
39
- `SpecificationCreation`: Methods for creating specification fragments
40
- `SpecificationFeatures`: Advanced features like tagging, grouping, execution control
41
42
### Spec
43
44
Lightweight specification class with minimal imports.
45
46
```scala { .api }
47
abstract class Spec extends SpecLike
48
```
49
50
**Usage Example:**
51
```scala
52
class SimpleSpec extends Spec { def is = s2"""
53
Simple specification
54
basic test $e1
55
"""
56
57
def e1 = true must beTrue
58
}
59
```
60
61
### SpecLike
62
63
Lightweight trait with essential functionality only.
64
65
```scala { .api }
66
trait SpecLike extends ImmutableSpecificationStructure
67
with S2StringContext1
68
with AcceptanceDsl1
69
with MustMatchers1
70
with ArgumentsCreation
71
with ArgumentsShortcuts
72
with FormattingFragments
73
with StandardResults
74
with StandardMatchResults
75
```
76
77
Includes minimal imports:
78
- `S2StringContext1`: Basic string interpolation for s2"" syntax
79
- `AcceptanceDsl1`: Essential DSL methods for examples and structure
80
- `MustMatchers1`: Core matchers only
81
- `ArgumentsCreation`: Methods for creating Arguments configurations
82
- `ArgumentsShortcuts`: Shortcut methods for common argument patterns
83
- `FormattingFragments`: Support for formatting and layout fragments
84
- `StandardResults`: Standard result types (Success, Failure, Error, etc.)
85
- `StandardMatchResults`: Standard matcher result handling
86
87
## Structure Traits
88
89
### SpecificationStructure
90
91
Base trait defining the structure of all specifications.
92
93
```scala { .api }
94
trait SpecificationStructure {
95
def is: SpecificationStructure
96
def content: Fragments
97
def header: String
98
def arguments: Arguments
99
}
100
```
101
102
### ImmutableSpecificationStructure
103
104
Structure trait for functional-style specifications.
105
106
```scala { .api }
107
trait ImmutableSpecificationStructure extends SpecificationStructure {
108
def map(f: Fragment => Fragment): ImmutableSpecificationStructure
109
def flatMap(f: Fragment => Fragments): ImmutableSpecificationStructure
110
}
111
```
112
113
### Fragment System
114
115
Specifications are built from fragments - the basic building blocks.
116
117
```scala { .api }
118
sealed trait Fragment
119
120
case class Text(text: String) extends Fragment
121
case class Example(description: String, body: Execution) extends Fragment
122
case class Step(action: () => Any) extends Fragment
123
case class Action(action: () => Any) extends Fragment
124
case class Tab(n: Int = 1) extends Fragment
125
case class Backtab(n: Int = 1) extends Fragment
126
case class Br() extends Fragment
127
case class End() extends Fragment
128
```
129
130
### Fragments
131
132
Collection and manipulation of fragments.
133
134
```scala { .api }
135
case class Fragments(fragments: Vector[Fragment]) {
136
def append(other: Fragments): Fragments
137
def prepend(other: Fragments): Fragments
138
def insert(index: Int, fragment: Fragment): Fragments
139
def map(f: Fragment => Fragment): Fragments
140
def filter(p: Fragment => Boolean): Fragments
141
}
142
```
143
144
## Creation Traits
145
146
### SpecificationCreation
147
148
Methods for creating specification content.
149
150
```scala { .api }
151
trait SpecificationCreation {
152
def title(t: String): Fragment
153
def text(t: String): Fragment
154
def example(desc: String)(body: => Any): Fragment
155
def step(action: => Any): Fragment
156
def action(action: => Any): Fragment
157
}
158
```
159
160
### DefaultFragmentFactory
161
162
Factory methods for creating fragments.
163
164
```scala { .api }
165
object DefaultFragmentFactory {
166
def text(t: String): Fragment
167
def example(desc: String, body: Execution): Fragment
168
def step(action: => Any): Fragment
169
def action(action: => Any): Fragment
170
def break: Fragment
171
def tab(n: Int = 1): Fragment
172
def backtab(n: Int = 1): Fragment
173
def end: Fragment
174
}
175
```
176
177
## Advanced Features
178
179
### SpecificationFeatures
180
181
Advanced specification capabilities.
182
183
```scala { .api }
184
trait SpecificationFeatures extends Groups
185
with Debug
186
with Level
187
with SpecificationInclusion
188
```
189
190
### ArgumentsCreation
191
192
Creates Arguments configurations for controlling specification execution.
193
194
```scala { .api }
195
trait ArgumentsCreation {
196
def args(
197
plan: Boolean = false,
198
skipAll: Boolean = false,
199
stopOnFail: Boolean = false,
200
sequential: Boolean = false,
201
isolated: Boolean = false,
202
threadsNb: Int = Runtime.getRuntime.availableProcessors,
203
specs2ThreadsNb: Int = Runtime.getRuntime.availableProcessors
204
): Arguments
205
}
206
```
207
208
### ArgumentsShortcuts
209
210
Convenient shortcut methods for common argument patterns.
211
212
```scala { .api }
213
trait ArgumentsShortcuts {
214
def sequential: Arguments
215
def isolated: Arguments
216
def skipAll: Arguments
217
def stopOnFail: Arguments
218
def plan: Arguments
219
}
220
```
221
222
### FormattingFragments
223
224
Support for formatting and layout fragments in specifications.
225
226
```scala { .api }
227
trait FormattingFragments {
228
def tab(n: Int = 1): Fragment
229
def backtab(n: Int = 1): Fragment
230
def br: Fragment
231
def p: Fragment
232
def end: Fragment
233
}
234
```
235
236
### StandardResults
237
238
Standard result types used throughout specs2.
239
240
```scala { .api }
241
trait StandardResults {
242
def success: Success
243
def success(message: String): Success
244
def failure: Failure
245
def failure(message: String): Failure
246
def pending: Pending
247
def pending(message: String): Pending
248
def skipped: Skipped
249
def skipped(message: String): Skipped
250
}
251
```
252
253
### StandardMatchResults
254
255
Standard matcher result handling and utilities.
256
257
```scala { .api }
258
trait StandardMatchResults {
259
def createMatchResult[T](
260
expectable: Expectable[T],
261
message: String,
262
negatedMessage: String,
263
isSuccess: Boolean
264
): MatchResult[T]
265
}
266
```
267
268
### Groups
269
270
Grouping examples for organization and selective execution.
271
272
```scala { .api }
273
trait Groups {
274
def group(name: String): Fragment
275
def section(name: String): Fragment
276
}
277
```
278
279
### Context Support
280
281
Execution context for examples.
282
283
```scala { .api }
284
trait Context {
285
def apply[T: AsResult](a: => T): Result
286
}
287
288
trait BeforeEach extends Context {
289
def before: Any
290
}
291
292
trait AfterEach extends Context {
293
def after: Any
294
}
295
296
trait AroundEach extends Context {
297
def around[T: AsResult](t: => T): Result
298
}
299
```
300
301
## Usage Patterns
302
303
### String Context Specifications
304
305
Using s2 string interpolation for embedded examples:
306
307
```scala
308
class UserSpec extends Specification { def is = s2"""
309
User management system
310
should create valid users $createUser
311
should validate email format $validateEmail
312
should handle duplicates $handleDups
313
"""
314
315
def createUser = {
316
val user = User("john", "john@example.com")
317
user.name must beEqualTo("john")
318
}
319
320
def validateEmail = {
321
User("jane", "invalid-email") must throwA[ValidationException]
322
}
323
324
def handleDups = {
325
val users = List(User("bob", "bob@test.com"), User("bob", "bob@test.com"))
326
users.distinct must have size(1)
327
}
328
}
329
```
330
331
### Sequential vs Parallel Execution
332
333
Control execution mode:
334
335
```scala
336
class SequentialSpec extends Specification { def is = sequential ^ s2"""
337
These examples run one after another
338
step 1 $step1
339
step 2 $step2
340
step 3 $step3
341
"""
342
343
// examples implementation...
344
}
345
```
346
347
### Specification Arguments
348
349
Configure specification behavior:
350
351
```scala
352
class ConfiguredSpec extends Specification { def is =
353
args(sequential = true, stopOnFail = true) ^ s2"""
354
Configured specification behavior
355
example 1 $e1
356
example 2 $e2
357
"""
358
359
// examples implementation...
360
}
361
```
362
363
### Including Other Specifications
364
365
Modular specification composition:
366
367
```scala
368
class MainSpec extends Specification { def is = s2"""
369
Main specification
370
${"UserSpec"}
371
${"OrderSpec"}
372
${"PaymentSpec"}
373
"""
374
}
375
```
376
377
## Best Practices
378
379
1. **Use descriptive names**: Make specification titles and example descriptions clear and readable
380
2. **Organize logically**: Group related examples together using sections
381
3. **Keep examples focused**: Each example should test one specific behavior
382
4. **Use appropriate contexts**: Apply setup/teardown contexts when needed
383
5. **Leverage string interpolation**: Use s2 strings for readable specification structure
384
6. **Control execution**: Use sequential execution when examples have dependencies