在軟件開發中,測試對于確保最終產品的質量和可靠性至關重要。然而,創建測試計劃和規范可能耗時且需要大量人力,尤其是在復雜系統中管理多種需求和不同測試類型時。許多此類任務通常由測試工程師手動執行。
為了簡化這一過程, NVIDIA 的 DriveOS 團隊開發了 Hephaestus(HEPH),這是一個用于自動測試生成的 內部生成式 AI 框架。HEPH 可自動執行各種測試的設計和實施,包括集成測試和單元測試。它使用 大語言模型 (LLMs)進行輸入分析和代碼生成,顯著減少了創建測試用例所花費的時間。通過根據輸入文檔、代碼樣本和反饋循環生成上下文感知測試,HEPH 使測試更快、更高效。
本文概述了如何構建智能體框架以生成各種類型的軟件測試。該文介紹了如何使用大型語言模型(LLM)智能體確保文檔的可溯性,以及如何根據軟件要求創建可執行測試。您還可以了解到如何提高智能體的測試生成能力。
用于自動創建測試用例的智能體框架
在軟件開發過程中,開發、安全和 QA 團隊通常會面臨手動創建測試用例的勞動密集型任務。
測試創建過程涉及耗時的步驟,包括檢索需求信息、將這些需求追蹤到相關文檔,以及最終根據匹配的需求和文檔生成測試。
為了簡化此工作流程,DriveOS 團隊設計了 HEPH,這是一種用于實現整個測試流程自動化的自定義內部框架,顯著減少了創建測試規范和實現所花費的時間。HEPH 使用大型語言模型(LLMs)分析輸入文檔和代碼示例,生成根據所提供的要求定制的測試。
測試自動化的價值?
HEPH 在測試生成過程的每個步驟(從文檔追蹤到代碼生成)中都使用 LLM 智能體。這實現了整個測試工作流程的自動化,并為工程團隊節省了大量時間。
- 節省時間: HEPH 顯著加快了測試創建過程。在 NVIDIA 多個試點團隊的試驗中,團隊報告節省了多達 10 周的開發時間。
- 上下文感知測試生成: HEPH 使用項目文檔和接口規范生成測試規范和實現。每個測試都經過編譯、執行和驗證,以確保正確性。測試覆蓋率數據會反饋回模型,以進一步優化測試生成。
- 多格式支持和模塊化:HEPH 支持各種輸入格式,包括 PDF、RST、RSTI 和 HTML,并與內部工具如 Confluence 和 JIRA 集成。
HEPH 的工作原理是什么?
HEPH 接受軟件需求、軟件架構文檔(SWAD)、接口控制文檔(ICD)和測試示例作為輸入,輸出是針對給定需求的一組測試規范和實現(圖 1)。

