or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-jest-each

Parameterised tests for Jest that enable running the same test multiple times with different data sets using arrays or tagged template literals

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/jest-each@30.1.x

To install, run

npx @tessl/cli install tessl/npm-jest-each@30.1.0

0

# jest-each

1

2

jest-each is a parameterized testing library that enables running the same test multiple times with different data sets. It provides two main approaches: array-based parameterization and tagged template literal syntax with readable table formatting. The library integrates seamlessly with all Jest test functions and modifiers.

3

4

## Package Information

5

6

- **Package Name**: jest-each

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install jest-each`

10

11

## Core Imports

12

13

```typescript

14

import each from "jest-each";

15

```

16

17

For CommonJS:

18

19

```javascript

20

const each = require("jest-each").default;

21

```

22

23

Named imports:

24

25

```typescript

26

import each, { bind } from "jest-each";

27

```

28

29

## Basic Usage

30

31

### Array Format

32

33

```typescript

34

import each from "jest-each";

35

36

// Array of arrays

37

each([

38

[1, 2, 3],

39

[4, 5, 9],

40

[7, 8, 15]

41

]).test('adds %i + %i to equal %i', (a, b, expected) => {

42

expect(a + b).toBe(expected);

43

});

44

45

// Array of objects

46

each([

47

{ name: 'John', age: 25 },

48

{ name: 'Jane', age: 30 }

49

]).test('user $name is $age years old', ({ name, age }) => {

50

expect(typeof name).toBe('string');

51

expect(typeof age).toBe('number');

52

});

53

```

54

55

### Template Literal Format

56

57

```typescript

58

each`

59

a | b | expected

60

${1} | ${2} | ${3}

61

${4} | ${5} | ${9}

62

${7} | ${8} | ${15}

63

`.test('adds $a + $b to equal $expected', ({ a, b, expected }) => {

64

expect(a + b).toBe(expected);

65

});

66

```

67

68

## Capabilities

69

70

### Main Each Function

71

72

Creates parameterized test functions that work with all Jest test methods and modifiers.

73

74

```typescript { .api }

75

/**

76

* Main function to create parameterized tests using arrays or template literals

77

* @param table - Test data as array of arrays, array of objects, or template literal

78

* @param data - Additional template data when using template literals

79

* @returns Object with Jest test methods (test, it, describe, etc.)

80

*/

81

function each(table: EachTable, ...data: TemplateData): {

82

test: EachTestFunction;

83

it: EachTestFunction;

84

describe: EachDescribeFunction;

85

xit: EachTestFunction;

86

fit: EachTestFunction;

87

xtest: EachTestFunction;

88

fdescribe: EachDescribeFunction;

89

xdescribe: EachDescribeFunction;

90

};

91

92

type EachTable = ArrayTable | TemplateTable;

93

type ArrayTable = Table | Row;

94

type Table = ReadonlyArray<Row>;

95

type Row = ReadonlyArray<unknown>;

96

type TemplateTable = TemplateStringsArray;

97

type TemplateData = ReadonlyArray<unknown>;

98

```

99

100

### With Global Context

101

102

Creates each function bound to a specific global context for custom Jest environments.

103

104

```typescript { .api }

105

/**

106

* Creates each function bound to specific global context

107

* @param g - Global Jest context object

108

* @returns Function that accepts table and returns test methods

109

*/

110

each.withGlobal: (g: Global) => (table: EachTable, ...data: TemplateData) => ReturnType<typeof each>;

111

112

interface Global {

113

test: TestFunction;

114

it: TestFunction;

115

describe: DescribeFunction;

116

xit: TestFunction;

117

fit: TestFunction;

118

xtest: TestFunction;

119

fdescribe: DescribeFunction;

120

xdescribe: DescribeFunction;

121

}

122

```

123

124

### Test Function Interface

125

126

All returned test functions support Jest's standard interface with modifiers.

127

128

```typescript { .api }

129

interface EachTestFunction {

130

/**

131

* Creates a parameterized test

132

* @param title - Test title with optional placeholders

133

* @param testFn - Test function receiving parameters from data table

134

* @param timeout - Optional timeout in milliseconds

135

*/

136

(title: string, testFn: EachTestFn<TestFn>, timeout?: number): void;

137

138

/** Run only this test */

139

only: EachTestFunction;

140

141

/** Skip this test */

142

skip: EachTestFunction;

143

144

/** Concurrent test execution */

145

concurrent: EachConcurrentTestFunction;

146

}

147

148

interface EachConcurrentTestFunction {

149

(title: string, testFn: EachTestFn<ConcurrentTestFn>, timeout?: number): void;

150

only: EachConcurrentTestFunction;

151

skip: EachConcurrentTestFunction;

152

}

153

154

