node --test "*.test.js” 이렇게 * 로 여러개 한번에 지정하는 패턴node --test *.test.js 안됨# 예시
test/
setup.mjs # 공통 설정
setup.unit.mjs # 유닛 테스트용 설정
setup.integration.mjs # 통합 테스트용 설정
setup.e2e.mjs # E2E 테스트용 설정
test('Detect OS', ...)
Node가 TestContext(t) 생성
for 문에서 t.test() 호출
import assert from 'node:assert/strict';
import { test } from 'node:test';
import { detectOsInUserAgent } from '…';
const userAgents = [
{
ua: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.3',
os: 'WIN',
},
// …
];
test('Detect OS via user-agent', { concurrency: true }, t => {
for (const { os, ua } of userAgents) {
t.test(ua, () => assert.equal(detectOsInUserAgent(ua), os));
}
});
Promise 추가, 전체 테스트
import assert from 'node:assert/strict';
import { test } from 'node:test';
import { getWorkspacePJSONs } from './getWorkspacePJSONs.mjs';
const requiredKeywords = ['node.js', 'sliced bread'];
test('Check package.jsons', { concurrency: true }, async t => {
const pjsons = await getWorkspacePJSONs();
const cases = pjsons.map(pjson =>
// ⚠️ `t.test`, NOT `test`
t.test(`Ensure fields are properly set: ${pjson.name}`, () => {
assert.partialDeepStrictEqual(pjson.keywords, requiredKeywords);
})
);
// Allow the cases to run concurrently.
await Promise.allSettled(cases);
});
import { globSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
// Note: This would be better implemented as an async generator, leveraging fs.glob (instead of fs.globSync);
// however, generators and especially async generators are much less understood,
// so this simplified example is provided for easier understanding.
/**
* Get all the package.json files, by default 1-level deep within ./workspaces/
*/
export function getWorkspacePJSONs(path = './workspaces/*/package.json') {
return Promise.all(
globSync(
// ⚠️ Passing a file URL string, like from import.meta.resolve, causes glob* to fail silently
fileURLToPath(import.meta.resolve(path))
).map(path => import(path, { with: { type: 'json' } }))
);
}
test/setup.sw.mjsimport { beforeEach } from 'node:test';
import { ServiceWorkerGlobalScope } from './globals/ServiceWorkerGlobalScope.js';
import './setup.mjs'; // 💡
beforeEach(globalSWBeforeEach);
function globalSWBeforeEach() {
globalThis.self = new ServiceWorkerGlobalScope();
}
import assert from 'node:assert/strict';
import { describe, mock, it } from 'node:test';
import { onActivate } from './onActivate.js';
describe('ServiceWorker::onActivate()', () => {
const globalSelf = globalThis.self;
const claim = mock.fn(async function mock__claim() {});
const matchAll = mock.fn(async function mock__matchAll() {});
class ActivateEvent extends Event {
constructor(...args) {
super('activate', ...args);
}
}
before(() => {
globalThis.self = {
clients: { claim, matchAll },
};
});
after(() => {
global.self = globalSelf;
});
it('should claim all clients', async () => {
await onActivate(new ActivateEvent());
assert.equal(claim.mock.callCount(), 1);
assert.equal(matchAll.mock.callCount(), 1);
});
});