or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdcli-usage.mdindex.mdreporters.mdtest-writing.md
tile.json

test-writing.mddocs/

0

# Test Writing

1

2

Core BDD functions for writing test suites and specifications with jasmine-node. Includes support for test organization, setup/teardown, assertions, spies, and asynchronous testing.

3

4

## Capabilities

5

6

### Test Suite Definition

7

8

Define test suites using the describe function to group related specifications.

9

10

```javascript { .api }

11

/**

12

* Define a test suite with a descriptive name and specification functions

13

* @param description - Descriptive name for the test suite

14

* @param specDefinitions - Function containing it() calls and setup

15

*/

16

function describe(description: string, specDefinitions: () => void): void;

17

18

/**

19

* Skip/disable a test suite (will not be executed)

20

* @param description - Descriptive name for the skipped test suite

21

* @param specDefinitions - Function containing it() calls and setup

22

*/

23

function xdescribe(description: string, specDefinitions: () => void): void;

24

```

25

26

**Usage Examples:**

27

28

```javascript

29

describe("User Authentication", function() {

30

// Test specifications go here

31

it("should validate user credentials", function() {

32

// Test implementation

33

});

34

35

describe("Password Reset", function() {

36

// Nested describe blocks for sub-functionality

37

it("should send reset email", function() {

38

// Test implementation

39

});

40

});

41

});

42

43

// Skip entire test suite during development/debugging

44

xdescribe("Feature Under Development", function() {

45

it("should work eventually", function() {

46

// This won't run

47

});

48

});

49

```

50

51

### Test Specification

52

53

Define individual test specifications within describe blocks.

54

55

```javascript { .api }

56

/**

57

* Define a test specification with optional timeout

58

* @param description - Descriptive name for the test

59

* @param specFunction - Test function, optionally accepting done callback

60

* @param timeout - Optional timeout in milliseconds (default: 5000)

61

*/

62

function it(description: string, specFunction: (done?: () => void) => void, timeout?: number): void;

63

64

/**

65

* Skip/disable a test specification (will not be executed)

66

* @param description - Descriptive name for the skipped test

67

* @param specFunction - Test function that won't be executed

68

*/

69

function xit(description: string, specFunction: () => void): void;

70

```

71

72

**Usage Examples:**

73

74

```javascript

75

describe("Calculator", function() {

76

it("should add two numbers", function() {

77

const result = add(2, 3);

78

expect(result).toEqual(5);

79

});

80

81

it("should handle async operations", function(done) {

82

setTimeout(function() {

83

expect(true).toBe(true);

84

done();

85

}, 100);

86

});

87

88

it("should timeout after custom duration", function(done) {

89

// This test will timeout after 1 second instead of default 5 seconds

90

setTimeout(done, 500);

91

}, 1000);

92

93

it("should handle async errors", function(done) {

94

setTimeout(function() {

95

try {

96

expect(false).toBe(true);

97

done();

98

} catch (error) {

99

done(error); // Pass error to done() to fail the test

100

}

101

}, 100);

102

});

103

104

// Skip this test during development

105

xit("should handle edge case", function() {

106

// This won't run

107

});

108

});

109

```

110

111

### Setup and Teardown

112

113

Functions to run setup and teardown code before and after each test specification.

114

115

```javascript { .api }

116

/**

117

* Run setup function before each test specification in the suite

118

* @param setupFunction - Function to run before each test, optionally accepting done callback

119

* @param timeout - Optional timeout in milliseconds for async setup

120

*/

121

function beforeEach(setupFunction: (done?: () => void) => void, timeout?: number): void;

122

123

/**

124

* Run teardown function after each test specification in the suite

125

* @param teardownFunction - Function to run after each test, optionally accepting done callback

126

* @param timeout - Optional timeout in milliseconds for async teardown

127

*/

128

function afterEach(teardownFunction: (done?: () => void) => void, timeout?: number): void;

129

```

130

131

**Usage Examples:**

132

133

```javascript

134

describe("Database Operations", function() {

135

let database;

136

137

beforeEach(function() {

138

database = new MockDatabase();

139

database.connect();

140

});

141

142

afterEach(function() {

143

database.disconnect();

144

database = null;

145

});

146

147

// Async setup and teardown

148

beforeEach(function(done) {

149

initializeTestData(function() {

150

done();

151

});

152

});

153

154

afterEach(function(done) {

155

cleanupTestData(function() {

156

done();

157

});

158

});

159

160

it("should save user data", function() {

161

const user = { name: "John", email: "john@example.com" };

162

const result = database.save(user);

163

expect(result.success).toBe(true);

164

});

165

});

166

```

