0
# Test Styles
1
2
ScalaTest provides multiple testing styles to accommodate different preferences and project requirements. Each style offers a different syntax and organization approach while sharing the same underlying execution engine.
3
4
## Capabilities
5
6
### FunSuite Style
7
8
Function-based testing style with named test functions.
9
10
```scala { .api }
11
abstract class AnyFunSuite extends Suite with TestSuite with Assertions with TestRegistration {
12
/**
13
* Register a test with the given spec text and test function value
14
*/
15
protected def test(testName: String)(testFun: => Any): Unit
16
17
/**
18
* Register a test to ignore with the given spec text
19
*/
20
protected def ignore(testName: String)(testFun: => Any): Unit
21
}
22
```
23
24
**Usage Example:**
25
26
```scala
27
import org.scalatest.funsuite.AnyFunSuite
28
29
class ExampleFunSuite extends AnyFunSuite {
30
test("pop is invoked on a non-empty stack") {
31
val stack = new Stack[Int]
32
stack.push(1)
33
stack.push(2)
34
val oldSize = stack.size
35
val result = stack.pop()
36
assert(result === 2)
37
assert(stack.size === oldSize - 1)
38
}
39
40
ignore("pop is invoked on an empty stack") {
41
val emptyStack = new Stack[Int]
42
intercept[IllegalArgumentException] {
43
emptyStack.pop()
44
}
45
}
46
}
47
```
48
49
### FlatSpec Style
50
51
Behavior-driven development style with "should" syntax.
52
53
```scala { .api }
54
abstract class AnyFlatSpec extends Suite with TestSuite with Assertions with TestRegistration {
55
/**
56
* Class that supports the registration of tests in shorthand form
57
*/
58
protected final class FlatSpecStringWrapper(string: String) {
59
def should(testFun: => Any): Unit
60
def must(testFun: => Any): Unit
61
def can(testFun: => Any): Unit
62
}
63
64
/**
65
* Implicitly converts strings to FlatSpecStringWrapper for test registration
66
*/
67
protected implicit def convertToFlatSpecStringWrapper(o: String): FlatSpecStringWrapper
68
69
/**
70
* Register a test to ignore
71
*/
72
protected def ignore: IgnoreWord
73
}
74
```
75
76
**Usage Example:**
77
78
```scala
79
import org.scalatest.flatspec.AnyFlatSpec
80
81
class ExampleFlatSpec extends AnyFlatSpec {
82
"A Stack" should "pop values in last-in-first-out order" in {
83
val stack = new Stack[Int]
84
stack.push(1)
85
stack.push(2)
86
assert(stack.pop() === 2)
87
assert(stack.pop() === 1)
88
}
89
90
it should "throw IllegalArgumentException if pop is invoked on an empty stack" in {
91
val emptyStack = new Stack[String]
92
intercept[IllegalArgumentException] {
93
emptyStack.pop()
94
}
95
}
96
97
ignore should "be ignored" in {
98
// This test will be ignored
99
}
100
}
101
```
102
103
### FunSpec Style
104
105
Ruby RSpec-like nested describe/it syntax.
106
107
```scala { .api }
108
abstract class AnyFunSpec extends Suite with TestSuite with Assertions with TestRegistration {
109
/**
110
* Register a description of the subject being specified and tested
111
*/
112
protected def describe(description: String)(fun: => Unit): Unit
113
114
/**
115
* Register a specification/test for the subject being described
116
*/
117
protected def it(specText: String)(testFun: => Any): Unit
118
119
/**
120
* Register a test to ignore
121
*/
122
protected def ignore(testName: String)(testFun: => Any): Unit
123
}
124
```
125
126
**Usage Example:**
127
128
```scala
129
import org.scalatest.funspec.AnyFunSpec
130
131
class ExampleFunSpec extends AnyFunSpec {
132
describe("A Stack") {
133
describe("when not empty") {
134
it("should remove and return the top item on pop") {
135
val stack = new Stack[Int]
136
stack.push(1)
137
stack.push(2)
138
assert(stack.pop() === 2)
139
}
140
}
141
142
describe("when empty") {
143
it("should throw IllegalArgumentException on pop") {
144
val emptyStack = new Stack[Int]
145
intercept[IllegalArgumentException] {
146
emptyStack.pop()
147
}
148
}
149
}
150
}
151
}
152
```
153
154
### WordSpec Style
155
156
Specification style with subject-verb-object structure.
157
158
```scala { .api }
159
abstract class AnyWordSpec extends Suite with TestSuite with Assertions with TestRegistration {
160
/**
161
* Class that supports the registration of subjects
162
*/
163
protected final class WordSpecStringWrapper(string: String) {
164
def when(f: => Unit): Unit
165
def which(f: => Unit): Unit
166
def should(f: => Unit): Unit
167
def must(f: => Unit): Unit
168
def can(f: => Unit): Unit
169
}
170
171
/**
172
* Implicitly converts strings to WordSpecStringWrapper
173
*/
174
protected implicit def convertToWordSpecStringWrapper(s: String): WordSpecStringWrapper
175
}
176
```
177
178
**Usage Example:**
179
180
```scala
181
import org.scalatest.wordspec.AnyWordSpec
182
183
class ExampleWordSpec extends AnyWordSpec {
184
"A Stack" when {
185
"not empty" should {
186
"return the last item added on pop" in {
187
val stack = new Stack[Int]
188
stack.push(1)
189
stack.push(2)
190
assert(stack.pop() === 2)
191
}
192
}
193
194
"empty" should {
195
"throw IllegalArgumentException on pop" in {
196
val emptyStack = new Stack[Int]
197
intercept[IllegalArgumentException] {
198
emptyStack.pop()
199
}
200
}
201
}
202
}
203
}
204
```
205
206
### FreeSpec Style
207
208
Free-form specification style allowing arbitrary nesting.
209
210
```scala { .api }
211
abstract class AnyFreeSpec extends Suite with TestSuite with Assertions with TestRegistration {
212
/**
213
* Class that supports the registration of free-form text with nested tests/scopes
214
*/
215
protected final class FreeSpecStringWrapper(string: String) {
216
def in(f: => Any): Unit
217
def is(f: => Unit): Unit
218
def ignore(f: => Any): Unit
219
}
220
221
/**
222
* Implicitly converts strings to FreeSpecStringWrapper
223
*/
224
protected implicit def convertToFreeSpecStringWrapper(s: String): FreeSpecStringWrapper
225
}
226
```
227
228
**Usage Example:**
229
230
```scala
231
import org.scalatest.freespec.AnyFreeSpec
232
233
class ExampleFreeSpec extends AnyFreeSpec {
234
"A Stack" - {
235
"when not empty" - {
236
"should pop values in LIFO order" in {
237
val stack = new Stack[Int]
238
stack.push(1)
239
stack.push(2)
240
assert(stack.pop() === 2)
241
assert(stack.pop() === 1)
242
}
243
}
244
245
"when empty" - {
246
"should throw on pop" in {
247
val emptyStack = new Stack[Int]
248
intercept[IllegalArgumentException] {
249
emptyStack.pop()
250
}
251
}
252
}
253
}
254
}
255
```
256
257
### PropSpec Style
258
259
Property-based testing style for specifying properties that should hold.
260
261
```scala { .api }
262
abstract class AnyPropSpec extends Suite with TestSuite with Assertions with TestRegistration {
263
/**
264
* Register a property-based test
265
*/
266
protected def property(testName: String)(testFun: => Any): Unit
267
268
/**
269
* Register a property-based test to ignore
270
*/
271
protected def ignore(testName: String)(testFun: => Any): Unit
272
}
273
```
274
275
**Usage Example:**
276
277
```scala
278
import org.scalatest.propspec.AnyPropSpec
279
import org.scalatest.prop.PropertyChecks
280
281
class ExamplePropSpec extends AnyPropSpec with PropertyChecks {
282
property("list size should equal the number of elements added") {
283
forAll { (list: List[Int]) =>
284
val buffer = scala.collection.mutable.ListBuffer.empty[Int]
285
list.foreach(buffer += _)
286
assert(buffer.size === list.size)
287
}
288
}
289
290
property("reversing a list twice should give the original list") {
291
forAll { (list: List[String]) =>
292
assert(list.reverse.reverse === list)
293
}
294
}
295
}
296
```
297
298
### FeatureSpec Style
299
300
Acceptance testing style with Given-When-Then structure.
301
302
```scala { .api }
303
abstract class AnyFeatureSpec extends Suite with TestSuite with Assertions with TestRegistration {
304
/**
305
* Register a feature (user story or requirement)
306
*/
307
protected def feature(description: String)(fun: => Unit): Unit
308
309
/**
310
* Register a scenario within a feature
311
*/
312
protected def scenario(description: String)(fun: => Any): Unit
313
314
/**
315
* Register a scenario to ignore
316
*/
317
protected def ignore(description: String)(fun: => Any): Unit
318
319
/**
320
* Provides Given step syntax
321
*/
322
protected def Given(description: String): Unit
323
324
/**
325
* Provides When step syntax
326
*/
327
protected def When(description: String): Unit
328
329
/**
330
* Provides Then step syntax
331
*/
332
protected def Then(description: String): Unit
333
334
/**
335
* Provides And step syntax
336
*/
337
protected def And(description: String): Unit
338
}
339
```
340
341
**Usage Example:**
342
343
```scala
344
import org.scalatest.featurespec.AnyFeatureSpec
345
import org.scalatest.GivenWhenThen
346
347
class ExampleFeatureSpec extends AnyFeatureSpec with GivenWhenThen {
348
feature("Stack operations") {
349
scenario("User pops an element from a non-empty stack") {
350
Given("a non-empty stack")
351
val stack = new Stack[String]
352
stack.push("item1")
353
stack.push("item2")
354
355
When("the user pops an element")
356
val poppedElement = stack.pop()
357
358
Then("the most recently pushed element should be returned")
359
assert(poppedElement === "item2")
360
361
And("the stack size should be reduced by one")
362
assert(stack.size === 1)
363
}
364
}
365
}
366
```
367
368
## Test Registration Traits
369
370
```scala { .api }
371
trait TestRegistration {
372
def registerTest(testName: String, testTags: Tag*)(testFun: => Any): Unit
373
def registerIgnoredTest(testName: String, testTags: Tag*)(testFun: => Any): Unit
374
}
375
376
trait TestSuite extends Suite {
377
def testNames: Set[String]
378
def tags: Map[String, Set[String]]
379
def runTest(testName: String, args: Args): Status
380
}
381
```