interface EachDescribeFunction {

155

/**

156

* Creates a parameterized describe block

157

* @param title - Describe title with optional placeholders

158

* @param suiteFn - Suite function receiving parameters from data table

159

* @param timeout - Optional timeout in milliseconds

160

*/

161

(title: string, suiteFn: EachTestFn<BlockFn>, timeout?: number): void;

162

163

/** Run only this describe block */

164

only: EachDescribeFunction;

165

166

/** Skip this describe block */

167

skip: EachDescribeFunction;

168

}

169

170

type EachTestFn<T extends TestCallback> = (...args: ReadonlyArray<any>) => ReturnType<T>;

171

```

172

173

### Bind Function (Advanced)

174

175

Core binding function for creating custom parameterized test functions.

176

177

```typescript { .api }

178

/**

179

* Creates parameterized test functions by binding to Jest global methods

180

* @param cb - Global Jest callback function to bind to

181

* @param supportsDone - Whether the callback supports done callback (default: true)

182

* @param needsEachError - Whether to pass error context (default: false)

183

* @returns Function that accepts table data and returns bound test function

184

*/

185

function bind<EachCallback extends TestCallback>(

186

cb: GlobalCallback,

187

supportsDone?: boolean,

188

needsEachError?: boolean

189

): EachTestFn<any>;

190

191

type GlobalCallback = (

192

testName: string,

193

fn: ConcurrentTestFn,

194

timeout?: number,

195

eachError?: Error

196

) => void;

197

198

type TestCallback = BlockFn | TestFn | ConcurrentTestFn;

199

```

200

201

## Title Formatting and Interpolation

202

203

### Printf-Style Placeholders

204

205

jest-each supports printf-style placeholders for automatic value formatting in test titles:

206

207

- `%s` - String formatting

208

- `%d`, `%i` - Integer formatting

209

- `%f` - Float formatting

210

- `%j` - JSON formatting

211

- `%o`, `%O` - Object formatting

212

- `%p` - Pretty-print formatting (with depth control)

213

- `%#` - Zero-based index placeholder

214

- `%$` - One-based index placeholder

215

216

```typescript

217

each([

218

[1, 2, 3],

219

[4, 5, 9]

220

]).test('test %# adds %i + %i to equal %i', (a, b, expected) => {

221

expect(a + b).toBe(expected);

222

});

223

// Results in: "test 0 adds 1 + 2 to equal 3", "test 1 adds 4 + 5 to equal 9"

224

```

225

226

### Template Variable Interpolation

227

228

When using template literals or object arrays, variables can be interpolated using `$variable` syntax:

229

230

```typescript

231

each`

232

name | age | status

233

${'John'} | ${25} | ${'active'}

234

${'Jane'} | ${30} | ${'inactive'}

235

`.test('user $name (age $age) is $status', ({ name, age, status }) => {

236

expect(typeof name).toBe('string');

237

});

238

```

239

240

### Object Property Access

241

242

Template variables support deep property access using dot notation:

243

244

```typescript

245

each([

246

{ user: { profile: { name: 'John' }, age: 25 } },

247

{ user: { profile: { name: 'Jane' }, age: 30 } }

248

]).test('user $user.profile.name is $user.age years old', ({ user }) => {

249

expect(user).toBeDefined();

250

});

251

```

252

253

## Data Table Formats

254

255

### Array of Arrays

256

257

Most basic format for simple parameter lists:

258

259

```typescript

260

each([

261

[1, 2, 3], // First test case

262

[4, 5, 9], // Second test case

263

[7, 8, 15] // Third test case

264

]).test('adds %i + %i to equal %i', (a, b, expected) => {

265

expect(a + b).toBe(expected);

266

});

267

```

268

269

### Array of Objects

270

271

Provides named parameters for better readability:

272

273

```typescript

274

each([

275

{ input: 'hello', expected: 5 },

276

{ input: 'world', expected: 5 },

277

{ input: '', expected: 0 }

278

]).test('$input has length $expected', ({ input, expected }) => {

279

expect(input.length).toBe(expected);

280

});

281

```

282

283

### Single Column Arrays

284

285

For tests with single parameters:

286

287

```typescript

288

each([1, 2, 3, 4, 5]).test('number %i is defined', (num) => {

289

expect(num).toBeDefined();

290

expect(typeof num).toBe('number');

291

});

292

```

293

294

### Template Literals

295

296

Tabular format with column headers for maximum readability:

297

298

```typescript

299

each`

300

operation | a | b | expected

301

${'add'} | ${1} | ${2} | ${3}

302

${'sub'} | ${5} | ${3} | ${2}

303

${'mul'} | ${3} | ${4} | ${12}

304

