refactor: move files

This commit is contained in:
lilong.129
2024-11-09 22:15:07 +08:00
parent d5401c94f2
commit cee68da11b
9 changed files with 111 additions and 116 deletions

View File

@@ -1 +1 @@
v5.0.0+2411092158
v5.0.0+2411092254

View File

@@ -1,70 +0,0 @@
package hrp
// define struct for testcase
type TestCaseDef struct {
Config *TConfig `json:"config" yaml:"config"`
Steps []*TStep `json:"teststeps" yaml:"teststeps"`
}
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 int `json:"loops,omitempty" yaml:"loops,omitempty"`
IgnorePopup bool `json:"ignore_popup,omitempty" yaml:"ignore_popup,omitempty"`
}
// define struct for teststep
type TStep struct {
StepConfig `json:",inline" yaml:",inline"`
Request *Request `json:"request,omitempty" yaml:"request,omitempty"`
API interface{} `json:"api,omitempty" yaml:"api,omitempty"` // *APIPath or *API
TestCase interface{} `json:"testcase,omitempty" yaml:"testcase,omitempty"` // *TestCasePath or *TestCase
Transaction *Transaction `json:"transaction,omitempty" yaml:"transaction,omitempty"`
Rendezvous *Rendezvous `json:"rendezvous,omitempty" yaml:"rendezvous,omitempty"`
ThinkTime *ThinkTime `json:"think_time,omitempty" yaml:"think_time,omitempty"`
WebSocket *WebSocketAction `json:"websocket,omitempty" yaml:"websocket,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"`
Shell *Shell `json:"shell,omitempty" yaml:"shell,omitempty"`
}
// one step contains one or multiple actions
type ActionResult struct {
Name string `json:"name"` // action name
StartTime int64 `json:"start_time"` // action start time
Elapsed int64 `json:"elapsed_ms"` // action elapsed time(ms)
Error error `json:"error"` // action execution result
}
// one testcase contains one or multiple steps
type StepResult struct {
Name string `json:"name" yaml:"name"` // step name
Identifier string `json:"identifier,omitempty" yaml:"identifier,omitempty"` // step identifier
StartTime int64 `json:"start_time" yaml:"time"` // step start time
StepType StepType `json:"step_type" yaml:"step_type"` // step type, testcase/request/transaction/rendezvous
Success bool `json:"success" yaml:"success"` // step execution result
Elapsed int64 `json:"elapsed_ms" yaml:"elapsed_ms"` // step execution time in millisecond(ms)
HttpStat map[string]int64 `json:"httpstat,omitempty" yaml:"httpstat,omitempty"` // httpstat in millisecond(ms)
Data interface{} `json:"data,omitempty" yaml:"data,omitempty"` // step data
ContentSize int64 `json:"content_size" yaml:"content_size"` // response body length
ExportVars map[string]interface{} `json:"export_vars,omitempty" yaml:"export_vars,omitempty"` // extract variables
Actions []*ActionResult `json:"actions,omitempty" yaml:"actions,omitempty"` // store action execution info
Attachments interface{} `json:"attachments,omitempty" yaml:"attachments,omitempty"` // store extra step information, such as error message or screenshots
}
// IStep represents interface for all types for teststeps, includes:
// StepRequest, StepRequestWithOptionalArgs, StepRequestValidation, StepRequestExtraction,
// StepTestCaseWithOptionalArgs,
// StepTransaction, StepRendezvous, StepWebSocket.
type IStep interface {
Name() string
Type() StepType
Config() *StepConfig
Run(*SessionRunner) (*StepResult, error)
}

View File

@@ -18,3 +18,66 @@ const (
stepTypeSuffixExtraction StepType = "_extraction"
stepTypeSuffixValidation StepType = "_validation"
)
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 int `json:"loops,omitempty" yaml:"loops,omitempty"`
IgnorePopup bool `json:"ignore_popup,omitempty" yaml:"ignore_popup,omitempty"`
}
// define struct for teststep
type TStep struct {
StepConfig `json:",inline" yaml:",inline"`
Request *Request `json:"request,omitempty" yaml:"request,omitempty"`
API interface{} `json:"api,omitempty" yaml:"api,omitempty"` // *APIPath or *API
TestCase interface{} `json:"testcase,omitempty" yaml:"testcase,omitempty"` // *TestCasePath or *TestCase
Transaction *Transaction `json:"transaction,omitempty" yaml:"transaction,omitempty"`
Rendezvous *Rendezvous `json:"rendezvous,omitempty" yaml:"rendezvous,omitempty"`
ThinkTime *ThinkTime `json:"think_time,omitempty" yaml:"think_time,omitempty"`
WebSocket *WebSocketAction `json:"websocket,omitempty" yaml:"websocket,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"`
Shell *Shell `json:"shell,omitempty" yaml:"shell,omitempty"`
}
// one step contains one or multiple actions
type ActionResult struct {
Name string `json:"name"` // action name
StartTime int64 `json:"start_time"` // action start time
Elapsed int64 `json:"elapsed_ms"` // action elapsed time(ms)
Error error `json:"error"` // action execution result
}
// one testcase contains one or multiple steps
type StepResult struct {
Name string `json:"name" yaml:"name"` // step name
Identifier string `json:"identifier,omitempty" yaml:"identifier,omitempty"` // step identifier
StartTime int64 `json:"start_time" yaml:"time"` // step start time
StepType StepType `json:"step_type" yaml:"step_type"` // step type, testcase/request/transaction/rendezvous
Success bool `json:"success" yaml:"success"` // step execution result
Elapsed int64 `json:"elapsed_ms" yaml:"elapsed_ms"` // step execution time in millisecond(ms)
HttpStat map[string]int64 `json:"httpstat,omitempty" yaml:"httpstat,omitempty"` // httpstat in millisecond(ms)
Data interface{} `json:"data,omitempty" yaml:"data,omitempty"` // step data
ContentSize int64 `json:"content_size" yaml:"content_size"` // response body length
ExportVars map[string]interface{} `json:"export_vars,omitempty" yaml:"export_vars,omitempty"` // extract variables
Actions []*ActionResult `json:"actions,omitempty" yaml:"actions,omitempty"` // store action execution info
Attachments interface{} `json:"attachments,omitempty" yaml:"attachments,omitempty"` // store extra step information, such as error message or screenshots
}
// IStep represents interface for all types for teststeps, includes:
// StepRequest, StepRequestWithOptionalArgs, StepRequestValidation, StepRequestExtraction,
// StepTestCaseWithOptionalArgs,
// StepTransaction, StepRendezvous, StepWebSocket.
type IStep interface {
Name() string
Type() StepType
Config() *StepConfig
Run(*SessionRunner) (*StepResult, error)
}