167

168

### Expectations and Matchers

169

170

Create expectations and assertions using the expect function and built-in matchers.

171

172

```javascript { .api }

173

/**

174

* Create an expectation for testing actual values

175

* @param actual - The actual value to test

176

* @returns Matchers object with assertion methods

177

*/

178

function expect(actual: any): jasmine.Matchers;

179

180

interface jasmine.Matchers {

181

/** Assert strict equality (===) */

182

toBe(expected: any): boolean;

183

/** Assert deep equality for objects and arrays */

184

toEqual(expected: any): boolean;

185

/** Assert string or regex match */

186

toMatch(expected: string | RegExp): boolean;

187

/** Assert value is null */

188

toBeNull(): boolean;

189

/** Assert value is undefined */

190

toBeUndefined(): boolean;

191

/** Assert value is truthy */

192

toBeTruthy(): boolean;

193

/** Assert value is falsy */

194

toBeFalsy(): boolean;

195

/** Assert array/string contains value */

196

toContain(expected: any): boolean;

197

/** Assert numeric greater than */

198

toBeGreaterThan(expected: number): boolean;

199

/** Assert numeric less than */

200

toBeLessThan(expected: number): boolean;

201

/** Assert function throws exception */

202

toThrow(expected?: any): boolean;

203

/** Assert spy was called (from jasmine-reporters) */

204

toHaveBeenCalled(): boolean;

205

/** Assert spy was called with specific arguments (from jasmine-reporters) */

206

toHaveBeenCalledWith(...args: any[]): boolean;

207

/** Negate any matcher */

208

not: jasmine.Matchers;

209

}

210

```

211

212

**Usage Examples:**

213

214

```javascript

215

describe("Matchers", function() {

216

it("should demonstrate basic matchers", function() {

217

expect(5).toBe(5); // Strict equality

218

expect({name: "John"}).toEqual({name: "John"}); // Deep equality

219

expect("hello world").toMatch(/world/); // Regex match

220

expect(null).toBeNull(); // Null check

221

expect(undefined).toBeUndefined(); // Undefined check

222

expect("truthy").toBeTruthy(); // Truthy check

223

expect(0).toBeFalsy(); // Falsy check

224

expect([1, 2, 3]).toContain(2); // Array contains

225

expect(10).toBeGreaterThan(5); // Numeric comparison

226

expect(3).toBeLessThan(10); // Numeric comparison

227

});

228

229

it("should demonstrate negation", function() {

230

expect(5).not.toBe(10);

231

expect("hello").not.toMatch(/goodbye/);

232

});

233

234

it("should test exceptions", function() {

235

expect(function() {

236

throw new Error("Something went wrong");

237

}).toThrow();

238

239

expect(function() {

240

throw new Error("Specific error");

241

}).toThrow("Specific error");

242

});

243

});

244

```

245

246

### Spies and Mocking

247

248

Create spies for testing function calls, arguments, and return values.

249

250

```javascript { .api }

251

/**

252

* Create a spy on an object method to track calls and control behavior

253

* @param object - Object containing the method to spy on

254

* @param method - Method name to spy on

255

* @returns Spy object with tracking and stubbing methods

256

*/

257

function spyOn(object: any, method: string): jasmine.Spy;

258

259

interface jasmine.Spy {

260

/** Make spy return specific value */

261

andReturn(value: any): jasmine.Spy;

262

/** Make spy throw specific exception */

263

andThrow(exception: any): jasmine.Spy;

264

/** Make spy call through to original method */

265

andCallThrough(): jasmine.Spy;

266

/** Make spy call fake function instead */

267

andCallFake(fakeFunction: Function): jasmine.Spy;

268

/** Array of all call objects */

269

calls: any[];

270

/** Most recent call object with args */

271

mostRecentCall: { args: any[] };

272

/** Array of argument arrays for each call */

273

argsForCall: any[][];

274

/** Number of times spy was called */

275

callCount: number;

276

}

277

```

278

279

**Usage Examples:**

280

281