`.test('$operation: $a and $b equals $expected', ({ operation, a, b, expected }) => {

305

switch (operation) {

306

case 'add':

307

expect(a + b).toBe(expected);

308

break;

309

case 'sub':

310

expect(a - b).toBe(expected);

311

break;

312

case 'mul':

313

expect(a * b).toBe(expected);

314

break;

315

}

316

});

317

```

318

319

## Jest Integration

320

321

### Test Methods

322

323

All Jest test methods are supported:

324

325

```typescript

326

each(testData).test('test title', testFn); // Standard test

327

each(testData).test.only('test title', testFn); // Run only this test

328

each(testData).test.skip('test title', testFn); // Skip this test

329

each(testData).test.concurrent('test title', testFn); // Concurrent execution

330

331

each(testData).it('test title', testFn); // Alias for test

332

each(testData).xit('test title', testFn); // Skip test (alias)

333

each(testData).fit('test title', testFn); // Focus test (alias)

334

each(testData).xtest('test title', testFn); // Skip test (alias)

335

```

336

337

### Describe Blocks

338

339

Parameterized describe blocks for grouping related tests:

340

341

```typescript

342

each([

343

{ type: 'user', endpoint: '/users' },

344

{ type: 'post', endpoint: '/posts' }

345

]).describe('$type API', ({ type, endpoint }) => {

346

test('should fetch all items', async () => {

347

const response = await api.get(endpoint);

348

expect(response.status).toBe(200);

349

});

350

351

test('should create new item', async () => {

352

const response = await api.post(endpoint, { name: 'Test' });

353

expect(response.status).toBe(201);

354

});

355

});

356

```

357

358

### Concurrent Test Execution

359

360

Support for concurrent test execution with proper typing:

361

362

```typescript

363

each([

364

{ url: '/api/users/1' },

365

{ url: '/api/users/2' },

366

{ url: '/api/users/3' }

367

]).test.concurrent('fetches data from $url', async ({ url }) => {

368

const response = await fetch(url);

369

expect(response.status).toBe(200);

370

});

371

```

372

373

### Done Callback Support

374

375

Automatic detection and support for Jest's done callback:

376

377

```typescript

378

each([

379

{ delay: 100 },

380

{ delay: 200 }

381

]).test('async test with $delay ms delay', ({ delay }, done) => {

382

setTimeout(() => {

383

expect(delay).toBeGreaterThan(0);

384

done();

385

}, delay);

386

});

387

```

388

389

## Error Handling and Validation

390

391

### Table Validation

392

393

Comprehensive validation with descriptive error messages:

394

395

```typescript

396

// Invalid: empty array

397

each([]).test('title', () => {}); // Throws: "Error: .each called with an empty Array of table data."

398

399

// Invalid: tagged template with no data

400

each``.test('title', () => {}); // Throws: "Error: .each called with an empty Tagged Template Literal of table data."

401

402

// Invalid: not an array or template literal

403

each("invalid").test('title', () => {}); // Throws: ".each must be called with an Array or Tagged Template Literal."

404

```

405

406

### Template Table Validation

407

408

Validation for template literal format and argument count:

409

410

```typescript

411

// Invalid: mismatched arguments

412

each`

413

a | b

414

${1} | ${2}

415

${3} // Missing second argument

416

`.test('title', () => {}); // Throws error with missing argument details

417

```

418

419

## Types

420

421

```typescript { .api }

422

// Core types for data tables

423

type Col = unknown;

424

type Row = ReadonlyArray<Col>;

425

type Table = ReadonlyArray<Row>;

426

type ArrayTable = Table | Row;

427

type TemplateTable = TemplateStringsArray;

428

type TemplateData = ReadonlyArray<unknown>;

429

type EachTable = ArrayTable | TemplateTable;

430

431

// Test function types

432

type ValidTestReturnValues = void | undefined;

433

type TestReturnValue = ValidTestReturnValues | Promise<unknown>;

434

type DoneFn = (reason?: string | Error) => void;

435

436

type TestFn = PromiseReturningTestFn | GeneratorReturningTestFn | DoneTakingTestFn;

437

type PromiseReturningTestFn = (this: TestContext) => TestReturnValue;

438

type DoneTakingTestFn = (this: TestContext, done: DoneFn) => ValidTestReturnValues;

439

type ConcurrentTestFn = () => Promise<unknown>;

440

type BlockFn = () => void;

441

442

// Generic test function type for parameterized tests

443

type EachTestFn<EachCallback extends TestCallback> = (

444

...args: ReadonlyArray<any>

445

) => ReturnType<EachCallback>;

446

447

// Template and interpolation types

448

type Template = Record<string, unknown>;

449

type Templates = Array<Template>;

450

type Headings = Array<string>;

451

452

// Internal test case representation

453

type EachTests = ReadonlyArray<{

454

title: string;

455

arguments: ReadonlyArray<unknown>;

456

}>;

457

```