c81ebb7053
- 根因:polling-backoff-recovery 测试断言失败后跳过 loop.dispose(),残留自续期定时器导致 node --test 子进程永不退出 - dead-code-cleanup:移除套娃用例 test_full_vitest_green(再跑一遍全量套件,放大问题),execSync 加 300s 超时;其余静态断言保留 - package.json:node --test --test-force-exit --test-timeout=180000 - CI workflow 前端测试步骤改为 npm test(与 package.json 单一来源) - 修正 3 处过时期望值(轮询退避/品牌 files+taskType/巡店 delete_conditions) - 验证:本地 666 用例全过,19-24s,无残留进程
69 lines
2.7 KiB
TypeScript
69 lines
2.7 KiB
TypeScript
import { test } from 'node:test'
|
||
import assert from 'node:assert/strict'
|
||
import fs from 'node:fs'
|
||
import path from 'node:path'
|
||
import { fileURLToPath } from 'node:url'
|
||
|
||
/** task-216:CI 接入测试阶段契约。.gitea/workflows/build.yml 含 Java 测试与前端测试,失败即红。 */
|
||
|
||
const YML = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..', '.gitea', 'workflows', 'build.yml')
|
||
|
||
function text(): string {
|
||
return fs.readFileSync(YML, 'utf8')
|
||
}
|
||
|
||
test('CI 工作流存在', () => {
|
||
assert.ok(fs.existsSync(YML), 'build.yml 应存在')
|
||
})
|
||
|
||
test('含 Java 测试阶段(mvn test 跑单元+契约+ArchUnit)', () => {
|
||
const t = text()
|
||
assert.ok(/Test \(Java: unit \+ contract \+ ArchUnit\)/.test(t), t)
|
||
assert.ok(/mvn test/.test(t), t)
|
||
assert.ok(!/mvn clean package -DskipTests.*\n\s*run: mvn test/.test(t), '测试应先于打包')
|
||
})
|
||
|
||
test('测试在打包之前执行(失败即红,阻断产物上传)', () => {
|
||
const t = text()
|
||
const testIdx = t.indexOf('mvn test')
|
||
const packageIdx = t.indexOf('mvn clean package -DskipTests')
|
||
assert.ok(testIdx !== -1 && packageIdx !== -1 && testIdx < packageIdx, 'mvn test 必须先于 package')
|
||
})
|
||
|
||
test('含前端测试 job(npm test 跑 node --test 契约测试)', () => {
|
||
const t = text()
|
||
assert.ok(/frontend-test/.test(t), t)
|
||
assert.ok(/run: npm test/.test(t), t)
|
||
assert.ok(/npm ci/.test(t), t)
|
||
})
|
||
|
||
test('前端测试脚本带防挂死参数(force-exit + timeout)', () => {
|
||
const pkgPath = path.resolve(path.dirname(YML), '..', '..', 'frontend-vue', 'package.json')
|
||
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')) as { scripts: Record<string, string> }
|
||
assert.ok(/node --test/.test(pkg.scripts.test), '测试脚本应基于 node --test')
|
||
assert.ok(/--test-force-exit/.test(pkg.scripts.test), '须带 --test-force-exit:避免残留句柄让套件永久挂起')
|
||
assert.ok(/--test-timeout=\d+/.test(pkg.scripts.test), '须带 --test-timeout:单个用例卡死时能失败退出')
|
||
})
|
||
|
||
test('前端含类型检查(vue-tsc)', () => {
|
||
const t = text()
|
||
assert.ok(/npm run build/.test(t), '应执行 npm run build(vue-tsc + vite)')
|
||
})
|
||
|
||
test('有超时与容器环境配置', () => {
|
||
const t = text()
|
||
assert.ok(/timeout-minutes:\s*\d+/.test(t), '应有超时配置')
|
||
assert.ok(/maven:3\.9-eclipse-temurin-21/.test(t), 'Java 容器应存在')
|
||
assert.ok(/node:24-alpine/.test(t), '前端容器应存在')
|
||
})
|
||
|
||
test('产物上传保留且路径指向 backend-java', () => {
|
||
const t = text()
|
||
assert.ok(/backend-java\/target\/\*\.jar/.test(t), 'jar 产物路径应对')
|
||
assert.ok(/Upload artifact/.test(t))
|
||
})
|
||
|
||
test('可重复、内容稳定(两次读取一致)', () => {
|
||
assert.equal(text(), text())
|
||
})
|