```javascript

282

describe("User Service", function() {

283

let userService, httpClient;

284

285

beforeEach(function() {

286

httpClient = {

287

get: function() {},

288

post: function() {}

289

};

290

userService = new UserService(httpClient);

291

});

292

293

it("should call HTTP client with correct URL", function() {

294

spyOn(httpClient, 'get').andReturn({id: 1, name: "John"});

295

296

const user = userService.getUser(123);

297

298

expect(httpClient.get).toHaveBeenCalled();

299

expect(httpClient.get).toHaveBeenCalledWith('/users/123');

300

expect(httpClient.get.callCount).toBe(1);

301

expect(user.name).toBe("John");

302

});

303

304

it("should handle errors from HTTP client", function() {

305

spyOn(httpClient, 'get').andThrow(new Error("Network error"));

306

307

expect(function() {

308

userService.getUser(123);

309

}).toThrow("Network error");

310

});

311

312

it("should use fake implementation", function() {

313

spyOn(httpClient, 'post').andCallFake(function(url, data) {

314

return { success: true, id: 999 };

315

});

316

317

const result = userService.createUser({name: "Jane"});

318

expect(result.id).toBe(999);

319

});

320

});

321

```

322

323

### Asynchronous Testing

324

325

jasmine-node provides multiple patterns for handling asynchronous operations in tests. The primary approach uses the `done` callback pattern, with additional support for waits, waitsFor, and runs.

326

327

```javascript { .api }

328

/**

329

* Wait for asynchronous condition to become true

330

* @param latchFunction - Function that returns true when condition is met

331

* @param timeoutMessage - Message to display if timeout occurs

332

* @param timeout - Timeout in milliseconds (default: 5000)

333

*/

334

function waitsFor(latchFunction: () => boolean, timeoutMessage?: string, timeout?: number): void;

335

336

/**

337

* Wait for specified duration

338

* @param timeout - Time to wait in milliseconds

339

*/

340

function waits(timeout: number): void;

341

342

/**

343

* Execute function in test context (used with waits/waitsFor)

344

* @param asyncMethod - Function to execute

345

*/

346

function runs(asyncMethod: () => void): void;

347

```

348

349

#### Done Callback Pattern

350

351

jasmine-node enhances the standard Jasmine framework with automatic detection of asynchronous specs. When a test function accepts a parameter (typically named `done`), jasmine-node automatically treats it as an asynchronous test and provides a callback function that must be called to complete the test.

352

353

The async callback implementation wraps the original test function and:

354

- Detects when a function parameter is present (indicating async)

355

- Provides a `done()` callback that marks the test as complete

356

- Automatically fails the test if `done()` is not called within the timeout period

357

- Supports error handling by passing an error to `done(error)`

358

359

**Usage Examples:**

360

361

```javascript

362

describe("Async Operations", function() {

363

it("should handle async with done callback", function(done) {

364

setTimeout(function() {

365

expect(true).toBe(true);

366

done();

367

}, 100);

368

});

369

370

it("should use waitsFor pattern", function() {

371

let completed = false;

372

373

runs(function() {

374

setTimeout(function() {

375

completed = true;

376

}, 100);

377

});

378

379

waitsFor(function() {

380

return completed;

381

}, "operation to complete", 1000);

382

383

runs(function() {

384

expect(completed).toBe(true);

385

});

386

});

387

388

it("should use waits pattern", function() {

389

let value = 0;

390

391

runs(function() {

392

setTimeout(function() {

393

value = 42;

394

}, 50);

395

});

396

397

waits(100);

398

399

runs(function() {

400

expect(value).toBe(42);

401

});

402

});

403

});

404

```

405

406

## Global Environment Access

407

408

```javascript { .api }

409

/**

410

* Get current Jasmine environment for configuration

411

* @returns Jasmine environment object

412

*/

413

function jasmine.getEnv(): jasmine.Env;

414

415

interface jasmine.Env {

416

/** Default timeout for async operations in milliseconds */

417

defaultTimeoutInterval: number;

418

/** Execute all registered specs */

419

execute(): void;

420

/** Add reporter to environment */

421

addReporter(reporter: any): void;

422

}

423

```

424

425

**Usage Examples:**

426

427

```javascript

428

// Set default timeout for all async tests

429

jasmine.getEnv().defaultTimeoutInterval = 10000;

430

431

// Add custom reporter

432

jasmine.getEnv().addReporter(new CustomReporter());

433

```