From 40a45f2ba9c16fe6af15983e429b252de910932d Mon Sep 17 00:00:00 2001 From: "lilong.129" Date: Tue, 20 Aug 2024 19:54:58 +0800 Subject: [PATCH] refactor: SessionRunner, parseStepStruct --- hrp/runner.go | 56 +++++++++++++++++++++++++------------------ hrp/step_mobile_ui.go | 15 ++---------- hrp/step_request.go | 35 +++++++++++---------------- hrp/step_testcase.go | 10 +------- hrp/step_websocket.go | 35 +++++++++++---------------- 5 files changed, 64 insertions(+), 87 deletions(-) diff --git a/hrp/runner.go b/hrp/runner.go index fd522fa0..bb728f64 100644 --- a/hrp/runner.go +++ b/hrp/runner.go @@ -458,9 +458,9 @@ func (r *SessionRunner) Start(givenVars map[string]interface{}) (summary *TestCa } if client.Device.LogEnabled() { - log, err := client.Driver.StopCaptureLog() + log, err1 := client.Driver.StopCaptureLog() if err != nil { - err = errors.Wrap(err, "get summary failed") + err = errors.Wrap(err1, "get summary failed") return } logs["content"] = log @@ -484,13 +484,13 @@ func (r *SessionRunner) Start(givenVars map[string]interface{}) (summary *TestCa log.Warn().Msg("interrupted in session runner") return summary, errors.Wrap(code.InterruptError, "session runner interrupted") default: - // TODO: parse step struct - // parse step name - parsedName, err := r.caseRunner.parser.ParseString(step.Name(), r.sessionVariables) - if err != nil { - parsedName = step.Name() + // parse step struct + err = r.parseStepStruct(step) + if err != nil && r.caseRunner.hrpRunner.failfast { + return summary, errors.Wrap(err, "parse step struct failed") } - stepName := convertString(parsedName) + + stepName := step.Name() stepType := string(step.Type()) log.Info().Str("step", stepName).Str("type", stepType).Msg("run step start") stepStartTime := time.Now() @@ -563,11 +563,12 @@ func (r *SessionRunner) Start(givenVars map[string]interface{}) (summary *TestCa return summary, nil } -// ParseStepVariables merges step variables with config variables and session variables -func (r *SessionRunner) ParseStepVariables(stepVariables map[string]interface{}) (map[string]interface{}, error) { - // override variables - // step variables > session variables (extracted variables from previous steps) - overrideVars := mergeVariables(stepVariables, r.sessionVariables) +func (r *SessionRunner) parseStepStruct(step IStep) error { + stepStruct := step.Struct() + + // parse step variables: merges step variables with config variables and session variables + // override variables, step variables > session variables (extracted variables from previous steps) + overrideVars := mergeVariables(stepStruct.Variables, r.sessionVariables) // step variables > testcase config variables overrideVars = mergeVariables(overrideVars, r.caseRunner.Config.Variables) @@ -576,26 +577,35 @@ func (r *SessionRunner) ParseStepVariables(stepVariables map[string]interface{}) if err != nil { log.Error().Interface("variables", r.caseRunner.Config.Variables). 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 err error - for _, iValidator := range iValidators { + for _, iValidator := range stepStruct.Validators { validator, ok := iValidator.(Validator) 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 { - return nil, errors.Wrap(err, "failed to parse validator expect") + return errors.Wrap(err, "failed to parse validator expect") } parsedValidators = append(parsedValidators, validator) } - return parsedValidators, nil + stepStruct.Validators = parsedValidators + + return nil } // initWithParameters updates session variables with given parameters. diff --git a/hrp/step_mobile_ui.go b/hrp/step_mobile_ui.go index 34003b02..75435941 100644 --- a/hrp/step_mobile_ui.go +++ b/hrp/step_mobile_ui.go @@ -607,13 +607,6 @@ func runStepMobileUI(s *SessionRunner, step *TStep) (stepResult *StepResult, err 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 uiDriver, err := initUIClient(mobileStep.Serial, osType) if err != nil { @@ -669,7 +662,7 @@ func runStepMobileUI(s *SessionRunner, step *TStep) (stepResult *StepResult, err log.Warn().Msg("interrupted in mobile UI runner") return stepResult, errors.Wrap(code.InterruptError, "mobile UI runner interrupted") 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) { err = errors.Wrap(code.ParseError, fmt.Sprintf("parse action params failed: %v", err)) @@ -686,11 +679,7 @@ func runStepMobileUI(s *SessionRunner, step *TStep) (stepResult *StepResult, err } // validate - stepValidators, err := s.ParseStepValidators(step.Validators, stepVariables) - if err != nil { - return - } - validateResults, err := validateUI(uiDriver, stepValidators) + validateResults, err := validateUI(uiDriver, step.Validators) if err != nil { if !code.IsErrorPredefined(err) { err = errors.Wrap(code.MobileUIValidationError, err.Error()) diff --git a/hrp/step_request.go b/hrp/step_request.go index a94e6867..65092fb8 100644 --- a/hrp/step_request.go +++ b/hrp/step_request.go @@ -284,13 +284,6 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err 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() { // update testcase summary 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 { return } @@ -310,29 +303,29 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err rb := newRequestBuilder(parser, config, step.Request) rb.req.Method = strings.ToUpper(string(step.Request.Method)) - err = rb.prepareUrlParams(stepVariables) + err = rb.prepareUrlParams(step.Variables) if err != nil { return } - err = rb.prepareHeaders(stepVariables) + err = rb.prepareHeaders(step.Variables) if err != nil { return } - err = rb.prepareBody(stepVariables) + err = rb.prepareBody(step.Variables) if err != nil { return } // add request object to step variables, could be used in setup hooks - stepVariables["hrp_step_name"] = step.Name - stepVariables["hrp_step_request"] = rb.requestMap - stepVariables["request"] = rb.requestMap // setup hooks compatible with v3 + step.Variables["hrp_step_name"] = step.Name + step.Variables["hrp_step_request"] = rb.requestMap + step.Variables["request"] = rb.requestMap // setup hooks compatible with v3 // deal with setup hooks for _, setupHook := range step.SetupHooks { - _, err := parser.Parse(setupHook, stepVariables) + _, err := parser.Parse(setupHook, step.Variables) if err != nil { 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 - stepVariables["hrp_step_response"] = respObj.respObjMeta - stepVariables["response"] = respObj.respObjMeta + step.Variables["hrp_step_response"] = respObj.respObjMeta + step.Variables["response"] = respObj.respObjMeta // deal with teardown hooks for _, teardownHook := range step.TeardownHooks { - _, err := parser.Parse(teardownHook, stepVariables) + _, err := parser.Parse(teardownHook, step.Variables) if err != nil { 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 extractors := step.Extract - extractMapping := respObj.Extract(extractors, stepVariables) + extractMapping := respObj.Extract(extractors, step.Variables) stepResult.ExportVars = extractMapping // override step variables with extracted variables - stepVariables = mergeVariables(stepVariables, extractMapping) + step.Variables = mergeVariables(step.Variables, extractMapping) // validate response - err = respObj.Validate(step.Validators, stepVariables) + err = respObj.Validate(step.Validators, step.Variables) sessionData.Validators = respObj.validationResults if err == nil { sessionData.Success = true diff --git a/hrp/step_testcase.go b/hrp/step_testcase.go index b495d657..4ca86bfa 100644 --- a/hrp/step_testcase.go +++ b/hrp/step_testcase.go @@ -5,7 +5,6 @@ import ( "time" "github.com/jinzhu/copier" - "github.com/pkg/errors" "github.com/rs/zerolog/log" ) @@ -52,13 +51,6 @@ func (s *StepTestCaseWithOptionalArgs) Run(r *SessionRunner) (stepResult *StepRe 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() { // update testcase summary if err != nil { @@ -93,7 +85,7 @@ func (s *StepTestCaseWithOptionalArgs) Run(r *SessionRunner) (stepResult *StepRe start := time.Now() var summary *TestCaseSummary // run referenced testcase with step variables - summary, err = sessionRunner.Start(stepVariables) + summary, err = sessionRunner.Start(s.step.Variables) stepResult.Elapsed = time.Since(start).Milliseconds() // update step names diff --git a/hrp/step_websocket.go b/hrp/step_websocket.go index 5a1e0dd9..aaf4abed 100644 --- a/hrp/step_websocket.go +++ b/hrp/step_websocket.go @@ -260,13 +260,6 @@ func runStepWebSocket(r *SessionRunner, step *TStep) (stepResult *StepResult, er 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() { // update testcase summary if err != nil { @@ -285,12 +278,12 @@ func runStepWebSocket(r *SessionRunner, step *TStep) (stepResult *StepResult, er } rb := newRequestBuilder(parser, config, dummyReq) - err = rb.prepareUrlParams(stepVariables) + err = rb.prepareUrlParams(step.Variables) if err != nil { return } - err = rb.prepareHeaders(stepVariables) + err = rb.prepareHeaders(step.Variables) if err != nil { return } @@ -298,12 +291,12 @@ func runStepWebSocket(r *SessionRunner, step *TStep) (stepResult *StepResult, er parsedHeader := rb.req.Header // add request object to step variables, could be used in setup hooks - stepVariables["hrp_step_name"] = step.Name - stepVariables["hrp_step_request"] = rb.requestMap + step.Variables["hrp_step_name"] = step.Name + step.Variables["hrp_step_request"] = rb.requestMap // deal with setup hooks for _, setupHook := range step.SetupHooks { - _, err = parser.Parse(setupHook, stepVariables) + _, err = parser.Parse(setupHook, step.Variables) if err != nil { return stepResult, errors.Wrap(err, "run setup hooks failed") } @@ -329,7 +322,7 @@ func runStepWebSocket(r *SessionRunner, step *TStep) (stepResult *StepResult, er } case wsPing: 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 { return stepResult, errors.Wrap(err, "send ping message failed") } @@ -347,7 +340,7 @@ func runStepWebSocket(r *SessionRunner, step *TStep) (stepResult *StepResult, er }() case wsWriteAndRead: 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 { return stepResult, errors.Wrap(err, "write message failed") } @@ -363,13 +356,13 @@ func runStepWebSocket(r *SessionRunner, step *TStep) (stepResult *StepResult, er } case wsWrite: log.Info().Str("url", parsedURL).Msg("write only") - err = writeWebSocket(parsedURL, r, step, stepVariables) + err = writeWebSocket(parsedURL, r, step, step.Variables) if err != nil { return stepResult, errors.Wrap(err, "write message failed") } case wsClose: 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 { return stepResult, errors.Wrap(err, "close connection failed") } @@ -392,12 +385,12 @@ func runStepWebSocket(r *SessionRunner, step *TStep) (stepResult *StepResult, er if respObj != nil { // 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 for _, teardownHook := range step.TeardownHooks { - _, err = parser.Parse(teardownHook, stepVariables) + _, err = parser.Parse(teardownHook, step.Variables) if err != nil { 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 extractors := step.Extract - extractMapping := respObj.Extract(extractors, stepVariables) + extractMapping := respObj.Extract(extractors, step.Variables) stepResult.ExportVars = extractMapping // override step variables with extracted variables - stepVariables = mergeVariables(stepVariables, extractMapping) + step.Variables = mergeVariables(step.Variables, extractMapping) // validate response - err = respObj.Validate(step.Validators, stepVariables) + err = respObj.Validate(step.Validators, step.Variables) sessionData.Validators = respObj.validationResults if err == nil { sessionData.Success = true