Files
ftb-project-management/apps/web/lib/test-case.test.ts
2026-06-26 11:01:11 +08:00

161 lines
4.0 KiB
TypeScript

import test from 'node:test';
import assert from 'node:assert/strict';
import {
TEST_CASE_STATUS_LABEL,
aggregateTestCaseHours,
calcTestProgress,
getTestCaseEstimateHours,
normalizeTestCase,
} from './test-case';
import { DEFAULT_TEST_CATEGORY_ID } from './task-category';
test('normalizeTestCase backfills missing categoryId', () => {
const tc = normalizeTestCase({
id: 'tc-1',
caseNo: 'TC-001',
versionId: 'v1',
title: '登录正常',
priority: 'P2',
status: 'pending',
createdBy: 'tester',
createdAt: '2026-06-25',
updatedAt: '2026-06-25',
} as any);
assert.equal(tc.categoryId, DEFAULT_TEST_CATEGORY_ID);
});
test('normalizeTestCase keeps existing categoryId', () => {
const tc = normalizeTestCase({
id: 'tc-1',
caseNo: 'TC-001',
versionId: 'v1',
title: '登录正常',
priority: 'P2',
status: 'pending',
categoryId: 'cat-test-api',
createdBy: 'tester',
createdAt: '2026-06-25',
updatedAt: '2026-06-25',
} as any);
assert.equal(tc.categoryId, 'cat-test-api');
});
test('normalizeTestCase keeps missing executor estimate empty', () => {
const tc = normalizeTestCase({
id: 'tc-1',
caseNo: 'TC-001',
versionId: 'v1',
title: '登录正常',
priority: 'P2',
status: 'pending',
categoryId: 'cat-test-api',
createdBy: 'tester',
createdAt: '2026-06-25',
updatedAt: '2026-06-25',
} as any);
assert.equal(tc.estimateHours, undefined);
assert.equal(getTestCaseEstimateHours(tc), 0);
});
test('getTestCaseEstimateHours prefers executor estimate over AI estimate', () => {
const tc = normalizeTestCase({
id: 'tc-1',
caseNo: 'TC-001',
versionId: 'v1',
title: '登录正常',
priority: 'P2',
status: 'pending',
categoryId: 'cat-test-api',
estimateHours: 0.7,
aiEstimateHours: 0.2,
createdBy: 'tester',
createdAt: '2026-06-25',
updatedAt: '2026-06-25',
} as any);
assert.equal(getTestCaseEstimateHours(tc), 0.7);
});
test('getTestCaseEstimateHours falls back to AI estimate', () => {
const tc = normalizeTestCase({
id: 'tc-1',
caseNo: 'TC-001',
versionId: 'v1',
title: '登录正常',
priority: 'P2',
status: 'pending',
categoryId: 'cat-test-api',
aiEstimateHours: 0.2,
createdBy: 'tester',
createdAt: '2026-06-25',
updatedAt: '2026-06-25',
} as any);
assert.equal(getTestCaseEstimateHours(tc), 0.2);
});
test('test case status labels use waiting and testing wording', () => {
assert.equal(TEST_CASE_STATUS_LABEL.pending, '待测试');
assert.equal(TEST_CASE_STATUS_LABEL.running, '测试中');
assert.equal(TEST_CASE_STATUS_LABEL.failed, '不通过');
});
test('calcTestProgress uses estimate-weighted completion', () => {
const progress = calcTestProgress([
normalizeTestCase({
id: 'tc-1',
caseNo: 'TC-001',
versionId: 'v1',
title: '待测试',
priority: 'P2',
status: 'pending',
categoryId: 'cat-test-functional',
estimateHours: 1,
createdBy: 'tester',
createdAt: '2026-06-25',
updatedAt: '2026-06-25',
} as any),
normalizeTestCase({
id: 'tc-2',
caseNo: 'TC-002',
versionId: 'v1',
title: '已通过',
priority: 'P2',
status: 'passed',
categoryId: 'cat-test-functional',
estimateHours: 3,
createdBy: 'tester',
createdAt: '2026-06-25',
updatedAt: '2026-06-25',
} as any),
]);
assert.equal(progress.completionRate, 75);
});
test('aggregateTestCaseHours returns estimate and actual totals', () => {
const hours = aggregateTestCaseHours([
normalizeTestCase({
id: 'tc-1',
caseNo: 'TC-001',
versionId: 'v1',
title: '测试中',
priority: 'P2',
status: 'running',
categoryId: 'cat-test-functional',
estimateHours: 1,
startedAt: '2026-06-25T01:00:00.000Z',
createdBy: 'tester',
createdAt: '2026-06-25',
updatedAt: '2026-06-25',
} as any),
], new Date('2026-06-25T02:00:00.000Z'));
assert.equal(hours.estimate, 1);
assert.equal(hours.actual, 1);
});