0
# Test Definition and Structure
1
2
Core DSL for creating tests and test suites with support for nested suites, test organization, and ZIO effect integration.
3
4
## Capabilities
5
6
### Test Function
7
8
Creates a single test case with a descriptive label and assertion.
9
10
```scala { .api }
11
/**
12
* Creates a test with the specified label and assertion
13
* @param label descriptive name for the test
14
* @param assertion test logic returning TestResult or ZIO effect
15
* @return test specification
16
*/
17
def test[R](label: String)(assertion: => ZIO[R, Any, TestResult]): Spec[R, Any]
18
```
19
20
**Usage Examples:**
21
22
```scala
23
import zio.test._
24
25
// Simple test with assertTrue
26
test("addition works correctly") {
27
assertTrue(2 + 2 == 4)
28
}
29
30
// Effectful test
31
test("database connection") {
32
for {
33
connection <- Database.connect
34
isValid <- connection.isValid
35
} yield assertTrue(isValid)
36
}
37
38
// Test with custom assertion
39
test("list contains element") {
40
val list = List(1, 2, 3, 4, 5)
41
assert(list)(contains(3))
42
}
43
```
44
45
### Suite Function
46
47
Creates a test suite containing multiple tests or nested suites.
48
49
```scala { .api }
50
/**
51
* Creates a test suite with the specified label and child specifications
52
* @param label descriptive name for the suite
53
* @param specs child test specifications (tests or nested suites)
54
* @return suite specification
55
*/
56
def suite[R](label: String)(specs: Spec[R, Any]*): Spec[R, Any]
57
```
58
59
**Usage Examples:**
60
61
```scala
62
import zio.test._
63
64
// Simple suite with multiple tests
65
suite("Math Operations")(
66
test("addition") { assertTrue(2 + 2 == 4) },
67
test("multiplication") { assertTrue(3 * 4 == 12) },
68
test("division") { assertTrue(10 / 2 == 5) }
69
)
70
71
// Nested suites
72
suite("API Tests")(
73
suite("User Endpoints")(
74
test("create user") { /* test logic */ },
75
test("get user") { /* test logic */ },
76
test("update user") { /* test logic */ }
77
),
78
suite("Product Endpoints")(
79
test("list products") { /* test logic */ },
80
test("create product") { /* test logic */ }
81
)
82
)
83
```
84
85
### ZTest Type
86
87
Low-level effectful test type for advanced test construction.
88
89
```scala { .api }
90
/**
91
* Effectful test that may fail with TestFailure[E] or succeed with TestSuccess
92
*/
93
type ZTest[-R, +E] = ZIO[R, TestFailure[E], TestSuccess]
94
95
object ZTest {
96
/**
97
* Builds a test with an effectual assertion
98
* @param label test label
99
* @param assertion effectual test assertion
100
* @return ZTest instance
101
*/
102
def apply[R, E](label: String, assertion: => ZIO[R, E, TestResult]): ZIO[R, TestFailure[E], TestSuccess]
103
}
104
```
105
106
### Spec Trait
107
108
Core specification type supporting composition and test aspect application.
109
110
```scala { .api }
111
/**
112
* A test specification that can be executed to produce test results
113
* @tparam R environment required to run the specification
114
* @tparam E error type that tests may fail with
115
*/
116
trait Spec[+R, +E] {
117
/**
118
* Apply a test aspect to this specification
119
* @param aspect test aspect to apply
120
* @return modified specification
121
*/
122
def @@[R1 <: R](aspect: TestAspect[Nothing, R1, Nothing, Any]): Spec[R1, E]
123
124
/**
125
* Transform the environment of this specification
126
* @param f transformation function
127
* @return specification with transformed environment
128
*/
129
def provideLayer[R0, R1, E1 >: E](layer: ZLayer[R0, E1, R1]): Spec[R0, E1]
130
}
131
```
132
133
**Usage Examples:**
134
135
```scala
136
import zio.test._
137
import zio.test.TestAspect._
138
139
// Apply timeout aspect to entire suite
140
suite("Database Tests")(
141
test("slow query") { /* test logic */ },
142
test("batch insert") { /* test logic */ }
143
) @@ timeout(30.seconds)
144
145
// Apply multiple aspects
146
suite("Integration Tests")(
147
test("external API call") { /* test logic */ }
148
) @@ timeout(10.seconds) @@ eventually @@ flaky
149
```
150
151
### SpecCase
152
153
Individual test case within a specification.
154
155
```scala { .api }
156
/**
157
* A single test case with metadata
158
* @param label descriptive test name
159
* @param test the test logic as ZIO effect
160
* @param annotations metadata attached to the test
161
*/
162
case class SpecCase[+R, +E](
163
label: String,
164
test: ZIO[R, TestFailure[E], TestSuccess],
165
annotations: TestAnnotationMap
166
)
167
```
168
169
### ZIOSpec Classes
170
171
Base classes for creating test suites with standard patterns.
172
173
```scala { .api }
174
/**
175
* Abstract base class for ZIO test specifications
176
* @tparam R environment type required by tests
177
*/
178
abstract class ZIOSpec[R] {
179
/**
180
* The test specification to execute
181
*/
182
def spec: Spec[R, Any]
183
}
184
185
/**
186
* Base class for test specs with standard test environment
187
*/
188
abstract class ZIOSpecDefault extends ZIOSpec[TestEnvironment] {
189
/**
190
* Test specification using default test environment
191
*/
192
def spec: Spec[TestEnvironment, Any]
193
}
194
```
195
196
**Usage Examples:**
197
198
```scala
199
import zio.test._
200
201
// Using ZIOSpecDefault (recommended)
202
object MyTestSpec extends ZIOSpecDefault {
203
def spec = suite("My Tests")(
204
test("basic test") {
205
assertTrue(1 + 1 == 2)
206
}
207
)
208
}
209
210
// Using ZIOSpec with custom environment
211
object CustomEnvSpec extends ZIOSpec[MyCustomEnv] {
212
def spec = suite("Custom Environment Tests")(
213
test("uses custom service") {
214
for {
215
result <- ZIO.serviceWithZIO[MyCustomService](_.doSomething())
216
} yield assertTrue(result.isSuccess)
217
}
218
)
219
}
220
```
221
222
### Suite Constructor
223
224
Type class for constructing suites from various input types.
225
226
```scala { .api }
227
/**
228
* Type class for constructing test suites from different input types
229
*/
230
trait SuiteConstructor[In] {
231
type OutEnvironment
232
type OutError
233
234
def apply(in: In): Spec[OutEnvironment, OutError]
235
}
236
237
// Instances for common types
238
implicit def functionSuiteConstructor[A, In](implicit
239
constructor: TestConstructor[In]
240
): SuiteConstructor[A => In]
241
242
implicit def specSuiteConstructor[R, E]: SuiteConstructor[Spec[R, E]]
243
```
244
245
## Test Lifecycle and Execution
246
247
### Test Runner Integration
248
249
```scala { .api }
250
/**
251
* Interface for running test specifications
252
*/
253
trait TestRunner[R, E] {
254
def run(spec: Spec[R, E]): ZIO[R, Nothing, ExecutionEvent]
255
}
256
257
object TestRunner {
258
def default[R, E]: TestRunner[R, E]
259
}
260
```
261
262
### Execution Events
263
264
```scala { .api }
265
/**
266
* Events emitted during test execution
267
*/
268
sealed trait ExecutionEvent
269
270
case class Test(labels: List[String], test: Either[TestFailure[Any], TestSuccess]) extends ExecutionEvent
271
case class SuiteStarted(labels: List[String]) extends ExecutionEvent
272
case class SuiteCompleted(labels: List[String]) extends ExecutionEvent
273
case class TestStarted(labels: List[String]) extends ExecutionEvent
274
case class TestCompleted[E](labels: List[String], result: Either[TestFailure[E], TestSuccess]) extends ExecutionEvent
275
```