0
# Core Testing DSL
1
2
Essential functions and types for creating test specifications and organizing test suites. These form the foundation of all ZIO Test usage.
3
4
## Capabilities
5
6
### Suite Creation
7
8
Creates a labeled test suite containing multiple test specifications.
9
10
```scala { .api }
11
/**
12
* Builds a suite containing a number of other specs
13
* @param label - The name/description of the test suite
14
* @param specs - The test specifications to include in the suite
15
* @return A Spec that represents the test suite
16
*/
17
def suite[In](label: String)(specs: In*)(implicit
18
suiteConstructor: SuiteConstructor[In],
19
sourceLocation: SourceLocation,
20
trace: Trace
21
): Spec[suiteConstructor.OutEnvironment, suiteConstructor.OutError]
22
```
23
24
**Usage Examples:**
25
26
```scala
27
import zio.test._
28
29
// Simple suite with multiple tests
30
suite("Math Operations")(
31
test("addition") {
32
assertTrue(2 + 2 == 4)
33
},
34
test("multiplication") {
35
assertTrue(3 * 4 == 12)
36
}
37
)
38
39
// Nested suites
40
suite("Calculator")(
41
suite("Basic Operations")(
42
test("add") { assertTrue(1 + 1 == 2) },
43
test("subtract") { assertTrue(5 - 3 == 2) }
44
),
45
suite("Advanced Operations")(
46
test("power") { assertTrue(Math.pow(2, 3) == 8) }
47
)
48
)
49
```
50
51
### Test Creation
52
53
Creates a single test with a descriptive label and assertion.
54
55
```scala { .api }
56
/**
57
* Builds a spec with a single test
58
* @param label - The name/description of the test
59
* @param assertion - The test assertion or effectful computation
60
* @return A test specification
61
*/
62
def test[In](label: String)(assertion: => In)(implicit
63
testConstructor: TestConstructor[Nothing, In],
64
sourceLocation: SourceLocation,
65
trace: Trace
66
): testConstructor.Out
67
```
68
69
**Usage Examples:**
70
71
```scala
72
import zio.test._
73
74
// Simple assertion test
75
test("string length") {
76
assertTrue("hello".length == 5)
77
}
78
79
// Effectful test
80
test("async operation") {
81
for {
82
result <- ZIO.succeed(42)
83
_ <- ZIO.sleep(100.millis)
84
} yield assertTrue(result > 40)
85
}
86
87
// Multiple assertions
88
test("list operations") {
89
val numbers = List(1, 2, 3, 4, 5)
90
assertTrue(
91
numbers.contains(3) &&
92
numbers.size == 5 &&
93
numbers.head == 1 &&
94
numbers.last == 5
95
)
96
}
97
```
98
99
### Test Specification Type
100
101
The core type representing test specifications that can be executed.
102
103
```scala { .api }
104
/**
105
* A Spec[R, E] is the backbone of ZIO Test. Every spec is either a suite,
106
* which contains other specs, or a test. All specs require an environment of
107
* type R and may potentially fail with an error of type E.
108
*/
109
final case class Spec[-R, +E](caseValue: SpecCase[R, E, Spec[R, E]]) {
110
/** Combines this spec with the specified spec */
111
def +[R1 <: R, E1 >: E](that: Spec[R1, E1]): Spec[R1, E1]
112
113
/** Apply test aspect to this spec */
114
def @@[R0 <: R1, R1 <: R, E0 >: E, E1 >: E0](
115
aspect: TestAspect[R0, R1, E0, E1]
116
)(implicit trace: Trace): Spec[R1, E0]
117
118
/** Annotate each test with the specified annotation */
119
def annotate[V](key: TestAnnotation[V], value: V)(implicit trace: Trace): Spec[R, E]
120
121
/** Execute this spec with the given execution strategy */
122
def execute(defExec: ExecutionStrategy)(implicit trace: Trace): ZIO[R with Scope, Nothing, Spec[Any, E]]
123
}
124
```
125
126
### ZTest Type
127
128
Type alias for effectfully produced tests.
129
130
```scala { .api }
131
/**
132
* A ZTest[R, E] is an effectfully produced test that requires an R and
133
* may fail with an E.
134
*/
135
type ZTest[-R, +E] = ZIO[R, TestFailure[E], TestSuccess]
136
137
object ZTest {
138
/**
139
* Builds a test with an effectual assertion
140
* @param label - Test label for error reporting
141
* @param assertion - Effectful computation producing TestResult
142
* @return ZIO effect representing the test
143
*/
144
def apply[R, E](label: String, assertion: => ZIO[R, E, TestResult])(implicit
145
trace: Trace
146
): ZIO[R, TestFailure[E], TestSuccess]
147
}
148
```
149
150
### Base Specification Classes
151
152
Abstract base classes for creating test specifications with different environment requirements.
153
154
```scala { .api }
155
/**
156
* Default ZIO spec using standard TestEnvironment
157
*/
158
abstract class ZIOSpecDefault extends ZIOSpec[TestEnvironment] {
159
final type Env = TestEnvironment
160
}
161
162
/**
163
* ZIO spec with custom environment type R
164
*/
165
abstract class ZIOSpec[R] extends ZIOSpecAbstract[R] {
166
type Env = R
167
168
/** The test specification to run */
169
def spec: Spec[R, Any]
170
}
171
172
/**
173
* Abstract base class for all ZIO test specifications
174
*/
175
abstract class ZIOSpecAbstract[R] {
176
/** Layer that provides the test environment */
177
def bootstrap: ZLayer[Any, Any, R] = ZLayer.environment[R]
178
179
/** Test execution aspects to apply */
180
def aspects: Chunk[TestAspectAtLeastR[R]] = Chunk.empty
181
}
182
```
183
184
**Usage Examples:**
185
186
```scala
187
import zio.test._
188
189
// Using ZIOSpecDefault for simple tests
190
object SimpleTest extends ZIOSpecDefault {
191
def spec = suite("Simple Tests")(
192
test("basic") {
193
assertTrue(1 + 1 == 2)
194
}
195
)
196
}
197
198
// Using ZIOSpec with custom environment
199
trait MyService {
200
def getValue: UIO[Int]
201
}
202
203
object CustomTest extends ZIOSpec[MyService] {
204
def spec = suite("Custom Environment Tests")(
205
test("service test") {
206
for {
207
service <- ZIO.service[MyService]
208
value <- service.getValue
209
} yield assertTrue(value > 0)
210
}
211
)
212
213
override def bootstrap = ZLayer.succeed(new MyService {
214
def getValue = ZIO.succeed(42)
215
})
216
}
217
```
218
219
### Test Result Types
220
221
Types representing the outcomes of test execution.
222
223
```scala { .api }
224
/**
225
* Represents successful test execution
226
*/
227
sealed trait TestSuccess
228
229
object TestSuccess {
230
final case class Succeeded(annotations: TestAnnotationMap = TestAnnotationMap.empty) extends TestSuccess
231
final case class Ignored(annotations: TestAnnotationMap = TestAnnotationMap.empty) extends TestSuccess
232
}
233
234
/**
235
* Represents failed test execution
236
*/
237
sealed trait TestFailure[+E]
238
239
object TestFailure {
240
final case class Assertion(result: TestResult) extends TestFailure[Nothing]
241
final case class Runtime[E](cause: Cause[E]) extends TestFailure[E]
242
}
243
244
/**
245
* Result of test assertion evaluation
246
*/
247
case class TestResult(arrow: TestArrow[Any, Boolean]) {
248
/** Whether the assertion succeeded */
249
def isSuccess: Boolean
250
251
/** Whether the assertion failed */
252
def isFailure: Boolean
253
254
/** Combine with another test result using logical AND */
255
def &&(that: TestResult): TestResult
256
257
/** Combine with another test result using logical OR */
258
def ||(that: TestResult): TestResult
259
260
/** Negate this test result */
261
def unary_! : TestResult
262
}
263
```
264
265
### Utility Functions
266
267
Helper functions for test creation and management.
268
269
```scala { .api }
270
/**
271
* Creates a failed test result with the specified runtime cause
272
*/
273
def failed[E](cause: Cause[E])(implicit trace: Trace): ZIO[Any, TestFailure[E], Nothing]
274
275
/**
276
* Creates an ignored test result
277
*/
278
val ignored: UIO[TestSuccess]
279
280
/**
281
* Passes platform specific information to create a test
282
*/
283
def platformSpecific[R, E, A](js: => A, jvm: => A)(f: A => ZTest[R, E]): ZTest[R, E]
284
285
/**
286
* Passes version specific information to create a test
287
*/
288
def versionSpecific[R, E, A](scala3: => A, scala2: => A)(f: A => ZTest[R, E]): ZTest[R, E]
289
290
/**
291
* Provides an effect with the "real" environment as opposed to the test environment
292
*/
293
def live[R, E, A](zio: ZIO[R, E, A])(implicit trace: Trace): ZIO[R, E, A]
294
```