0
# Hooks
1
2
Test lifecycle hooks for scenario and step-level setup, teardown, and monitoring. Provides comprehensive control over test execution with support for execution order, tag-based filtering, and access to test context through the Scenario object.
3
4
## Capabilities
5
6
### Before and After Scenario Hooks
7
8
Hooks that execute before and after each scenario, with optional access to scenario context.
9
10
```java { .api }
11
/**
12
* Before hooks with Scenario parameter - execute before each scenario
13
* Hooks with higher order values execute first (default order: 1000)
14
*/
15
default void Before(HookBody body) { ... }
16
default void Before(String tagExpression, HookBody body) { ... }
17
default void Before(int order, HookBody body) { ... }
18
default void Before(String tagExpression, int order, HookBody body) { ... }
19
20
/**
21
* Before hooks without parameters - execute before each scenario
22
*/
23
default void Before(HookNoArgsBody body) { ... }
24
default void Before(String tagExpression, HookNoArgsBody body) { ... }
25
default void Before(int order, HookNoArgsBody body) { ... }
26
default void Before(String tagExpression, int order, HookNoArgsBody body) { ... }
27
28
/**
29
* After hooks with Scenario parameter - execute after each scenario
30
* Hooks with higher order values execute first (default order: 1000)
31
*/
32
default void After(HookBody body) { ... }
33
default void After(String tagExpression, HookBody body) { ... }
34
default void After(int order, HookBody body) { ... }
35
default void After(String tagExpression, int order, HookBody body) { ... }
36
37
/**
38
* After hooks without parameters - execute after each scenario
39
*/
40
default void After(HookNoArgsBody body) { ... }
41
default void After(String tagExpression, HookNoArgsBody body) { ... }
42
default void After(int order, HookNoArgsBody body) { ... }
43
default void After(String tagExpression, int order, HookNoArgsBody body) { ... }
44
```
45
46
**Usage Examples:**
47
48
```java
49
import io.cucumber.java8.En;
50
import io.cucumber.java8.Scenario;
51
52
public class HookDefinitions implements En {
53
private WebDriver driver;
54
private Database database;
55
56
public HookDefinitions() {
57
// Basic before hook with scenario access
58
Before((Scenario scenario) -> {
59
System.out.println("Starting scenario: " + scenario.getName());
60
initializeTestData();
61
});
62
63
// Before hook without scenario parameter
64
Before(() -> {
65
setupTestEnvironment();
66
});
67
68
// Before hook with execution order (lower numbers execute first)
69
Before(10, (Scenario scenario) -> {
70
// This executes before hooks with higher order values
71
setupDatabase();
72
});
73
74
// Before hook with tag filtering - only runs for scenarios tagged with @web
75
Before("@web", (Scenario scenario) -> {
76
driver = new ChromeDriver();
77
driver.manage().window().maximize();
78
});
79
80
// Before hook with both order and tags
81
Before(5, "@api", () -> {
82
setupApiClient();
83
});
84
85
// After hook with cleanup logic
86
After((Scenario scenario) -> {
87
if (scenario.isFailed()) {
88
// Capture screenshot on failure
89
if (driver != null) {
90
byte[] screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
91
scenario.attach(screenshot, "image/png", "failure-screenshot");
92
}
93
94
// Log failure details
95
scenario.log("Test failed with status: " + scenario.getStatus());
96
}
97
98
cleanupTestData();
99
});
100
101
// After hook for specific tags
102
After("@web", () -> {
103
if (driver != null) {
104
driver.quit();
105
}
106
});
107
108
// After hook with execution order (higher numbers execute first)
109
After(1000, (Scenario scenario) -> {
110
// This executes before hooks with lower order values
111
generateTestReport(scenario);
112
});
113
}
114
}
115
```
116
117
### Before and After Step Hooks
118
119
Hooks that execute before and after each individual step, useful for detailed monitoring and step-level setup/teardown.
120
121
```java { .api }
122
/**
123
* BeforeStep hooks with Scenario parameter - execute before each step
124
*/
125
default void BeforeStep(HookBody body) { ... }
126
default void BeforeStep(String tagExpression, HookBody body) { ... }
127
default void BeforeStep(int order, HookBody body) { ... }
128
default void BeforeStep(String tagExpression, int order, HookBody body) { ... }
129
130
/**
131
* BeforeStep hooks without parameters - execute before each step
132
*/
133
default void BeforeStep(HookNoArgsBody body) { ... }
134
default void BeforeStep(String tagExpression, HookNoArgsBody body) { ... }
135
default void BeforeStep(int order, HookNoArgsBody body) { ... }
136
default void BeforeStep(String tagExpression, int order, HookNoArgsBody body) { ... }
137
138
/**
139
* AfterStep hooks with Scenario parameter - execute after each step
140
*/
141
default void AfterStep(HookBody body) { ... }
142
default void AfterStep(String tagExpression, HookBody body) { ... }
143
default void AfterStep(int order, HookBody body) { ... }
144
default void AfterStep(String tagExpression, int order, HookBody body) { ... }
145
146
/**
147
* AfterStep hooks without parameters - execute after each step
148
*/
149
default void AfterStep(HookNoArgsBody body) { ... }
150
default void AfterStep(String tagExpression, HookNoArgsBody body) { ... }
151
default void AfterStep(int order, HookNoArgsBody body) { ... }
152
default void AfterStep(String tagExpression, int order, HookNoArgsBody body) { ... }
153
```
154
155
**Usage Examples:**
156
157
```java
158
public class StepHookDefinitions implements En {
159
160
public StepHookDefinitions() {
161
// Log each step execution
162
BeforeStep((Scenario scenario) -> {
163
System.out.println("About to execute step in scenario: " + scenario.getName());
164
});
165
166
// Capture step timing
167
BeforeStep(() -> {
168
stepStartTime = System.currentTimeMillis();
169
});
170
171
// Log step completion and timing
172
AfterStep((Scenario scenario) -> {
173
long duration = System.currentTimeMillis() - stepStartTime;
174
scenario.log("Step completed in " + duration + "ms");
175
});
176
177
// Screenshot after each step for UI tests
178
AfterStep("@ui", (Scenario scenario) -> {
179
if (driver != null) {
180
byte[] screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
181
scenario.attach(screenshot, "image/png", "step-screenshot");
182
}
183
});
184
185
// Monitor for step failures
186
AfterStep((Scenario scenario) -> {
187
if (scenario.isFailed()) {
188
logStepFailure(scenario);
189
}
190
});
191
}
192
}
193
```
194
195
### Hook Body Functional Interfaces
196
197
Functional interfaces defining the lambda signatures for hook implementations.
198
199
```java { .api }
200
/**
201
* Hook body with Scenario parameter providing access to test context
202
*/
203
@FunctionalInterface
204
public interface HookBody {
205
/**
206
* Execute hook with access to scenario information
207
* @param scenario Current scenario context with metadata and utilities
208
* @throws Throwable Any exception during hook execution
209
*/
210
void accept(Scenario scenario) throws Throwable;
211
}
212
213
/**
214
* Hook body without parameters for simple setup/teardown operations
215
*/
216
@FunctionalInterface
217
public interface HookNoArgsBody {
218
/**
219
* Execute hook without scenario context
220
* @throws Throwable Any exception during hook execution
221
*/
222
void accept() throws Throwable;
223
}
224
```
225
226
### Tag Expressions
227
228
Hooks support Cucumber tag expressions for conditional execution based on scenario tags.
229
230
**Tag Expression Syntax:**
231
232
```java
233
// Single tag
234
Before("@web", () -> { ... });
235
236
// Multiple tags with AND
237
Before("@web and @slow", () -> { ... });
238
239
// Multiple tags with OR
240
Before("@web or @api", () -> { ... });
241
242
// Tag negation
243
Before("not @skip", () -> { ... });
244
245
// Complex expressions with parentheses
246
Before("(@web or @mobile) and not @skip", () -> { ... });
247
```
248
249
**Usage Examples:**
250
251
```java
252
public class TaggedHooks implements En {
253
254
public TaggedHooks() {
255
// Run only for web UI tests
256
Before("@web", () -> {
257
setupWebDriver();
258
});
259
260
// Run for API tests but not integration tests
261
Before("@api and not @integration", () -> {
262
setupApiMocks();
263
});
264
265
// Run for either database or performance tests
266
Before("@database or @performance", () -> {
267
setupDatabaseConnection();
268
});
269
270
// Complex conditional setup
271
Before("(@smoke or @regression) and not @skip", (Scenario scenario) -> {
272
setupTestEnvironment(scenario.getSourceTagNames());
273
});
274
}
275
}
276
```
277
278
### Hook Execution Order
279
280
Hooks with the same trigger point (Before/After/BeforeStep/AfterStep) are executed in order based on their order parameter:
281
282
- **Before hooks**: Higher order values execute first (descending order)
283
- **After hooks**: Higher order values execute first (descending order)
284
- **Default order**: 1000 if not specified
285
- **Same order**: Execution order is undefined for hooks with identical order values
286
287
```java
288
public class OrderedHooks implements En {
289
290
public OrderedHooks() {
291
// Execute first (order 2000 - highest)
292
Before(2000, () -> {
293
setupBasicInfrastructure();
294
});
295
296
// Execute second (default order 1000)
297
Before(() -> {
298
setupApplicationServices();
299
});
300
301
// Execute third (order 100 - lowest)
302
Before(100, () -> {
303
setupTestData();
304
});
305
306
// Cleanup in reverse order
307
308
// Execute first after scenario (order 2000 > 1000 > 100)
309
After(2000, () -> {
310
generateReports();
311
});
312
313
// Execute second (default order 1000)
314
After(() -> {
315
cleanupTestData();
316
});
317
318
// Execute last (order 100)
319
After(100, () -> {
320
shutdownApplicationServices();
321
});
322
}
323
}
324
```
325
326
### Hook Constants
327
328
```java { .api }
329
/**
330
* Constants for hook configuration
331
*/
332
public interface LambdaGlue {
333
/** Empty tag expression - matches all scenarios */
334
String EMPTY_TAG_EXPRESSION = "";
335
336
/** Default execution order for Before hooks */
337
int DEFAULT_BEFORE_ORDER = 1000;
338
339
/** Default execution order for After hooks */
340
int DEFAULT_AFTER_ORDER = 1000;
341
}
342
```