or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

assertions.mdindex.mdlifecycle-hooks.mdmocking.mdsubprocess-testing.mdtest-organization.md

test-organization.mddocs/

0

# Test Organization

1

2

Test creation, skipping, planning, and control flow management for organizing test suites with comprehensive test lifecycle control.

3

4

## Capabilities

5

6

### Test Creation

7

8

Core methods for creating and organizing tests with various execution strategies.

9

10

```typescript { .api }

11

/**

12

* Create a new test with the given name and function

13

* @param name - Descriptive name for the test

14

* @param fn - Test function to execute

15

* @returns Promise that resolves when test completes

16

*/

17

function test(name: string, fn?: TestFunction): Promise<void>;

18

19

/**

20

* Create a new test with options

21

* @param name - Descriptive name for the test

22

* @param options - Test configuration options

23

* @param fn - Test function to execute

24

* @returns Promise that resolves when test completes

25

*/

26

function test(name: string, options: TestOpts, fn?: TestFunction): Promise<void>;

27

28

/**

29

* Skip a test - it won't be executed but will appear in output

30

* @param name - Descriptive name for the skipped test

31

* @param fn - Test function (not executed)

32

* @returns Promise that resolves immediately

33

*/

34

function skip(name: string, fn?: TestFunction): Promise<void>;

35

36

/**

37

* Skip a test with options

38

* @param name - Descriptive name for the skipped test

39

* @param options - Test configuration options

40

* @param fn - Test function (not executed)

41

* @returns Promise that resolves immediately

42

*/

43

function skip(name: string, options: TestOpts, fn?: TestFunction): Promise<void>;

44

45

/**

46

* Mark a test as todo - it will run but failures won't cause test suite to fail

47

* @param name - Descriptive name for the todo test

48

* @param fn - Test function to execute

49

* @returns Promise that resolves when test completes

50

*/

51

function todo(name: string, fn?: TestFunction): Promise<void>;

52

53

/**

54

* Mark a test as todo with options

55

* @param name - Descriptive name for the todo test

56

* @param options - Test configuration options

57

* @param fn - Test function to execute

58

* @returns Promise that resolves when test completes

59

*/

60

function todo(name: string, options: TestOpts, fn?: TestFunction): Promise<void>;

61

62

/**

63

* Run only this test (requires filter plugin) - other tests will be skipped

64

* @param name - Descriptive name for the test

65

* @param fn - Test function to execute

66

* @returns Promise that resolves when test completes

67

*/

68

function only(name: string, fn?: TestFunction): Promise<void>;

69

70

/**

71

* Run only this test with options

72

* @param name - Descriptive name for the test

73

* @param options - Test configuration options

74

* @param fn - Test function to execute

75

* @returns Promise that resolves when test completes

76

*/

77

function only(name: string, options: TestOpts, fn?: TestFunction): Promise<void>;

78

```

79

80

**Usage Examples:**

81

82

```typescript

83

import { test, skip, todo, only } from "tap";

84

85

// Basic test

86

test("addition works", (t) => {

87

t.equal(2 + 2, 4);

88

t.end();

89

});

90

91

// Test with options

92

test("async test", { timeout: 5000 }, async (t) => {

93

const result = await asyncOperation();

94

t.ok(result.success);

95

});

96

97

// Skip a test

98

skip("not implemented yet", (t) => {

99

// This won't run

100

t.fail("should not run");

101

t.end();

102

});

103

104

// Todo test - runs but failures don't fail the suite

105

todo("fix this later", (t) => {

106

t.fail("known issue"); // Won't cause suite failure

107

t.end();

108

});

109

110

// Only run this test (requires --only flag or filter plugin)

111

only("debug this test", (t) => {

112

t.ok(true);

113

t.end();

114

});

115

```

116

117

### Test Control

118

119

Methods for controlling test execution flow and planning.

120

121

```typescript { .api }

122

/**

123

* Set the expected number of assertions in this test

124

* @param count - Number of assertions expected

125

*/

126

function plan(count: number): void;

127

128

/**

129

* Explicitly end the test - useful for async tests

130

*/

131

function end(): void;

132

133

/**

134

* Bail out of the entire test run with an optional reason

135

* @param reason - Optional reason for bailing out

136

*/

137

function bailout(reason?: string): void;

138

139

/**

140

* Set timeout for the current test in milliseconds

141

* @param ms - Timeout in milliseconds

142

*/

143

function timeout(ms: number): void;

144

145

/**

146

* Add a comment to the TAP output stream

147

* @param message - Comment message

148

*/

149

function comment(message: string): void;

150

151

/**

152

* Add a pragma directive to the TAP output

153

* @param pragma - Pragma directive

154

*/

155

function pragma(pragma: string): void;

156

```

157

158

**Usage Examples:**

159

160

