Skip to content

Commit 4955dd9

Browse files
committed
Docs: New blogpost "Test lifecycle diagram"
1 parent eb925e7 commit 4955dd9

File tree

3 files changed

+45
-3
lines changed

3 files changed

+45
-3
lines changed

docs/_posts/2025-01-19-stacktrace-cleaner.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,11 @@ qunit example.js
137137
<figure><img src="/resources/2025-stacktrace-error-after.png" width="540" height="288" alt="Failed to load file example.js. TypeError: eventName must be a string. at example.js, at node:internal/cjs/loader."><figcaption>QUnit 2.24.0</figcaption></figure>
138138
</div>
139139

140-
Notice the removal of the first `qunit.js` call, which lets the trace starts cleanly at `example.js`. The other internal calls are greyed out.
140+
Notice the removal of the first `Object.on (qunit/qunit.js)` line, so that the trace starts cleanly at your `example.js` file. The other internal calls are greyed out.
141141

142142
### Trimming traces
143143

144-
For assertion failures and uncaught exceptions alike, we only trim internal frames from the start or end of a stack. Removing frames from the middle would falsely present a call relationship that never happened, and would cause confusion among developers. Instead, frames we can't trim, are greyed out instead. This is similar to Node.js's own error formatter does.
144+
For assertion failures and uncaught exceptions alike, we only trim internal frames from the start or end of a stack. Removing frames from the middle would falsely present a call relationship that never happened, and would cause confusion among developers. Instead, frames we can't trim, are greyed out instead. This works similar to Node.js' error handler.
145145

146146
## TAP reporter
147147

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
---
2+
layout: post
3+
title: "Test lifecycle diagram"
4+
author: krinkle
5+
tags:
6+
- feature
7+
---
8+
9+
Ever wondered how beforeEach works in unit test frameworks?
10+
11+
## Test lifecycle
12+
13+
<figure>
14+
<img src="/resources/qunit-lifecycle-hooks-order.svg" width="676" height="901" alt="" title="Imagine a test suite with global hooks, and a Parent and Child module that use hooks also. The execution order is:
15+
1. Parent module runs the before hook.
16+
2. Every test in the Parent module inherits context from the before hook, and repeats as follows: call global beforeEach, parent beforeEach, the actual test, parent afterEach, and lastly the global afterEach.
17+
3. The Child module inherits context from the Parent before hook, and then runs its own before hook.
18+
4. Every test in the Child module inherits context from this before hook, and repeats as follows: call global beforeEach, parent beforeEach, child beforeEach, the actual test, child afterEach, parent afterEach, and lastly the global afterEach.
19+
">
20+
<figcaption markdown="1">
21+
Learn about the execution on the new [Test lifecycle](https://qunitjs.com/lifecycle/) page.
22+
</figcaption>
23+
</figure>
24+
25+
## Why
26+
27+
An experienced developer will find that test hooks work more or less the same in every JavaScript unit test framework. The execution order is also intuitive enough that most people answer correctly when they guess. So why explain it?
28+
29+
You shouldn't have to guess!
30+
31+
I think it's worth laying out explicitly, even if this is not unique to QUnit, because a new developer is going to encounter this for the first time.
32+
33+
But more importantly, by demonstrating that the order is stable and guaranteed, I hope this gives you the confidence to lean into it. Build on it! The new [Test lifecycle](https://qunitjs.com/lifecycle/) page showcases what's possible when you depend on this with intent: Nesting hooks, sharing hooks, [global hooks](https://qunitjs.com/api/QUnit/hooks/), and extending test context.
34+
35+
## Thanks
36+
37+
Thanks to FND, Jan D, and NullVoxPopuli for reviewing, improving, and promoting this work!
38+
39+
## See also
40+
41+
* [QUnit.module()](https://qunitjs.com/api/QUnit/module/)
42+
* [Issue #1358](https://github.com/qunitjs/qunit/issues/1358)

docs/_sass/custom.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ h3 a {
9090
.figure-row {
9191
display: flex;
9292
flex-wrap: wrap;
93-
align-items: center;
93+
align-items: flex-end;
9494
justify-content: center;
9595
gap: $box-spacing;
9696
// "pop out"

0 commit comments

Comments
 (0)