測試生成流程包括以下主要步驟:
- 數據準備: 輸入文檔(如 SWAD 和 ICD)被編入索引并存儲在嵌入數據庫中,之后用于查詢相關信息。
- 需求提取: 從需求存儲系統(例如 Jama )檢索需求詳細信息。如果輸入需求缺乏生成測試所需的詳細信息,HEPH 會自動連接到存儲服務,定位需求并下載缺失的信息。
- 數據可追溯性:HEPH 搜索嵌入數據庫以追蹤與輸入需求相關的信息。輸出是需求與相關 SWAD 和 ICD 片段之間的映射連接。
- 測試規范生成: 基于需求的驗證步驟以及已識別的 SWAD 和 ICD 片段(可追蹤性),HEPH 生成正面和負面的測試規范,以涵蓋需求的各個方面。
- 測試實現生成 :HEPH 使用 ICD 片段(可追溯性)和生成的測試規范來創建 C/C++ 測試。ICD 提供函數名稱、數據類型、枚舉和返回代碼等上下文,供 LLM 在代碼生成過程中使用。該步驟生成可執行測試。
- 測試執行: 編譯并執行生成的測試,收集覆蓋率數據。HEPH 代理分析測試覆蓋率結果,并重復生成缺失案例的測試規范和實施。
真實場景
這是一個了解 HEPH 工作原理的真實示例。
NVIDIA DriveOS 使用 QNX 操作系統。為了演示 HEPH 的功能,我使用了一個 QNX BSP 驅動作為示例,以及對 QNX BSP 中的熱功能要求。鑒于輸入要求和驅動文檔,HEPH 從 Jama 中提取需求信息,將其追溯到相應的文檔片段,并生成測試規范和實現。
- 需求提取
- SWAD 數據可追蹤性
- ICD 數據追蹤
- 測試規范生成
- 測試實現生成
需求提取?
HEPH 使用需求標識符從需求存儲(Jama)中提取詳細信息。生成的需求格式為 JSON:
{
"requirement_id": "DOSBSP60-REQ-3874",
"name": "Get Temperature for Thermal Zones in the SOC_THERM Domain",
"description": "When a request to retrieve the temperature of a thermal zone in the SOC_THERM domain is made via TMON_GUEST_LIF#GetTempSocTherm, QNX_BSP shall retrieve and return two consecutive temperature values for the thermal zone via TEGRA_CTRL_LIF#GetTemp, preserving the temperature resolution, along with two corresponding timestamps via DRIVE_OS::QNX_System::OS_LIBC_LIF#ReadClockCycles."
}
SWAD 數據可追蹤性?
HEPH 可搜索所有架構文檔(SWAD),以找到與需求相關的信息。輸出是架構細節的集合,包括單元要求、方法、錯誤處理和驗證標準。
### Extracted Information for Requirement: DOSBSP60-REQ-3874
#### Unit Requirements and Functional Blocks
- **UREQ_NvThermmon_Library_0601**:
If the thermal zone bound to **Handle** is in the SOC_THERM domain, Thermal_API#GetTempSocTherm shall retrieve the bound zone ID, pass it to BPMP_Comm_API#GetZoneTemp to get the zone temperature, populate **TempVal1** with the zone temperature, use libc_api#QnxLibcReadClockCycles to populate **Timestamp1**, call BPMP_Comm_API#GetZoneTemp to get the zone temperature again, populate **TempVal2** with the zone temperature, use libc_api#QnxLibcReadClockCycles to populate **Timestamp2**, and return success as per Thermal_API ICD.
- **UREQ_NvThermmon_Library_0602**:
If BPMP_Comm_API#GetZoneTemp fails, Thermal_API#GetTempSocTherm shall return error as per Thermal_API ICD and perform no other action.
#### Methods and Functions
- **Functional Block FUNC_NvThermmon_01**:
FUNC_NvThermmon_01
Thermal_API provides the Thermal_API#GetTempSmTmon and Thermal_API#GetTempSocTherm interface to query the temperature of the thermal zone bound to **Handle** and return the result in **zone_temp**.
#### Error Handling
- **UREQ_NvThermmon_Resmgr_1201**:
If NvThermmon_Resmgr encounters a SW diagnostic error, the NvThermmon_Resmgr returns error as per Thermal_devctl_API ICD for all current and future Thermal_devctl_API requests and performs no other action.
- **UREQ_NvThermmon_Resmgr_1202**:
If libc_api#QnxLibcIoctl is called on ``/dev/<ZoneName>`` and the command is not Thermal_devctl_API#GetTemp or Thermal_devctl_API#SetAlert, NvThermmon_Resmgr shall return error as per Thermal_devctl_API ICD.
#### Verification Criteria (Verification Environment: AV+Q Safety prod-debug)
Verification Environment: AV+Q Safety prod-debug
Pre-Condition: N/A
Constraints: N/A
Verification Steps:
- Run interface tests on API
- Pass invalid thermal zones and verify the API fails
- Pass valid thermal zones from a process with required privileges and permissions and verify that the temperature can be read.
- Inject error such that I2C_API#SendReceive returns error and verify that Thermal_API#GetTempSmTmon fails as expected.
- Inject error such that BPMP_Comm_API#GetZoneTemp returns error and verify that Thermal_API#GetTempSocTherm fails as expected.
ICD 數據追蹤?
搜索 SWADs 后,HEPH 會在 ICDs 中查找信息。結果包括方法、函數、數據結構、錯誤代碼和函數依賴項的詳細信息。
### Extracted Information from ICDs
#### Methods and Functions:
1. **NvThermmonOpen**
**Description**: Opens a connection to the nvthermmon driver for the thermal sensor/zone user is interested in.
**Parameters**:
- `const char *const ZoneName`: Thermal sensor/zone name
- `NvThermmonHandle *const Handle`: User handle for further API calls
**Returns**:
- `NV_THERMMON_ERR_CODE_NO_ERROR`: Success
- `NV_THERMMON_ERR_CODE_INVALID_PARAM`: Invalid parameters
- `NV_THERMMON_ERR_CODE_DT_FAILED`: Device tree failure
- `NV_THERMMON_ERR_CODE_INVALID_PERM`: Permission error
- `NV_THERMMON_ERR_CODE_INVALID_STATE`: Invalid system state
- `NV_THERMMON_ERR_CODE_ERROR`: BPMP Comm error
**Precondition**: None
**Usage Considerations**:
- Allowed context for the API call
- Sync, not re-entrant
2. **NvThermmonGetZoneTemp**
**Description**: Read temperature from selected thermal zone. Populates memory pointed to by `temp` with temperature of thermal zone in millidegrees Celsius and returns status.
**Parameters**:
- `const NvThermmonHandle Handle`: Handle for execution context bound in `NvThermmonOpen`
- `int32_t * const TempVal`: Pointer to save temperature value in millidegrees Celsius.
**Returns**:
- `NvThermmonErrCode`: Error Code (e.g., `NV_THERMMON_ERR_CODE_NO_ERROR`, `NV_THERMMON_ERR_CODE_INVALID_PARAM`)
#### Data Structures and Fields:
1. **zone_temp_t Structure**
**Fields**:
- `int32_t temp_1`: First temperature reading
- `int32_t temp_2`: Second temperature reading
- `uint64_t ts_1`: Timestamp for first temp reading
- `uint64_t ts_2`: Timestamp for second temp reading
#### Enumerations:
1. **NvThermmonErrCode**
**Error Codes**:
- `NV_THERMMON_ERR_CODE_NO_ERROR`
- `NV_THERMMON_ERR_CODE_INVALID_PARAM`
- `NV_THERMMON_ERR_CODE_DT_FAILED`
- `NV_THERMMON_ERR_CODE_INVALID_PERM`
- `NV_THERMMON_ERR_CODE_INVALID_STATE`
- `NV_THERMMON_ERR_CODE_ERROR`
### Integration of Information for Testing:
1. **NvThermmonOpen()**:
**Precondition**: Ensure that `NvThermmonOpen` returns success for the thermal zone.
**Dependencies**:
- Handle for execution context
2. **NvThermmonGetZoneTemp()**:
**Dependencies**:
- `zone_temp_t` structure to store temperature readings and timestamps.
- Error codes to handle different edge cases and validation steps.
測試規范生成?
根據需求中的驗證步驟以及追蹤的 SWAD 和 ICD 片段,HEPH 生成測試規范。以下代碼塊是生成的測試用例示例。
######
Test Case ID: TC_DOSBSP60-REQ-3874_001
Test Case Name: Verify successful temperature query for a supported thermal zone
Test Type: Positive
Test Design: Ensure the temperature for a thermal zone in the SOC_THERM domain can be queried successfully.
Pre-condition: Thermal zone is supported and NvThermmonOpen() returns success for the thermal zone.
Test Procedure:
1. Open a connection to the thermal zone using NvThermmonOpen().
2. Query the temperature for the thermal zone using NvThermmonGetZoneTemp().
3. Retrieve two consecutive temperature values.
Expected Result: The API should return success with two temperature values that differ by no more than the delta determined by the thermal characteristics of the board.
######
Test Case ID: TC_DOSBSP60-REQ-3874_002
Test Case Name: Verify accompanying timestamp for temperature queries
Test Type: Positive
Test Design: Ensure that two timestamp values are returned with temperature queries.
Pre-condition: Thermal zone is supported and NvThermmonOpen() returns success for the thermal zone.
Test Procedure:
1. Open a connection to the thermal zone using NvThermmonOpen().
2. Query the temperature for the thermal zone using NvThermmonGetZoneTemp().
3. Retrieve two consecutive temperature values along with two corresponding timestamps.
Expected Result: The API should return success with two timestamp values that do not exceed T microseconds between them.
######
Test Case ID: TC_DOSBSP60-REQ-3874_003
Test Case Name: Verify temperature variation over successive calls
Test Type: Positive
Test Design: Ensure that the temperature for the thermal zone varies over successive queries.
Pre-condition: Thermal zone is supported and NvThermmonOpen() returns success for the thermal zone.
Test Procedure:
1. Open a connection to the thermal zone using NvThermmonOpen().
2. Query the temperature for the thermal zone using NvThermmonGetZoneTemp() multiple times.
3. Compare temperature values over successive calls.
Expected Result: The temperature values should show a difference of >0 and should vary with the resolution supported by the temperature sensor.
測試實現生成?
基于測試規范和 ICD 詳細信息,HEPH 以 C 生成測試。
#include <stdio.h>
#include <stdint.h>
#include "NvThermmonAPI.h"
// Test Case TC_DOSBSP60-REQ-3874_001
// Verify successful temperature query for a supported thermal zone
void TC_DOSBSP60_REQ_3874_001(void) {
NvThermmonHandle handle;
zone_temp_t zoneTemp;
// Step 1: Open a connection to the thermal zone using NvThermmonOpen()
NvThermmonErrCode status = NvThermmonOpen("CPU-therm", &handle);
if (status != NV_THERMMON_ERR_CODE_NO_ERROR) {
printf("TC_DOSBSP60-REQ-3874_001: NvThermmonOpen failed\n");
return;
}
// Step 2: Query the temperature for the thermal zone using NvThermmonGetZoneTemp()
status = NvThermmonGetZoneTemp(handle, &zoneTemp);
if (status != NV_THERMMON_ERR_CODE_NO_ERROR) {
printf("TC_DOSBSP60-REQ-3874_001: NvThermmonGetZoneTemp failed\n");
return;
}
// Step 3: Retrieve two consecutive temperature values
int32_t delta = zoneTemp.temp_2 - zoneTemp.temp_1;
if (delta > 100) { // Assume 100 is the delta determined by the thermal characteristics of the board
printf("TC_DOSBSP60-REQ-3874_001: Temperature delta is too large\n");
} else {
printf("TC_DOSBSP60-REQ-3874_001: Passed\n");
}
}
// Test Case TC_DOSBSP60-REQ-3874_002
// Verify accompanying timestamp for temperature queries
void TC_DOSBSP60_REQ_3874_002(void) {
NvThermmonHandle handle;
zone_temp_t zoneTemp;
// Step 1: Open a connection to the thermal zone using NvThermmonOpen()
NvThermmonErrCode status = NvThermmonOpen("CPU-therm", &handle);
if (status != NV_THERMMON_ERR_CODE_NO_ERROR) {
printf("TC_DOSBSP60-REQ-3874_002: NvThermmonOpen failed\n");
return;
}
// Step 2: Query the temperature for the thermal zone using NvThermmonGetZoneTemp()
status = NvThermmonGetZoneTemp(handle, &zoneTemp);
if (status != NV_THERMMON_ERR_CODE_NO_ERROR) {
printf("TC_DOSBSP60-REQ-3874_002: NvThermmonGetZoneTemp failed\n");
return;
}
// Step 3: Retrieve two consecutive temperature values along with two corresponding timestamps
uint64_t deltaTs = zoneTemp.ts_2 - zoneTemp.ts_1;
if (deltaTs > 1000) { // Assume 1000 microseconds is the maximum allowed delta
printf("TC_DOSBSP60-REQ-3874_002: Timestamp delta is too large\n");
} else {
printf("TC_DOSBSP60-REQ-3874_002: Passed\n");
}
}
// Test Case TC_DOSBSP60-REQ-3874_003
// Verify temperature variation over successive calls
void TC_DOSBSP60_REQ_3874_003(void) {
NvThermmonHandle handle;
zone_temp_t zoneTemp1, zoneTemp2;
// Step 1: Open a connection to the thermal zone using NvThermmonOpen()
NvThermmonErrCode status = NvThermmonOpen("CPU-therm", &handle);
if (status != NV_THERMMON_ERR_CODE_NO_ERROR) {
printf("TC_DOSBSP60-REQ-3874_003: NvThermmonOpen failed\n");
return;
}
// Step 2: Query the temperature for the thermal zone using NvThermmonGetZoneTemp() multiple times
status = NvThermmonGetZoneTemp(handle, &zoneTemp1);
if (status != NV_THERMMON_ERR_CODE_NO_ERROR) {
printf("TC_DOSBSP60-REQ-3874_003: NvThermmonGetZoneTemp (1st call) failed\n");
return;
}
status = NvThermmonGetZoneTemp(handle, &zoneTemp2);
if (status != NV_THERMMON_ERR_CODE_NO_ERROR) {
printf("TC_DOSBSP60-REQ-3874_003: NvThermmonGetZoneTemp (2nd call) failed\n");
return;
}
// Step 3: Compare temperature values over successive calls
int32_t temperatureDifference = zoneTemp2.temp_1 - zoneTemp1.temp_1;
if (temperatureDifference <= 0) {
printf("TC_DOSBSP60-REQ-3874_003: Temperature did not vary as expected\n");
} else {
printf("TC_DOSBSP60-REQ-3874_003: Passed\n");
}
}
未來增強功能?
在設計測試生成框架時,需要關注以下幾個核心問題:
- 支持不同的測試工作流程
- 集成實時人類反饋
支持不同的測試工作流程?
HEPH 旨在支持軟件團隊的大多數測試生成用例。然而,在某些情況下,團隊需要自定義測試框架或不受支持的測試創建工作流程。
為了應對這些挑戰,HEPH 的未來潛在改進可能包括模塊化設計,使軟件團隊能夠為非標準工作流程定義自定義模塊。例如,團隊可能會受益于直接從輸入代碼(而不是文檔)或擴展 LLM 提示生成測試的能力。這種模塊化方法有助于解決自定義和非標準測試生成場景的復雜性。
集成實時人類反饋?
雖然最新的 LLMs 在理解開發環境和生成高質量代碼方面表現良好,但在某些情況下,生成的測試集可能需要改進。
HEPH 未來可能的增強功能包括在當前的自動模式下引入交互模式。在此交互模式下,您將在測試生成過程的每個步驟中與 HEPH 代理進行交互,在繼續之前審查結果、提供反饋并優化輸出。例如,如果生成的測試規范缺乏有關寄存器映射的詳細信息,您可以添加此上下文,HEPH 將重新生成更準確的測試規范。
開始使用 HEPHing 生成自動測試?
Hephaestus (HEPH) 利用大型語言模型 (LLMs) 自動生成全面且上下文感知的測試,從而實現軟件開發中的測試自動化。這種自動化可以減少人工工作量、加速開發并提高最終產品的質量和可靠性。
即將推出的增強功能包括模塊化,允許自定義模塊支持非標準測試工作流程,以及交互模式,允許您提供反饋并優化測試生成流程,以提高準確性和相關性。
構建您的 AI 智能體應用?
有關使用 NVIDIA 生成式 AI 技術和工具創建您自己的 AI 代理和應用的更多信息,請參閱 ai.nvidia.com 或試用 NVIDIA NIM APIs 。
如果您不熟悉此領域,請探索我們的初學者友好型系列: 構建您的首個大型語言模型智能體應用 。
致謝?
感謝 DriveOS QNX BSP 團隊試用 HEPH
?
?