mirror of
https://github.com/httprunner/httprunner.git
synced 2026-07-09 06:23:52 +08:00
refactor: move files
This commit is contained in:
@@ -1 +1 @@
|
|||||||
v5.0.0+2411092158
|
v5.0.0+2411092254
|
||||||
|
|||||||
@@ -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)
|
|
||||||
}
|
|
||||||
63
hrp/step.go
63
hrp/step.go
@@ -18,3 +18,66 @@ const (
|
|||||||
stepTypeSuffixExtraction StepType = "_extraction"
|
stepTypeSuffixExtraction StepType = "_extraction"
|
||||||
stepTypeSuffixValidation StepType = "_validation"
|
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)
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package hrp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
@@ -737,3 +738,38 @@ func runStepMobileUI(s *SessionRunner, step IStep) (stepResult *StepResult, err
|
|||||||
stepResult.Success = true
|
stepResult.Success = true
|
||||||
return stepResult, nil
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -259,11 +259,11 @@ func initUpload(step *StepRequestWithOptionalArgs) {
|
|||||||
step.Request.Body = "$m_encoder"
|
step.Request.Body = "$m_encoder"
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareUpload(parser *Parser, step *StepRequestWithOptionalArgs, stepVariables map[string]interface{}) (err error) {
|
func prepareUpload(parser *Parser, stepRequest *StepRequest, stepVariables map[string]interface{}) (err error) {
|
||||||
if len(step.Request.Upload) == 0 {
|
if len(stepRequest.Request.Upload) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
uploadMap, err := parser.Parse(step.Request.Upload, stepVariables)
|
uploadMap, err := parser.Parse(stepRequest.Request.Upload, stepVariables)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
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 {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -908,11 +908,7 @@ func (s *StepRequestExtraction) WithJmesPath(jmesPath string, varName string) *S
|
|||||||
// Validate switches to step validation.
|
// Validate switches to step validation.
|
||||||
func (s *StepRequestExtraction) Validate() *StepRequestValidation {
|
func (s *StepRequestExtraction) Validate() *StepRequestValidation {
|
||||||
return &StepRequestValidation{
|
return &StepRequestValidation{
|
||||||
StepRequestWithOptionalArgs: &StepRequestWithOptionalArgs{
|
StepRequestWithOptionalArgs: s.StepRequestWithOptionalArgs,
|
||||||
StepRequest: &StepRequest{
|
|
||||||
StepConfig: s.StepConfig,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import (
|
|||||||
|
|
||||||
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
|
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
|
||||||
"github.com/httprunner/httprunner/v4/hrp/internal/json"
|
"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}
|
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")
|
log.Error().Str("expr", expr).Msg("search regexp failed")
|
||||||
return expr
|
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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -14,6 +14,12 @@ import (
|
|||||||
"github.com/httprunner/httprunner/v4/hrp/pkg/uixt"
|
"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,
|
// ITestCase represents interface for testcases,
|
||||||
// includes TestCase and TestCasePath.
|
// includes TestCase and TestCasePath.
|
||||||
type ITestCase interface {
|
type ITestCase interface {
|
||||||
|
|||||||
Reference in New Issue
Block a user