0
# SBT Framework Integration
1
2
This document covers ZIO Test SBT's implementation of the SBT test framework interface, including test discovery and framework registration.
3
4
## ZTestFramework
5
6
The main framework class that SBT uses to integrate with ZIO tests.
7
8
```scala { .api }
9
class ZTestFramework extends sbt.testing.Framework {
10
val name: String
11
val fingerprints: Array[sbt.testing.Fingerprint]
12
def runner(args: Array[String], remoteArgs: Array[String], testClassLoader: ClassLoader): sbt.testing.Runner
13
}
14
```
15
16
### Properties
17
18
- `name`: Returns the framework display name `"ZIO Test"` with ANSI formatting
19
- `fingerprints`: Array containing `ZioSpecFingerprint` for test discovery
20
21
### Methods
22
23
#### runner
24
25
Creates platform-appropriate test runners:
26
- **JVM**: Returns `ZTestRunnerJVM` instance
27
- **JavaScript**: Returns `ZMasterTestRunnerJS` instance
28
- **Native**: Returns `ZMasterTestRunner` instance
29
30
**Parameters:**
31
- `args`: Command-line arguments passed to the test framework
32
- `remoteArgs`: Arguments for remote test execution (distributed testing)
33
- `testClassLoader`: ClassLoader for loading test classes
34
35
## ZioSpecFingerprint
36
37
Enables SBT to discover ZIO test classes by identifying `ZIOSpecAbstract` subclasses.
38
39
```scala { .api }
40
object ZioSpecFingerprint extends sbt.testing.SubclassFingerprint {
41
def superclassName(): String
42
def isModule(): Boolean
43
def requireNoArgConstructor(): Boolean
44
}
45
```
46
47
### Methods
48
49
#### superclassName
50
51
Returns the fully qualified name of the base class that SBT should look for: `zio.test.ZIOSpecAbstract`.
52
53
```scala
54
ZioSpecFingerprint.superclassName()
55
// Returns: "zio.test.ZIOSpecAbstract"
56
```
57
58
#### isModule
59
60
Indicates that ZIO specs are typically implemented as Scala objects (modules), not classes.
61
62
```scala
63
ZioSpecFingerprint.isModule()
64
// Returns: true
65
```
66
67
#### requireNoArgConstructor
68
69
Specifies that ZIO specs don't require no-argument constructors since they're objects.
70
71
```scala
72
ZioSpecFingerprint.requireNoArgConstructor()
73
// Returns: false
74
```
75
76
## Platform-Specific Framework Behavior
77
78
### JVM Framework
79
80
The JVM implementation provides the full feature set:
81
82
```scala { .api }
83
final class ZTestFramework extends sbt.testing.Framework {
84
override val name: String = s"${Console.UNDERLINED}ZIO Test${Console.RESET}"
85
val fingerprints: Array[sbt.testing.Fingerprint] = Array(ZioSpecFingerprint)
86
override def runner(args: Array[String], remoteArgs: Array[String], testClassLoader: ClassLoader): ZTestRunnerJVM
87
}
88
```
89
90
### JavaScript Framework
91
92
JavaScript implementation supports both master and slave runner patterns for distributed testing:
93
94
```scala { .api }
95
final class ZTestFramework extends sbt.testing.Framework {
96
override final val name: String = s"${Console.UNDERLINED}ZIO Test${Console.RESET}"
97
val fingerprints: Array[sbt.testing.Fingerprint] = Array(ZioSpecFingerprint)
98
99
override def runner(args: Array[String], remoteArgs: Array[String], testClassLoader: ClassLoader): sbt.testing.Runner
100
101
override def slaveRunner(
102
args: Array[String],
103
remoteArgs: Array[String],
104
testClassLoader: ClassLoader,
105
send: String => Unit
106
): sbt.testing.Runner
107
}
108
```
109
110
### Native Framework
111
112
Similar to JavaScript but with platform-specific optimizations:
113
114
```scala { .api }
115
final class ZTestFramework extends sbt.testing.Framework {
116
override def name(): String = s"${Console.UNDERLINED}ZIO Test${Console.RESET}"
117
override def fingerprints(): Array[sbt.testing.Fingerprint] = Array(ZioSpecFingerprint)
118
119
override def runner(args: Array[String], remoteArgs: Array[String], testClassLoader: ClassLoader): sbt.testing.Runner
120
121
override def slaveRunner(
122
args: Array[String],
123
remoteArgs: Array[String],
124
testClassLoader: ClassLoader,
125
send: String => Unit
126
): sbt.testing.Runner
127
}
128
```
129
130
## Usage Examples
131
132
### Basic SBT Configuration
133
134
```scala
135
// build.sbt
136
testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework")
137
138
libraryDependencies += "dev.zio" %% "zio-test-sbt" % "2.1.19" % Test
139
```
140
141
### Custom Framework Registration
142
143
For advanced scenarios where you need to programmatically register the framework:
144
145
```scala
146
import sbt.testing._
147
148
val framework = new zio.test.sbt.ZTestFramework()
149
val fingerprints = framework.fingerprints
150
151
// Verify framework can discover ZIO specs
152
fingerprints.foreach { fingerprint =>
153
println(s"Looking for: ${fingerprint match {
154
case sf: SubclassFingerprint => sf.superclassName()
155
case af: AnnotatedFingerprint => af.annotationName()
156
}}")
157
}
158
```
159
160
## Integration Notes
161
162
- The framework automatically detects ZIO test specs without requiring explicit registration
163
- Test discovery happens at compile time through SBT's fingerprinting mechanism
164
- The framework supports SBT's parallel test execution capabilities
165
- Cross-platform compatibility ensures consistent behavior across JVM, JS, and Native platforms