View File

@@ -2,6 +2,7 @@ package hrp
import (
"fmt"
"strings"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
@@ -737,3 +738,38 @@ func runStepMobileUI(s *SessionRunner, step IStep) (stepResult *StepResult, err
stepResult.Success = true
return stepResult, nil
}
func validateUI(ud *uixt.DriverExt, iValidators []interface{}) (validateResults []*ValidationResult, err error) {
for _, iValidator := range iValidators {
validator, ok := iValidator.(Validator)
if !ok {
return nil, errors.New("validator type error")
}
validataResult := &ValidationResult{
Validator: validator,
CheckResult: "fail",
}
// parse check value
if !strings.HasPrefix(validator.Check, "ui_") {
validataResult.CheckResult = "skip"
log.Warn().Interface("validator", validator).Msg("skip validator")
validateResults = append(validateResults, validataResult)
continue
}
expected, ok := validator.Expect.(string)
if !ok {
return nil, errors.New("validator expect should be string")
}
if !ud.DoValidation(validator.Check, validator.Assert, expected, validator.Message) {
return validateResults, errors.New("step validation failed")
}
validataResult.CheckResult = "pass"
validateResults = append(validateResults, validataResult)
}
return validateResults, nil
}

View File

@@ -259,11 +259,11 @@ func initUpload(step *StepRequestWithOptionalArgs) {
step.Request.Body = "$m_encoder"
}
func prepareUpload(parser *Parser, step *StepRequestWithOptionalArgs, stepVariables map[string]interface{}) (err error) {
if len(step.Request.Upload) == 0 {
func prepareUpload(parser *Parser, stepRequest *StepRequest, stepVariables map[string]interface{}) (err error) {
if len(stepRequest.Request.Upload) == 0 {
return
}
uploadMap, err := parser.Parse(step.Request.Upload, stepVariables)
uploadMap, err := parser.Parse(stepRequest.Request.Upload, stepVariables)
if err != nil {
return
}
@@ -292,7 +292,7 @@ func runStepRequest(r *SessionRunner, step IStep) (stepResult *StepResult, err e
}
}()
err = prepareUpload(r.caseRunner.parser, stepRequest, stepRequest.Variables)
err = prepareUpload(r.caseRunner.parser, stepRequest.StepRequest, stepRequest.Variables)
if err != nil {
return
}
@@ -908,11 +908,7 @@ func (s *StepRequestExtraction) WithJmesPath(jmesPath string, varName string) *S
// Validate switches to step validation.
func (s *StepRequestExtraction) Validate() *StepRequestValidation {
return &StepRequestValidation{
StepRequestWithOptionalArgs: &StepRequestWithOptionalArgs{
StepRequest: &StepRequest{
StepConfig: s.StepConfig,
},
},
StepRequestWithOptionalArgs: s.StepRequestWithOptionalArgs,
}
}

View File

@@ -16,7 +16,6 @@ import (
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
"github.com/httprunner/httprunner/v4/hrp/internal/json"
"github.com/httprunner/httprunner/v4/hrp/pkg/uixt"
)
var fieldTags = []string{"proto", "status_code", "headers", "cookies", "body", textExtractorSubRegexp}
@@ -273,38 +272,3 @@ func (v *responseObject) searchRegexp(expr string) interface{} {
log.Error().Str("expr", expr).Msg("search regexp failed")
return expr
}
func validateUI(ud *uixt.DriverExt, iValidators []interface{}) (validateResults []*ValidationResult, err error) {
for _, iValidator := range iValidators {
validator, ok := iValidator.(Validator)
if !ok {
return nil, errors.New("validator type error")
}
validataResult := &ValidationResult{
Validator: validator,
CheckResult: "fail",
}
// parse check value
if !strings.HasPrefix(validator.Check, "ui_") {
validataResult.CheckResult = "skip"
log.Warn().Interface("validator", validator).Msg("skip validator")
validateResults = append(validateResults, validataResult)
continue
}
expected, ok := validator.Expect.(string)
if !ok {
return nil, errors.New("validator expect should be string")
}
if !ud.DoValidation(validator.Check, validator.Assert, expected, validator.Message) {
return validateResults, errors.New("step validation failed")
}
validataResult.CheckResult = "pass"
validateResults = append(validateResults, validataResult)
}
return validateResults, nil
}

View File

@@ -14,6 +14,12 @@ import (
"github.com/httprunner/httprunner/v4/hrp/pkg/uixt"
)
// define struct for testcase
type TestCaseDef struct {
Config *TConfig `json:"config" yaml:"config"`
Steps []*TStep `json:"teststeps" yaml:"teststeps"`
}
// ITestCase represents interface for testcases,
// includes TestCase and TestCasePath.
type ITestCase interface {