TestTrace is a VS Code extension that parses gtest and CUnit test code, lets developers confirm detected cases, and generates AI test trace labels in the format:
AI_<UT|FT>_<COMPONENT>_<YYYYMMDD>_<CASE_HASH16B>_<CONTENT_HASH16B>
TestTrace is split into two parts:
- a VS Code extension that collects editor context, opens the review panel, and calls the backend service
- a standalone backend service that detects the test framework, parses test cases, resolves scope from path mappings, and generates labels
The current user flow is:
- Run a command from the editor context menu or command palette.
- Let the backend parse the current file or selection.
- Review detected test cases in the webview panel.
- Generate labels for selected cases.
- Detects
gtestandCUnitsources - Supports current-file and selection-driven workflows
- Shows a review panel before label generation
- Resolves
teamandcomponentfrom server-side path mappings - Exposes a direct backend generation endpoint for automation scenarios
- gtest: TEST, TEST_F, TEST_P, TYPED_TEST, TYPED_TEST_P
- CUnit: CU_add_suite and CU_add_test registration flow
- UT and FT labels from current-file and selection-driven right-click commands
- Review panel for case confirmation and label generation
The extension contributes these commands:
TestTrace: 从当前文件生成 UT 标签TestTrace: 从当前文件生成 FT 标签TestTrace: 从选中内容生成 UT 标签TestTrace: 从选中内容生成 FT 标签TestTrace: 查看上次解析结果
The four generation commands are available from the TestTrace submenu in the C/C++ editor context menu. Compatibility API calls without a label type continue to generate UT labels.
- Node.js 20 or later
- VS Code 1.90 or later
- A running TestTrace backend service before using the extension commands
The extension uses the following setting:
testTrace.serviceBaseUrl: base URL of the backend service, defaulting tohttp://127.0.0.1:43125
To use a backend on another machine, open VS Code Settings, search for TestTrace: Service Base Url, and set its address. You can also add the setting to settings.json:
{
"testTrace.serviceBaseUrl": "http://192.168.1.10:43125"
}The standalone service listens on 0.0.0.0:43125 by default. Override its bind address or port with environment variables before starting it:
TESTTRACE_HOST=0.0.0.0 TESTTRACE_PORT=43125 npm run server:startSet testTrace.serviceBaseUrl to the reachable host and port, for example http://192.168.1.10:43125. Ensure the service port is reachable from the machine running VS Code.
src/
extension.ts VS Code extension entry point and command handlers
types.ts extension review and generation session types
utils.ts extension path utilities
parsing/detect.ts lightweight local framework detection
service/client.ts HTTP client for the backend service
shared/ runtime-shared types, utilities, and framework detection
webview/panel.ts review and result panel UI
server/src/
index.ts backend process entry point
lib/
httpServer.ts HTTP routes
service.ts parsing and label-generation orchestration
internalPathMappings.ts server-side team and component path mappings
scope.ts scope resolution logic
labels.ts label generation logic
utils.ts hashes, normalization, and label construction
types.ts backend-only API types
parsing/ gtest and CUnit parsers
tests/
hashing.test.ts hash, normalization, and label type behavior
parsers.test.ts parser behavior
scope.test.ts scope resolution behavior
fixtures/ parser test fixtures
Install dependencies:
npm installInstall backend dependencies:
npm --prefix server installBuild once:
npm run compileWatch mode:
npm run watchRun tests:
npm testBuild the backend service:
npm run server:buildRun the backend service:
npm run server:startThe extension now expects a standalone backend service.
Build and start the backend service:
npm run server:build
npm run server:startThen start the extension host with Run TestTrace Extension, or use the compound configuration Run TestTrace Service + Extension to start both together.
The plugin calls the backend at testTrace.serviceBaseUrl, which defaults to http://127.0.0.1:43125.
The standalone backend currently exposes these routes:
GET /healthPOST /parse-previewPOST /generate-labelsPOST /generate-direct
/parse-preview is used by the extension review flow.
/generate-labels turns reviewed cases into final labels.
/generate-direct is intended for direct service-driven generation from file content and absolute path.
Health check:
curl http://127.0.0.1:43125/healthParse the current file for review:
curl -X POST http://127.0.0.1:43125/parse-preview \
-H "Content-Type: application/json" \
-d '{
"sourceRelativePath": "components/payment/tests/refund_test.cpp",
"fileName": "refund_test.cpp",
"language": "cpp",
"frameworkHint": "gtest",
"selectionMode": "current_file",
"selectionStart": 0,
"selectionEnd": 0,
"fullFileText": "TEST(RefundServiceTest, RejectsNegativeAmount) { EXPECT_FALSE(service.Apply(-1)); }"
}'Generate labels for reviewed cases:
curl -X POST http://127.0.0.1:43125/generate-labels \
-H "Content-Type: application/json" \
-d '{
"sourceRelativePath": "components/payment/tests/refund_test.cpp",
"fileName": "refund_test.cpp",
"framework": "gtest",
"labelType": "FT",
"team": "TRADE",
"component": "PAYMENT",
"selectedIds": ["RefundServiceTest:RejectsNegativeAmount:0"],
"cases": [
{
"id": "RefundServiceTest:RejectsNegativeAmount:0",
"framework": "gtest",
"fileName": "refund_test.cpp",
"sourceRelativePath": "components/payment/tests/refund_test.cpp",
"suiteName": "RefundServiceTest",
"caseName": "RejectsNegativeAmount",
"displayName": "RejectsNegativeAmount",
"sourceSnippet": "TEST(RefundServiceTest, RejectsNegativeAmount) { EXPECT_FALSE(service.Apply(-1)); }",
"normalizedTestCode": "TEST(RefundServiceTest, RejectsNegativeAmount) { EXPECT_FALSE(service.Apply(-1)); }",
"lineStart": 1,
"lineEnd": 1,
"parseConfidence": 95,
"parseStrategy": "gtest_macro_block",
"warnings": [],
"startOffset": 0,
"endOffset": 75
}
]
}'Direct generation from file content and absolute path:
curl -X POST http://127.0.0.1:43125/generate-direct \
-H "Content-Type: application/json" \
-d '{
"absolutePath": "/workspace/components/payment/tests/refund_test.cpp",
"labelType": "FT",
"fileContent": "TEST(RefundServiceTest, RejectsNegativeAmount) { EXPECT_FALSE(service.Apply(-1)); }"
}'Build a local VSIX package with:
npm run package:vsixThe package script allows a missing repository URL and skips the license-file check so local packaging remains non-interactive.
- Scope mapping rules are owned by the backend and live in
server/src/lib/internalPathMappings.ts. - Full test parsing is owned by the backend service.
- The extension still performs lightweight local framework detection before calling the backend.