test: Split the test suite into isolation groups for faster runs (#2613)
This commit is contained in:
+1
-1
@@ -188,7 +188,7 @@
|
|||||||
"format-check": "prettier --check .",
|
"format-check": "prettier --check .",
|
||||||
"rollup": "rollup -c",
|
"rollup": "rollup -c",
|
||||||
"prune": "knip",
|
"prune": "knip",
|
||||||
"test": "vitest run",
|
"test": "VITEST_GROUP=shared vitest run && VITEST_GROUP=isolated vitest run",
|
||||||
"coverage": "vitest run --coverage"
|
"coverage": "vitest run --coverage"
|
||||||
},
|
},
|
||||||
"volta": {
|
"volta": {
|
||||||
|
|||||||
+52
-2
@@ -1,3 +1,6 @@
|
|||||||
|
import { readdirSync, readFileSync } from 'fs';
|
||||||
|
import { join } from 'path';
|
||||||
|
|
||||||
import { defineConfig } from 'vitest/config';
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
import { svgPath } from './scripts/svg-path-plugin.js';
|
import { svgPath } from './scripts/svg-path-plugin.js';
|
||||||
@@ -19,7 +22,48 @@ const EXCLUSIONS = [
|
|||||||
'src/patches/**/*.ts',
|
'src/patches/**/*.ts',
|
||||||
];
|
];
|
||||||
|
|
||||||
const INCLUSIONS = ['tests/**/*.test.ts'];
|
const TEST_DIRECTORY = 'tests';
|
||||||
|
const INCLUSIONS = [`${TEST_DIRECTORY}/**/*.test.ts`];
|
||||||
|
|
||||||
|
// For test performance reasons, tests are split into two groups:
|
||||||
|
//
|
||||||
|
// - `shared`: run non-isolated, so they share one loaded copy of the source
|
||||||
|
// tree instead of each re-importing it.
|
||||||
|
// - `isolated`: given their own module registry per file, because sharing one
|
||||||
|
// would change their behaviour. A file calling `vi.mock()` cannot replace a
|
||||||
|
// module an earlier file already loaded unmocked; a file loading the template
|
||||||
|
// renderer reads browser globals as the renderer loads; and a file needing a
|
||||||
|
// DOM leaves modules holding a `window` that is torn down when it finishes,
|
||||||
|
// which breaks any later file that reaches one of those modules.
|
||||||
|
//
|
||||||
|
// Absent this variable every test file runs isolated, which is both the safe
|
||||||
|
// default and what coverage requires (istanbul only counts a module's top-level
|
||||||
|
// code the first time it runs).
|
||||||
|
const GROUP = process.env.VITEST_GROUP;
|
||||||
|
|
||||||
|
const findTestFiles = (directory: string): string[] => {
|
||||||
|
const files: string[] = [];
|
||||||
|
for (const entry of readdirSync(directory, { withFileTypes: true })) {
|
||||||
|
const path = join(directory, entry.name);
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
files.push(...findTestFiles(path));
|
||||||
|
} else if (entry.name.endsWith('.test.ts')) {
|
||||||
|
files.push(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
};
|
||||||
|
|
||||||
|
const REQUIRE_ISOLATION_REGEXP =
|
||||||
|
/\bvi\.(do)?mock\(|loadRenderer|stubConnectedHomeAssistant|@vitest-environment\s+jsdom/;
|
||||||
|
|
||||||
|
const getGroup = (file: string): string =>
|
||||||
|
REQUIRE_ISOLATION_REGEXP.test(readFileSync(file, 'utf-8')) ? 'isolated' : 'shared';
|
||||||
|
|
||||||
|
const getInclusions = (): string[] =>
|
||||||
|
GROUP
|
||||||
|
? findTestFiles(TEST_DIRECTORY).filter((file) => getGroup(file) === GROUP)
|
||||||
|
: INCLUSIONS;
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [svgPath()],
|
plugins: [svgPath()],
|
||||||
@@ -31,7 +75,13 @@ export default defineConfig({
|
|||||||
inline: ['ha-nunjucks', 'ts-py-datetime'],
|
inline: ['ha-nunjucks', 'ts-py-datetime'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
include: INCLUSIONS,
|
include: getInclusions(),
|
||||||
|
|
||||||
|
// Forked child processes start and tear down faster here than worker
|
||||||
|
// threads, which matters when every test file needs a fresh one.
|
||||||
|
pool: 'forks',
|
||||||
|
|
||||||
|
isolate: !GROUP || GROUP === 'isolated',
|
||||||
|
|
||||||
// Hide console writing to keep output clean, usual sources of noise:
|
// Hide console writing to keep output clean, usual sources of noise:
|
||||||
// - Unnecessary Lit dev-mode warnings.
|
// - Unnecessary Lit dev-mode warnings.
|
||||||
|
|||||||
Reference in New Issue
Block a user