refactor: SessionRunner, parseStepStruct

This commit is contained in:
lilong.129
2024-08-20 19:54:58 +08:00
parent 140fef90e9
commit 40a45f2ba9
5 changed files with 64 additions and 87 deletions
+33 -23
View File
@@ -458,9 +458,9 @@ func (r *SessionRunner) Start(givenVars map[string]interface{}) (summary *TestCa
} }
if client.Device.LogEnabled() { if client.Device.LogEnabled() {
log, err := client.Driver.StopCaptureLog() log, err1 := client.Driver.StopCaptureLog()
if err != nil { if err != nil {
err = errors.Wrap(err, "get summary failed") err = errors.Wrap(err1, "get summary failed")
return return
} }
logs["content"] = log logs["content"] = log
@@ -484,13 +484,13 @@ func (r *SessionRunner) Start(givenVars map[string]interface{}) (summary *TestCa
log.Warn().Msg("interrupted in session runner") log.Warn().Msg("interrupted in session runner")
return summary, errors.Wrap(code.InterruptError, "session runner interrupted") return summary, errors.Wrap(code.InterruptError, "session runner interrupted")
default: default:
// TODO: parse step struct // parse step struct
// parse step name err = r.parseStepStruct(step)
parsedName, err := r.caseRunner.parser.ParseString(step.Name(), r.sessionVariables) if err != nil && r.caseRunner.hrpRunner.failfast {
if err != nil { return summary, errors.Wrap(err, "parse step struct failed")
parsedName = step.Name()
} }
stepName := convertString(parsedName)
stepName := step.Name()
stepType := string(step.Type()) stepType := string(step.Type())
log.Info().Str("step", stepName).Str("type", stepType).Msg("run step start") log.Info().Str("step", stepName).Str("type", stepType).Msg("run step start")
stepStartTime := time.Now() stepStartTime := time.Now()
@@ -563,11 +563,12 @@ func (r *SessionRunner) Start(givenVars map[string]interface{}) (summary *TestCa
return summary, nil return summary, nil
} }
// ParseStepVariables merges step variables with config variables and session variables func (r *SessionRunner) parseStepStruct(step IStep) error {
func (r *SessionRunner) ParseStepVariables(stepVariables map[string]interface{}) (map[string]interface{}, error) { stepStruct := step.Struct()
// override variables
// step variables > session variables (extracted variables from previous steps) // parse step variables: merges step variables with config variables and session variables
overrideVars := mergeVariables(stepVariables, r.sessionVariables) // override variables, step variables > session variables (extracted variables from previous steps)
overrideVars := mergeVariables(stepStruct.Variables, r.sessionVariables)
// step variables > testcase config variables // step variables > testcase config variables
overrideVars = mergeVariables(overrideVars, r.caseRunner.Config.Variables) overrideVars = mergeVariables(overrideVars, r.caseRunner.Config.Variables)
@@ -576,26 +577,35 @@ func (r *SessionRunner) ParseStepVariables(stepVariables map[string]interface{})
if err != nil { if err != nil {
log.Error().Interface("variables", r.caseRunner.Config.Variables). log.Error().Interface("variables", r.caseRunner.Config.Variables).
Err(err).Msg("parse step variables failed") Err(err).Msg("parse step variables failed")
return nil, errors.Wrap(err, "parse step variables failed") return errors.Wrap(err, "parse step variables failed")
} }
return parsedVariables, nil stepStruct.Variables = parsedVariables
}
func (r *SessionRunner) ParseStepValidators(iValidators []interface{}, stepVariables map[string]interface{}) ([]interface{}, error) { // parse step name
parsedName, err := r.caseRunner.parser.ParseString(
stepStruct.Name, stepStruct.Variables)
if err != nil {
parsedName = step.Name()
}
stepStruct.Name = convertString(parsedName)
// parse step validators
var parsedValidators []interface{} var parsedValidators []interface{}
var err error for _, iValidator := range stepStruct.Validators {
for _, iValidator := range iValidators {
validator, ok := iValidator.(Validator) validator, ok := iValidator.(Validator)
if !ok { if !ok {
return nil, errors.New("validator type error") return errors.New("validator type error")
} }
validator.Expect, err = r.caseRunner.parser.Parse(validator.Expect, stepVariables) validator.Expect, err = r.caseRunner.parser.Parse(
validator.Expect, stepStruct.Variables)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to parse validator expect") return errors.Wrap(err, "failed to parse validator expect")
} }
parsedValidators = append(parsedValidators, validator) parsedValidators = append(parsedValidators, validator)
} }
return parsedValidators, nil stepStruct.Validators = parsedValidators
return nil
} }
// initWithParameters updates session variables with given parameters. // initWithParameters updates session variables with given parameters.
+2 -13
View File
@@ -607,13 +607,6 @@ func runStepMobileUI(s *SessionRunner, step *TStep) (stepResult *StepResult, err
ContentSize: 0, ContentSize: 0,
} }
// merge step variables with session variables
stepVariables, err := s.ParseStepVariables(step.Variables)
if err != nil {
err = errors.Wrap(err, "parse step variables failed")
return
}
// init wda/uia driver // init wda/uia driver
uiDriver, err := initUIClient(mobileStep.Serial, osType) uiDriver, err := initUIClient(mobileStep.Serial, osType)
if err != nil { if err != nil {
@@ -669,7 +662,7 @@ func runStepMobileUI(s *SessionRunner, step *TStep) (stepResult *StepResult, err
log.Warn().Msg("interrupted in mobile UI runner") log.Warn().Msg("interrupted in mobile UI runner")
return stepResult, errors.Wrap(code.InterruptError, "mobile UI runner interrupted") return stepResult, errors.Wrap(code.InterruptError, "mobile UI runner interrupted")
default: default:
if action.Params, err = s.caseRunner.parser.Parse(action.Params, stepVariables); err != nil { if action.Params, err = s.caseRunner.parser.Parse(action.Params, step.Variables); err != nil {
if !code.IsErrorPredefined(err) { if !code.IsErrorPredefined(err) {
err = errors.Wrap(code.ParseError, err = errors.Wrap(code.ParseError,
fmt.Sprintf("parse action params failed: %v", err)) fmt.Sprintf("parse action params failed: %v", err))
@@ -686,11 +679,7 @@ func runStepMobileUI(s *SessionRunner, step *TStep) (stepResult *StepResult, err
} }
// validate // validate
stepValidators, err := s.ParseStepValidators(step.Validators, stepVariables) validateResults, err := validateUI(uiDriver, step.Validators)
if err != nil {
return
}
validateResults, err := validateUI(uiDriver, stepValidators)
if err != nil { if err != nil {
if !code.IsErrorPredefined(err) { if !code.IsErrorPredefined(err) {
err = errors.Wrap(code.MobileUIValidationError, err.Error()) err = errors.Wrap(code.MobileUIValidationError, err.Error())
+14 -21
View File
@@ -284,13 +284,6 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err
ContentSize: 0, ContentSize: 0,
} }
// merge step variables with session variables
stepVariables, err := r.ParseStepVariables(step.Variables)
if err != nil {
err = errors.Wrap(err, "parse step variables failed")
return
}
defer func() { defer func() {
// update testcase summary // update testcase summary
if err != nil { if err != nil {
@@ -298,7 +291,7 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err
} }
}() }()
err = prepareUpload(r.caseRunner.parser, step, stepVariables) err = prepareUpload(r.caseRunner.parser, step, step.Variables)
if err != nil { if err != nil {
return return
} }
@@ -310,29 +303,29 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err
rb := newRequestBuilder(parser, config, step.Request) rb := newRequestBuilder(parser, config, step.Request)
rb.req.Method = strings.ToUpper(string(step.Request.Method)) rb.req.Method = strings.ToUpper(string(step.Request.Method))
err = rb.prepareUrlParams(stepVariables) err = rb.prepareUrlParams(step.Variables)
if err != nil { if err != nil {
return return
} }
err = rb.prepareHeaders(stepVariables) err = rb.prepareHeaders(step.Variables)
if err != nil { if err != nil {
return return
} }
err = rb.prepareBody(stepVariables) err = rb.prepareBody(step.Variables)
if err != nil { if err != nil {
return return
} }
// add request object to step variables, could be used in setup hooks // add request object to step variables, could be used in setup hooks
stepVariables["hrp_step_name"] = step.Name step.Variables["hrp_step_name"] = step.Name
stepVariables["hrp_step_request"] = rb.requestMap step.Variables["hrp_step_request"] = rb.requestMap
stepVariables["request"] = rb.requestMap // setup hooks compatible with v3 step.Variables["request"] = rb.requestMap // setup hooks compatible with v3
// deal with setup hooks // deal with setup hooks
for _, setupHook := range step.SetupHooks { for _, setupHook := range step.SetupHooks {
_, err := parser.Parse(setupHook, stepVariables) _, err := parser.Parse(setupHook, step.Variables)
if err != nil { if err != nil {
return stepResult, errors.Wrap(err, "run setup hooks failed") return stepResult, errors.Wrap(err, "run setup hooks failed")
} }
@@ -405,12 +398,12 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err
} }
// add response object to step variables, could be used in teardown hooks // add response object to step variables, could be used in teardown hooks
stepVariables["hrp_step_response"] = respObj.respObjMeta step.Variables["hrp_step_response"] = respObj.respObjMeta
stepVariables["response"] = respObj.respObjMeta step.Variables["response"] = respObj.respObjMeta
// deal with teardown hooks // deal with teardown hooks
for _, teardownHook := range step.TeardownHooks { for _, teardownHook := range step.TeardownHooks {
_, err := parser.Parse(teardownHook, stepVariables) _, err := parser.Parse(teardownHook, step.Variables)
if err != nil { if err != nil {
return stepResult, errors.Wrap(err, "run teardown hooks failed") return stepResult, errors.Wrap(err, "run teardown hooks failed")
} }
@@ -421,14 +414,14 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err
// extract variables from response // extract variables from response
extractors := step.Extract extractors := step.Extract
extractMapping := respObj.Extract(extractors, stepVariables) extractMapping := respObj.Extract(extractors, step.Variables)
stepResult.ExportVars = extractMapping stepResult.ExportVars = extractMapping
// override step variables with extracted variables // override step variables with extracted variables
stepVariables = mergeVariables(stepVariables, extractMapping) step.Variables = mergeVariables(step.Variables, extractMapping)
// validate response // validate response
err = respObj.Validate(step.Validators, stepVariables) err = respObj.Validate(step.Validators, step.Variables)
sessionData.Validators = respObj.validationResults sessionData.Validators = respObj.validationResults
if err == nil { if err == nil {
sessionData.Success = true sessionData.Success = true
+1 -9
View File
@@ -5,7 +5,6 @@ import (
"time" "time"
"github.com/jinzhu/copier" "github.com/jinzhu/copier"
"github.com/pkg/errors"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
) )
@@ -52,13 +51,6 @@ func (s *StepTestCaseWithOptionalArgs) Run(r *SessionRunner) (stepResult *StepRe
Success: false, Success: false,
} }
// merge step variables with session variables
stepVariables, err := r.ParseStepVariables(s.step.Variables)
if err != nil {
err = errors.Wrap(err, "parse step variables failed")
return
}
defer func() { defer func() {
// update testcase summary // update testcase summary
if err != nil { if err != nil {
@@ -93,7 +85,7 @@ func (s *StepTestCaseWithOptionalArgs) Run(r *SessionRunner) (stepResult *StepRe
start := time.Now() start := time.Now()
var summary *TestCaseSummary var summary *TestCaseSummary
// run referenced testcase with step variables // run referenced testcase with step variables
summary, err = sessionRunner.Start(stepVariables) summary, err = sessionRunner.Start(s.step.Variables)
stepResult.Elapsed = time.Since(start).Milliseconds() stepResult.Elapsed = time.Since(start).Milliseconds()
// update step names // update step names
+14 -21
View File
@@ -260,13 +260,6 @@ func runStepWebSocket(r *SessionRunner, step *TStep) (stepResult *StepResult, er
ContentSize: 0, ContentSize: 0,
} }
// merge step variables with session variables
stepVariables, err := r.ParseStepVariables(step.Variables)
if err != nil {
err = errors.Wrap(err, "parse step variables failed")
return
}
defer func() { defer func() {
// update testcase summary // update testcase summary
if err != nil { if err != nil {
@@ -285,12 +278,12 @@ func runStepWebSocket(r *SessionRunner, step *TStep) (stepResult *StepResult, er
} }
rb := newRequestBuilder(parser, config, dummyReq) rb := newRequestBuilder(parser, config, dummyReq)
err = rb.prepareUrlParams(stepVariables) err = rb.prepareUrlParams(step.Variables)
if err != nil { if err != nil {
return return
} }
err = rb.prepareHeaders(stepVariables) err = rb.prepareHeaders(step.Variables)
if err != nil { if err != nil {
return return
} }
@@ -298,12 +291,12 @@ func runStepWebSocket(r *SessionRunner, step *TStep) (stepResult *StepResult, er
parsedHeader := rb.req.Header parsedHeader := rb.req.Header
// add request object to step variables, could be used in setup hooks // add request object to step variables, could be used in setup hooks
stepVariables["hrp_step_name"] = step.Name step.Variables["hrp_step_name"] = step.Name
stepVariables["hrp_step_request"] = rb.requestMap step.Variables["hrp_step_request"] = rb.requestMap
// deal with setup hooks // deal with setup hooks
for _, setupHook := range step.SetupHooks { for _, setupHook := range step.SetupHooks {
_, err = parser.Parse(setupHook, stepVariables) _, err = parser.Parse(setupHook, step.Variables)
if err != nil { if err != nil {
return stepResult, errors.Wrap(err, "run setup hooks failed") return stepResult, errors.Wrap(err, "run setup hooks failed")
} }
@@ -329,7 +322,7 @@ func runStepWebSocket(r *SessionRunner, step *TStep) (stepResult *StepResult, er
} }
case wsPing: case wsPing:
log.Info().Int64("timeout(ms)", step.WebSocket.GetTimeout()).Str("url", parsedURL).Msg("send ping and expect pong") log.Info().Int64("timeout(ms)", step.WebSocket.GetTimeout()).Str("url", parsedURL).Msg("send ping and expect pong")
err = writeWebSocket(parsedURL, r, step, stepVariables) err = writeWebSocket(parsedURL, r, step, step.Variables)
if err != nil { if err != nil {
return stepResult, errors.Wrap(err, "send ping message failed") return stepResult, errors.Wrap(err, "send ping message failed")
} }
@@ -347,7 +340,7 @@ func runStepWebSocket(r *SessionRunner, step *TStep) (stepResult *StepResult, er
}() }()
case wsWriteAndRead: case wsWriteAndRead:
log.Info().Int64("timeout(ms)", step.WebSocket.GetTimeout()).Str("url", parsedURL).Msg("write a message and read response") log.Info().Int64("timeout(ms)", step.WebSocket.GetTimeout()).Str("url", parsedURL).Msg("write a message and read response")
err = writeWebSocket(parsedURL, r, step, stepVariables) err = writeWebSocket(parsedURL, r, step, step.Variables)
if err != nil { if err != nil {
return stepResult, errors.Wrap(err, "write message failed") return stepResult, errors.Wrap(err, "write message failed")
} }
@@ -363,13 +356,13 @@ func runStepWebSocket(r *SessionRunner, step *TStep) (stepResult *StepResult, er
} }
case wsWrite: case wsWrite:
log.Info().Str("url", parsedURL).Msg("write only") log.Info().Str("url", parsedURL).Msg("write only")
err = writeWebSocket(parsedURL, r, step, stepVariables) err = writeWebSocket(parsedURL, r, step, step.Variables)
if err != nil { if err != nil {
return stepResult, errors.Wrap(err, "write message failed") return stepResult, errors.Wrap(err, "write message failed")
} }
case wsClose: case wsClose:
log.Info().Int64("timeout(ms)", step.WebSocket.GetTimeout()).Str("url", parsedURL).Msg("close webSocket connection") log.Info().Int64("timeout(ms)", step.WebSocket.GetTimeout()).Str("url", parsedURL).Msg("close webSocket connection")
resp, err = closeWithTimeout(parsedURL, r, step, stepVariables) resp, err = closeWithTimeout(parsedURL, r, step, step.Variables)
if err != nil { if err != nil {
return stepResult, errors.Wrap(err, "close connection failed") return stepResult, errors.Wrap(err, "close connection failed")
} }
@@ -392,12 +385,12 @@ func runStepWebSocket(r *SessionRunner, step *TStep) (stepResult *StepResult, er
if respObj != nil { if respObj != nil {
// add response object to step variables, could be used in teardown hooks // add response object to step variables, could be used in teardown hooks
stepVariables["hrp_step_response"] = respObj.respObjMeta step.Variables["hrp_step_response"] = respObj.respObjMeta
} }
// deal with teardown hooks // deal with teardown hooks
for _, teardownHook := range step.TeardownHooks { for _, teardownHook := range step.TeardownHooks {
_, err = parser.Parse(teardownHook, stepVariables) _, err = parser.Parse(teardownHook, step.Variables)
if err != nil { if err != nil {
return stepResult, errors.Wrap(err, "run teardown hooks failed") return stepResult, errors.Wrap(err, "run teardown hooks failed")
} }
@@ -409,14 +402,14 @@ func runStepWebSocket(r *SessionRunner, step *TStep) (stepResult *StepResult, er
// extract variables from response // extract variables from response
extractors := step.Extract extractors := step.Extract
extractMapping := respObj.Extract(extractors, stepVariables) extractMapping := respObj.Extract(extractors, step.Variables)
stepResult.ExportVars = extractMapping stepResult.ExportVars = extractMapping
// override step variables with extracted variables // override step variables with extracted variables
stepVariables = mergeVariables(stepVariables, extractMapping) step.Variables = mergeVariables(step.Variables, extractMapping)
// validate response // validate response
err = respObj.Validate(step.Validators, stepVariables) err = respObj.Validate(step.Validators, step.Variables)
sessionData.Validators = respObj.validationResults sessionData.Validators = respObj.validationResults
if err == nil { if err == nil {
sessionData.Success = true sessionData.Success = true