docs: update dev instruct

This commit is contained in:
lilong.129
2025-05-27 15:34:41 +08:00
parent 6c60383f70
commit f4cc74b3ca
2 changed files with 227 additions and 35 deletions

View File

@@ -34,8 +34,13 @@ type IStep interface {
- [thinktime](step_thinktime.go):思考时间,按照配置的逻辑进行等待
- [transaction](step_transaction.go):事务机制,用于压测
- [rendezvous](step_rendezvous.go):集合点机制,用于压测
- [mobile_UI](step_mobile_ui.go):移动端 UI 自动化
- [websocket](step_websocket.go)WebSocket 通信
- [android](step_ui.go)Android UI 自动化
- [ios](step_ui.go)iOS UI 自动化
- [harmony](step_ui.go)Harmony UI 自动化
- [browser](step_ui.go):浏览器 UI 自动化
- [shell](step_shell.go):执行 shell 命令
- [function](step_function.go):自定义函数调用
基于该机制,我们可以扩展支持新的协议类型,例如 HTTP2/WebSocket/RPC 等;同时也可以支持新的测试类型,例如 UI 自动化。甚至我们还可以在一个测试用例中混合调用多种不同的 Step 类型,例如实现 HTTP/RPC/UI 混合场景。
@@ -43,28 +48,44 @@ type IStep interface {
### 整体控制器 HRPRunner
执行接口测试时,会初始化一个 `HRPRunner`,用于控制测试的执行策略。
执行测试时,会初始化一个 `HRPRunner`,用于控制测试的执行策略。
```go
type HRPRunner struct {
t *testing.T
failfast bool
requestsLogOn bool
pluginLogOn bool
saveTests bool
genHTMLReport bool
client *http.Client
t *testing.T
failfast bool
httpStatOn bool
requestsLogOn bool
pluginLogOn bool
venv string
saveTests bool
genHTMLReport bool
httpClient *http.Client
http2Client *http.Client
wsDialer *websocket.Dialer
caseTimeoutTimer *time.Timer // case timeout timer
interruptSignal chan os.Signal // interrupt signal channel
}
func (r *HRPRunner) Run(testcases ...ITestCase) error
func (r *HRPRunner) NewCaseRunner(testcase TestCase) (*CaseRunner, error)
func NewCaseRunner(testcase TestCase, hrpRunner *HRPRunner) (*CaseRunner, error)
```
重点关注两个方法:
重点关注方法:
- Run测试执行的主入口支持运行一个或多个测试用例
- NewCaseRunner针对给定的测试用例初始化一个 CaseRunner
HRPRunner 支持多种配置选项:
- SetFailfast配置是否在步骤失败时立即停止
- SetRequestsLogOn开启请求响应详细日志
- SetHTTPStatOn开启 HTTP 延迟统计
- SetPluginLogOn开启插件日志
- SetProxyUrl配置代理 URL用于抓包调试
- SetRequestTimeout配置全局请求超时
- SetCaseTimeout配置测试用例超时
- GenHTMLReport生成 HTML 测试报告
### 用例执行器 CaseRunner
针对每个测试用例,采用 CaseRunner 存储其公共信息,包括 plugin/parser
@@ -96,49 +117,220 @@ type SessionRunner struct {
sessionVariables map[string]interface{} // testcase execution session variables
summary *TestCaseSummary // record test case summary
// transactions stores transaction timing info.
// key is transaction name, value is map of transaction type and time, e.g. start time and end time.
transactions map[string]map[TransactionType]time.Time
// websocket session
ws *wsSession
}
func (r *SessionRunner) Start(givenVars map[string]interface{}) (summary *TestCaseSummary, err error)
func (r *SessionRunner) RunStep(step IStep) (stepResult *StepResult, err error)
func (r *SessionRunner) ParseStep(step IStep) error
```
重点关注一个方法:
重点关注方法:
- Start启动执行用例依次执行所有测试步骤
- RunStep执行单个测试步骤支持循环执行
- ParseStep解析步骤配置包括变量替换和验证器解析
```go
func (r *SessionRunner) Start(givenVars map[string]interface{}) (summary *TestCaseSummary, err error) {
...
r.resetSession()
// report GA event
sdk.SendGA4Event("hrp_session_runner_start", nil)
config := r.caseRunner.TestCase.Config.Get()
log.Info().Str("testcase", config.Name).Msg("run testcase start")
// update config variables with given variables
r.InitWithParameters(givenVars)
defer func() {
// release session resources
r.ReleaseResources()
summary = r.summary
}
summary.Name = config.Name
summary.Time.Duration = time.Since(summary.Time.StartAt).Seconds()
// ... handle export variables and logs
}()
// run step in sequential order
for _, step := range r.testCase.TestSteps {
// parse step
err = r.parseStepStruct(step)
for _, step := range r.caseRunner.TestSteps {
select {
case <-r.caseRunner.hrpRunner.caseTimeoutTimer.C:
log.Warn().Msg("timeout in session runner")
return summary, errors.Wrap(code.TimeoutError, "session runner timeout")
case <-r.caseRunner.hrpRunner.interruptSignal:
log.Warn().Msg("interrupted in session runner")
return summary, errors.Wrap(code.InterruptError, "session runner interrupted")
default:
_, err := r.RunStep(step)
if err == nil {
continue
}
// interrupted or timeout, abort running
if errors.Is(err, code.InterruptError) || errors.Is(err, code.TimeoutError) {
return summary, err
}
// run step
stepResult, err := step.Run(r)
// update summary
r.summary.Records = append(r.summary.Records, stepResult)
// update extracted variables
for k, v := range stepResult.ExportVars {
r.sessionVariables[k] = v
}
// check if failfast
if err != nil && r.caseRunner.hrpRunner.failfast {
return errors.Wrap(err, "abort running due to failfast setting")
// check if failfast
if r.caseRunner.hrpRunner.failfast {
return summary, errors.Wrap(err, "abort running due to failfast setting")
}
}
}
...
log.Info().Str("testcase", config.Name).Msg("run testcase end")
return summary, nil
}
```
在主流程中SessionRunner 并不需要关注 step 的具体类型,统一都是调用 `step.Run(r)`,具体实现逻辑都在对应 step 的 `Run(*SessionRunner)` 方法中。
在主流程中SessionRunner 并不需要关注 step 的具体类型,统一都是调用 `r.RunStep(step)`,具体实现逻辑都在对应 step 的 `Run(*SessionRunner)` 方法中。
## 新增特性
### 1. 超时和中断处理
v5 版本增加了完善的超时和中断处理机制:
- 支持测试用例级别的超时控制
- 支持优雅的中断处理SIGTERM, SIGINT
- 在执行过程中实时检查超时和中断信号
### 2. 多平台 UI 自动化
统一的 UI 自动化接口,支持多个平台:
- **Android**:基于 ADB 和 UIAutomator2
- **iOS**:基于 WebDriverAgent (WDA)
- **Harmony**:基于 HDC (Harmony Device Connector)
- **Browser**:基于 WebDriver 协议
### 3. AI 集成
集成了大模型能力:
- 支持 AI 驱动的 UI 操作
- 通过 MCP (Model Context Protocol) 与大模型通信
- 支持自然语言描述的测试步骤
### 4. 增强的步骤配置
步骤配置支持更多选项:
```go
type StepConfig struct {
StepName string `json:"name" yaml:"name"` // required
Variables map[string]interface{} `json:"variables,omitempty" yaml:"variables,omitempty"`
SetupHooks []string `json:"setup_hooks,omitempty" yaml:"setup_hooks,omitempty"`
TeardownHooks []string `json:"teardown_hooks,omitempty" yaml:"teardown_hooks,omitempty"`
Extract map[string]string `json:"extract,omitempty" yaml:"extract,omitempty"`
Validators []interface{} `json:"validate,omitempty" yaml:"validate,omitempty"`
StepExport []string `json:"export,omitempty" yaml:"export,omitempty"`
Loops *types.IntOrString `json:"loops,omitempty" yaml:"loops,omitempty"`
IgnorePopup bool `json:"ignore_popup,omitempty" yaml:"ignore_popup,omitempty"`
}
```
### 5. 协议支持扩展
除了 HTTP/HTTPS还支持
- HTTP/2 协议
- WebSocket 通信
- 自定义函数调用
### 6. 资源管理
增强的资源管理机制:
- 自动释放会话资源
- UI 驱动器缓存管理
- 日志收集和聚合
## UI 自动化步骤示例
### StepMobile 结构
UI 自动化步骤统一使用 `StepMobile` 结构:
```go
type StepMobile struct {
StepConfig
Mobile *MobileUI `json:"mobile,omitempty" yaml:"mobile,omitempty"`
Android *MobileUI `json:"android,omitempty" yaml:"android,omitempty"`
Harmony *MobileUI `json:"harmony,omitempty" yaml:"harmony,omitempty"`
IOS *MobileUI `json:"ios,omitempty" yaml:"ios,omitempty"`
Browser *MobileUI `json:"browser,omitempty" yaml:"browser,omitempty"`
}
```
### 常用 UI 操作方法
```go
// 基础操作
func (s *StepMobile) TapXY(x, y float64, opts ...option.ActionOption) *StepMobile
func (s *StepMobile) TapByOCR(ocrText string, opts ...option.ActionOption) *StepMobile
func (s *StepMobile) TapByCV(imagePath string, opts ...option.ActionOption) *StepMobile
func (s *StepMobile) AIAction(prompt string, opts ...option.ActionOption) *StepMobile
// 应用管理
func (s *StepMobile) AppLaunch(bundleId string) *StepMobile
func (s *StepMobile) AppTerminate(bundleId string) *StepMobile
func (s *StepMobile) InstallApp(path string) *StepMobile
// 滑动操作
func (s *StepMobile) Swipe(sx, sy, ex, ey float64, opts ...option.ActionOption) *StepMobile
func (s *StepMobile) SwipeUp(opts ...option.ActionOption) *StepMobile
func (s *StepMobile) SwipeDown(opts ...option.ActionOption) *StepMobile
// 输入操作
func (s *StepMobile) Input(text string, opts ...option.ActionOption) *StepMobile
// 等待操作
func (s *StepMobile) Sleep(nSeconds float64, startTime ...time.Time) *StepMobile
func (s *StepMobile) SleepRandom(params ...float64) *StepMobile
// 验证操作
func (s *StepMobile) Validate() *StepMobileUIValidation
```
### UI 验证方法
```go
// OCR 文本验证
func (s *StepMobileUIValidation) AssertOCRExists(expectedText string, msg ...string) *StepMobileUIValidation
func (s *StepMobileUIValidation) AssertOCRNotExists(expectedText string, msg ...string) *StepMobileUIValidation
// 图像验证
func (s *StepMobileUIValidation) AssertImageExists(expectedImagePath string, msg ...string) *StepMobileUIValidation
func (s *StepMobileUIValidation) AssertImageNotExists(expectedImagePath string, msg ...string) *StepMobileUIValidation
// AI 验证
func (s *StepMobileUIValidation) AssertAI(prompt string, msg ...string) *StepMobileUIValidation
// 应用状态验证
func (s *StepMobileUIValidation) AssertAppInForeground(packageName string, msg ...string) *StepMobileUIValidation
func (s *StepMobileUIValidation) AssertAppNotInForeground(packageName string, msg ...string) *StepMobileUIValidation
```
## 开发建议
### 1. 添加新的步骤类型
要添加新的步骤类型,需要:
1.`step.go` 中定义新的 `StepType` 常量
2. 创建实现 `IStep` 接口的结构体
3.`testcase.go``loadISteps` 方法中添加对应的处理逻辑
### 2. 扩展 UI 平台支持
要支持新的 UI 平台:
1.`uixt/` 目录下实现对应的驱动器
2.`StepMobile` 中添加新的平台字段
3.`obj()` 方法中添加对应的处理逻辑
### 3. 调试技巧
- 使用 `SetRequestsLogOn()` 开启详细的请求日志
- 使用 `SetPluginLogOn()` 开启插件日志
- 使用 `SetProxyUrl()` 配置代理进行抓包分析
- 查看生成的 HTML 报告了解执行详情

View File

@@ -1 +1 @@
v5.0.0-beta-2505271528
v5.0.0-beta-2505271534