or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdcore-api.mdcore-classes.mdfactories.mdindex.mdplugins.mdreporters.mdtest-management.md
tile.json

test-management.mddocs/

0

# Test Management

1

2

Advanced test creation, grouping, and macro functionality for organizing complex test suites.

3

4

## Capabilities

5

6

### Test Groups

7

8

Create organized groups of related tests with shared setup, teardown, and configuration.

9

10

```typescript { .api }

11

/**

12

* Create a Japa test group

13

* @param title - Group title

14

* @param callback - Function that receives the group instance for configuration

15

* @returns Group instance

16

*/

17

test.group(title: string, callback: (group: Group) => void): Group;

18

19

interface Group {

20

add(test: Test): void;

21

bail(toggle?: boolean): this;

22

timeout(duration: number): this;

23

retry(count: number): this;

24

setup(handler: GroupHooksHandler<TestContext>): this;

25

teardown(handler: GroupHooksHandler<TestContext>): this;

26

each: {

27

setup(handler: GroupHooksHandler<TestContext>): Group;

28

teardown(handler: GroupHooksHandler<TestContext>): Group;

29

};

30

tap(handler: (test: Test) => void): this;

31

}

32

33

type GroupHooksHandler<Context> = (context: Context) => void | Promise<void>;

34

```

35

36

**Usage Examples:**

37

38

```typescript

39

import { test } from "@japa/runner";

40

import { assert } from "chai";

41

42

test.group("User Authentication", (group) => {

43

let authService: AuthService;

44

45

// Setup before all tests in group

46

group.setup(async () => {

47

authService = new AuthService();

48

await authService.initialize();

49

});

50

51

// Teardown after all tests in group

52

group.teardown(async () => {

53

await authService.cleanup();

54

});

55

56

// Setup before each test in group

57

group.each.setup(async ({ context }) => {

58

context.user = await createTestUser();

59

});

60

61

// Teardown after each test in group

62

group.each.teardown(async ({ context }) => {

63

await deleteTestUser(context.user.id);

64

});

65

66

test("should login with valid credentials", async (ctx) => {

67

const result = await authService.login(ctx.context.user.email, "password");

68

assert.isTrue(result.success);

69

});

70

71

test("should reject invalid credentials", async (ctx) => {

72

const result = await authService.login("invalid@email.com", "wrong");

73

assert.isFalse(result.success);

74

});

75

});

76

77

// Group with timeout and retry configuration

78

test.group("API Integration Tests", (group) => {

79

group.timeout(10000);

80

group.retry(2);

81

82

test("should fetch user data", async (ctx) => {

83

// Test logic here

84

});

85

});

86

```

87

88

### Test Macros

89

90

Create reusable test bound macros that can access the currently executed test.

91

92

```typescript { .api }

93

/**

94

* Create a test bound macro. Within the macro, you can access the

95

* currently executed test to read its context values or define cleanup hooks.

96

* @param callback - Macro function that receives the test instance as first parameter

97

* @returns Function that can be called within tests

98

*/

99

test.macro<T extends (test: Test, ...args: any[]) => any>(

100

callback: T

101

): (...args: OmitFirstArg<Parameters<T>>) => ReturnType<T>;

102

103

type OmitFirstArg<F> = F extends [_: any, ...args: infer R] ? R : never;

104

```

105

106

**Usage Examples:**

107

108

```typescript

109

import { test } from "@japa/runner";

110

import { assert } from "chai";

111

112

// Create a macro for database operations

113

const withDatabase = test.macro((test: Test, tableName: string) => {

114

test.setup(async () => {

115

await createTable(tableName);

116

});

117

118

test.cleanup(async () => {

119

await dropTable(tableName);

120

});

121

122

return {

123

async insert(data: any) {

124

return await db.table(tableName).insert(data);

125

},

126

async find(id: number) {

127

return await db.table(tableName).find(id);

128

},

129

};

130

});

131

132

// Create a macro for API testing

133

const withApiClient = test.macro((test: Test, baseUrl: string) => {

134

let client: ApiClient;

135

136

test.setup(() => {

137

client = new ApiClient(baseUrl);

138

});

139

140

test.cleanup(async () => {

141

await client.close();

142

});

143

144

return client;

145

});

146

147

// Use macros in tests

148

test("should create and retrieve user", async (ctx) => {

149

const db = withDatabase("users");

150

const api = withApiClient("http://localhost:3000");

151

152

const user = await db.insert({ name: "John", email: "john@example.com" });

153

const retrieved = await db.find(user.id);

154

155

assert.equal(retrieved.name, "John");

156

});

157

```

158

159

### Active Test Management

160

161

Functions to access and manage the currently executing test.

162

163

```typescript { .api }

164

/**

165

* Get the currently running test instance

166

* @returns Current test instance or undefined if not in test context

167

*/

168

function getActiveTest(): Test<any> | undefined;

169

170

/**

171

* Get the currently running test instance or throw an error

172

* @returns Current test instance

173

* @throws Error if not in test context

174

*/

175

function getActiveTestOrFail(): Test<any>;

176

```

177

178

**Usage Examples:**

179

180

```typescript

181

import { test, getActiveTest, getActiveTestOrFail } from "@japa/runner";

182

import { assert } from "chai";

183

184

// Helper function that works with current test

185

function addTestMetadata(key: string, value: any) {

186

const currentTest = getActiveTest();

187

if (currentTest) {

188

currentTest.options.meta[key] = value;

189

}

190

}

191

192

// Macro that uses active test

193

const trackTestExecution = test.macro(() => {

194

const currentTest = getActiveTestOrFail();

195

const startTime = Date.now();

196

197

currentTest.cleanup(() => {

198

const duration = Date.now() - startTime;

199

console.log(`Test "${currentTest.title}" took ${duration}ms`);

200

});

201

});

202

203

test("performance test", async (ctx) => {

204

trackTestExecution();

205

addTestMetadata("category", "performance");

206

207

// Test logic here

208

await someAsyncOperation();

209

assert.isTrue(true);

210

});

211

```

212

213

## Types

214

215

### Group Types

216

217

```typescript { .api }

218

interface Group {

219

add(test: Test): void;

220

bail(toggle?: boolean): this;

221

timeout(duration: number): this;

222

retry(count: number): this;

223

setup(handler: GroupHooksHandler<TestContext>): this;

224

teardown(handler: GroupHooksHandler<TestContext>): this;

225

each: {

226

setup(handler: GroupHooksHandler<TestContext>): Group;

227

teardown(handler: GroupHooksHandler<TestContext>): Group;

228

};

229

tap(handler: (test: Test) => void): this;

230

}

231

232

type GroupHooksHandler<Context> = (context: Context) => void | Promise<void>;

233

```

234

235

### Macro Types

236

237

```typescript { .api }

238

type OmitFirstArg<F> = F extends [_: any, ...args: infer R] ? R : never;

239

```