```typescript

161

// Planned test - expects exactly 3 assertions

162

test("planned test", (t) => {

163

t.plan(3);

164

t.ok(true, "first assertion");

165

t.ok(true, "second assertion");

166

t.ok(true, "third assertion");

167

// Test ends automatically after 3 assertions

168

});

169

170

// Explicit end for async tests

171

test("async test with explicit end", (t) => {

172

setTimeout(() => {

173

t.ok(true, "delayed assertion");

174

t.end(); // Explicitly end the test

175

}, 100);

176

});

177

178

// Test with timeout

179

test("timeout test", (t) => {

180

t.timeout(1000); // 1 second timeout

181

// Test will fail if it takes longer than 1 second

182

t.ok(true);

183

t.end();

184

});

185

186

// Adding comments and pragmas

187

test("documented test", (t) => {

188

t.comment("Starting the test");

189

t.pragma("version 14");

190

t.ok(true);

191

t.comment("Test completed successfully");

192

t.end();

193

});

194

195

// Bail out example (use sparingly)

196

test("critical test", (t) => {

197

if (!criticalCondition) {

198

t.bailout("Critical condition not met, cannot continue");

199

return;

200

}

201

t.ok(true);

202

t.end();

203

});

204

```

205

206

### Nested Tests

207

208

TAP supports nested test structures for organizing related tests.

209

210

```typescript

211

test("parent test", (t) => {

212

t.test("child test 1", (ct) => {

213

ct.ok(true, "child assertion");

214

ct.end();

215

});

216

217

t.test("child test 2", (ct) => {

218

ct.equal(1 + 1, 2, "math works in child");

219

ct.end();

220

});

221

222

t.end();

223

});

224

```

225

226

### Test Options

227

228

```typescript { .api }

229

interface TestOpts {

230

/** Override the test name */

231

name?: string;

232

233

/** Timeout in milliseconds for this test */

234

timeout?: number;

235

236

/** Skip this test (boolean or reason string) */

237

skip?: boolean | string;

238

239

/** Mark as todo (boolean or reason string) */

240

todo?: boolean | string;

241

242

/** Run only this test (requires filter plugin) */

243

only?: boolean;

244

245

/** Bail out on first failure in this test */

246

bail?: boolean;

247

248

/** Run test even if parent test fails */

249

autoend?: boolean;

250

251

/** Buffer output until test completes */

252

buffered?: boolean;

253

}

254

255

type TestFunction = (t: TAP) => void | Promise<void>;

256

```

257

258

**Usage Examples:**

259

260

```typescript

261

// Test with multiple options

262

test("complex test", {

263

timeout: 5000,

264

skip: process.env.SKIP_SLOW_TESTS === "true",

265

bail: true

266

}, async (t) => {

267

await complexAsyncOperation();

268

t.ok(true);

269

t.end();

270

});

271

272

// Conditional skip

273

test("platform specific test", {

274

skip: process.platform === "win32" ? "Not supported on Windows" : false

275

}, (t) => {

276

t.ok(true);

277

t.end();

278

});

279

280

// Todo with reason

281

test("future feature", {

282

todo: "Waiting for API changes"

283

}, (t) => {

284

t.ok(false, "This will fail but won't fail the suite");

285

t.end();

286

});

287

```

288

289

### Subtests vs Top-Level Tests

290

291

TAP distinguishes between top-level tests and subtests:

292

293

```typescript

294

// Top-level test - runs in its own process

295

test("top level", (t) => {

296

// This runs in a separate process

297

t.ok(true);

298

299

// Subtest - runs in the same process as parent

300

t.test("subtest", (st) => {

301

st.ok(true);

302

st.end();

303

});

304

305

t.end();

306

});

307

```

308

309

### Test Filtering

310

311

When using the filter plugin, you can control which tests run:

312

313

```typescript

314

// Only run tests marked with 'only'

315

test("normal test", (t) => {

316

// Skipped when --only is used

317

t.ok(true);

318

t.end();

319

});

320

321

only("focused test", (t) => {

322

// Only this runs when --only is used

323

t.ok(true);

324

t.end();

325

});

326

```

327

328

### Asynchronous Test Patterns

329

330

TAP supports several patterns for async testing:

331

332

```typescript

333

// Promise-based test

334

test("promise test", async (t) => {

335

const result = await fetchData();

336

t.ok(result.success);

337

// No need to call t.end() with async functions

338

});

339

340

// Callback-based test with explicit end

341

test("callback test", (t) => {

342

fetchDataWithCallback((err, result) => {

343

t.error(err);

344

t.ok(result.success);

345

t.end(); // Must call end() for non-async functions

346

});

347

});

348

349

// Mixed async/sync with planning

350

test("mixed test", (t) => {

351

t.plan(2);

352

t.ok(true, "sync assertion");

353

354

setTimeout(() => {

355

t.ok(true, "async assertion");

356

// Test ends after 2 assertions due to plan

357

}, 100);

358

});

359

```