Skip to content

Commit 15ff02a

Browse files
committed
05/01: add exercise texts
1 parent 88d97ee commit 15ff02a

File tree

18 files changed

+299
-19
lines changed

18 files changed

+299
-19
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Profiling slow tests
2+
3+
There are numerous factors that can contribute to the performance of your test suite: the number of tests, the amount of test setup, the speed of the tested code itself. But no matter the factors, you have to know _how_ to spot a slow test and _what_ to do to improve it.
4+
5+
When it comes to dissecting any performance degradation, a gut feeling or a guess what might be making your software slow simply won't cut it. You need to know for a fact how that degradation manifests and where it stems from. Only then can you design an appropriate plan to fix it for good.
6+
7+
## Profiling
8+
9+
_Profiling_ is an essential process in analyzing code performance. Your tests are still code—the code you're testing wrapped in your test framework. Profiling it will come down to measuring critical points of the test's execution and analyzing the resulting report to see which areas consume most time/CPU/RAM/etc.
10+
11+
You employ all sorts of tools to help you with profiling. From the built-in "Profiler" in your browser's DevTools to CPU and heap maps and even native profiling instruments in your test framework.
12+
13+
But it all starts from a slow test (or a few). In our case, we have a `rows.test.ts` test suite that's unusually slow:
14+
15+
```txt nonumber nocopy highlight=4,9
16+
npx vitest run
17+
18+
✓ src/rows.test.ts (1 test) 563ms
19+
✓ retrieves all the rows 562ms
20+
21+
Test Files 1 passed (1)
22+
Tests 1 passed (1)
23+
Start at 10:57:37
24+
Duration 1.10s (transform 18ms, setup 0ms, collect 13ms, tests 563ms, environment 0ms, prepare 34ms)
25+
```
26+
27+
## Your task
28+
29+
👨‍💼 Your mission this time is to _profile_ the slow test's performance and _identify_ the area that costs it most time. There are a few ways to do that in Vitest, but today you will be using the [`vitest-profiler`](https://github.com/kettanaito/vitest-profiler) plugin to help you out! Follow Kody to get it installed and configured in your project.
30+
31+
🐨 Install `vitest-profiler` as a dependency in your project:
32+
33+
```sh nonumber
34+
npm install vitest-profiler --save-dev
35+
```
36+
37+
🐨 Import the `vitestProfiler` function from `vitest-profiler/plugin` and add its call to the `plugins` array of your <InlineFile file="vitest.config.ts" />:
38+
39+
```ts filename=vitest.config.ts add=2,5
40+
import { defineConfig } from 'vitest/config'
41+
import { vitestProfiler } from 'vitest-profiler/plugin'
42+
43+
export default defineConfig({
44+
plugins: [vitestProfiler()],
45+
test: {
46+
globals: true,
47+
},
48+
})
49+
```
50+
51+
🐨 Finally, head to <InlineFile file="package.json" /> and add a new script called `test:profile`. In that script, call the `vitest-profiler` CLI like this:
52+
53+
```json filename=package.json add=4
54+
{
55+
"scripts": {
56+
"test": "vitest",
57+
"test:profile": "vitest-profiler npm test"
58+
}
59+
}
60+
```
61+
62+
> Notice that you are passing the test command `npm test` as the argument to the `vitest-profiler` CLI. It will use that command to run the tests the same way you normally do.
63+
64+
Alright, this has you equipped with the profiler! What's left is to run `npm run test:profile` and analyze the results. Feel free to refer to the [`vitest-profiler` README](https://github.com/kettanaito/vitest-profiler) for more details on how to read the profiling report.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"type": "module",
3+
"name": "exercises_04.performance_01.problem.profiling-slow-tests",
4+
"scripts": {
5+
"dev": "vite",
6+
"test": "vitest --no-cache",
7+
"build": "vite build"
8+
},
9+
"devDependencies": {
10+
"vite": "^6.2.6",
11+
"vitest": "^3.1.1",
12+
"vitest-profiler": "^0.1.8"
13+
}
14+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { expensiveCompute } from './utils'
2+
3+
test('retrieves all the rows', function myTest() {
4+
const rows = expensiveCompute()
5+
expect(rows).toBeInstanceOf(Array)
6+
expect(rows).toHaveLength(100_000_000)
7+
})
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export function expensiveCompute() {
2+
const rows = []
3+
4+
for (let i = 0; i < 100_000_000; i++) {
5+
rows.push(i)
6+
}
7+
8+
return rows
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"extends": "./tsconfig.base.json",
3+
"include": ["src/**/*"],
4+
"exclude": ["src/**/*.test.ts*"],
5+
"compilerOptions": {
6+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
7+
"jsx": "react-jsx"
8+
}
9+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ESNext",
4+
"module": "ESNext",
5+
"useDefineForClassFields": true,
6+
"skipLibCheck": true,
7+
8+
/* Bundler mode */
9+
"moduleResolution": "bundler",
10+
"allowImportingTsExtensions": true,
11+
"isolatedModules": true,
12+
"moduleDetection": "force",
13+
"noEmit": true,
14+
"verbatimModuleSyntax": true,
15+
16+
/* Linting */
17+
"strict": true,
18+
"noUnusedLocals": false,
19+
"noUnusedParameters": false,
20+
"noFallthroughCasesInSwitch": true,
21+
"noUncheckedSideEffectImports": true
22+
}
23+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"files": [],
3+
"references": [
4+
{ "path": "./tsconfig.app.json" },
5+
{ "path": "./tsconfig.node.json" },
6+
{ "path": "./tsconfig.test.json" }
7+
]
8+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"extends": "./tsconfig.base.json",
3+
"compilerOptions": {
4+
"lib": ["ES2023"]
5+
},
6+
"include": ["vitest.config.ts"]
7+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"extends": "./tsconfig.app.json",
3+
"include": ["src/**/*", "src/**/*.test.ts*"],
4+
"exclude": [],
5+
"compilerOptions": {
6+
"types": ["vitest/globals"]
7+
}
8+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { defineConfig } from 'vitest/config'
2+
3+
export default defineConfig({
4+
test: {
5+
globals: true,
6+
},
7+
})

0 commit comments

Comments
 (0)