support variable reference during extraction

This commit is contained in:
buyuxiang
2022-06-24 17:46:22 +08:00
parent 51bd652c8c
commit f986a2298a
5 changed files with 27 additions and 25 deletions

View File

@@ -1,6 +1,6 @@
# Release History
## v4.1.5 (2022-06-26)
## v4.1.5 (2022-06-27)
**go version**
@@ -12,6 +12,8 @@
- fix: failed to load json/data content in api reference
- fix: failed to convert postman collection containing multipart/form-data requests to pytest
- fix: only get the first parameter in referenced testcase
- fix: support variable reference during extraction
- fix: simplify jmespath compatibility conversion
**python version**

View File

@@ -123,24 +123,35 @@ type responseObject struct {
const textExtractorSubRegexp string = `(.*)`
func (v *responseObject) searchField(value string) interface{} {
var result interface{}
if strings.Contains(value, textExtractorSubRegexp) {
result = v.searchRegexp(value)
} else {
result = v.searchJmespath(value)
func (v *responseObject) searchField(field string, variablesMapping map[string]interface{}) interface{} {
var result interface{} = field
if strings.Contains(field, "$") {
// parse reference variables in field before search
var err error
result, err = v.parser.Parse(field, variablesMapping)
if err != nil {
log.Error().Str("filed name", field).Err(err).Msg("fail to parse field before search")
}
}
// search field using jmespath or regex if parsed field is still string and contains specified fieldTags
if parsedField, ok := result.(string); ok && checkSearchField(parsedField) {
if strings.Contains(field, textExtractorSubRegexp) {
result = v.searchRegexp(parsedField)
} else {
result = v.searchJmespath(parsedField)
}
}
return result
}
func (v *responseObject) Extract(extractors map[string]string) map[string]interface{} {
func (v *responseObject) Extract(extractors map[string]string, variablesMapping map[string]interface{}) map[string]interface{} {
if extractors == nil {
return nil
}
extractMapping := make(map[string]interface{})
for key, value := range extractors {
extractedValue := v.searchField(value)
extractedValue := v.searchField(value, variablesMapping)
log.Info().Str("from", value).Interface("value", extractedValue).Msg("extract value")
log.Info().Str("variable", key).Interface("value", extractedValue).Msg("set variable")
extractMapping[key] = extractedValue
@@ -157,19 +168,7 @@ func (v *responseObject) Validate(iValidators []interface{}, variablesMapping ma
}
// parse check value
checkItem := validator.Check
var checkValue interface{}
if strings.Contains(checkItem, "$") {
// parse reference variables in checkItem
checkValue, err = v.parser.Parse(checkItem, variablesMapping)
if err != nil {
return err
}
} else {
checkValue = checkItem
}
if searchCheckValue, ok := checkValue.(string); ok && checkSearchField(searchCheckValue) {
checkValue = v.searchField(searchCheckValue)
}
checkValue := v.searchField(checkItem, variablesMapping)
// get assert method
assertMethod := validator.Assert

View File

@@ -419,7 +419,7 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err
// extract variables from response
extractors := step.Extract
extractMapping := respObj.Extract(extractors)
extractMapping := respObj.Extract(extractors, stepVariables)
stepResult.ExportVars = extractMapping
// override step variables with extracted variables

View File

@@ -365,7 +365,7 @@ func runStepWebSocket(r *SessionRunner, step *TStep) (stepResult *StepResult, er
// extract variables from response
extractors := step.Extract
extractMapping := respObj.Extract(extractors)
extractMapping := respObj.Extract(extractors, stepVariables)
stepResult.ExportVars = extractMapping
// override step variables with extracted variables

View File

@@ -18,6 +18,7 @@ func TestCaseExtractStepSingle(t *testing.T) {
"var1": "bar1",
"agent": "HttpRunnerPlus",
"expectedStatusCode": 200,
"jmespathFoo1": "body.args.foo1",
}).
GET("/get").
WithParams(map[string]interface{}{"foo1": "$var1", "foo2": "bar2"}).
@@ -25,7 +26,7 @@ func TestCaseExtractStepSingle(t *testing.T) {
Extract().
WithJmesPath("status_code", "statusCode").
WithJmesPath("headers.\"Content-Type\"", "contentType").
WithJmesPath("body.args.foo1", "varFoo1").
WithJmesPath("$jmespathFoo1", "varFoo1").
Validate().
AssertEqual("$statusCode", "$expectedStatusCode", "check status code"). // assert with extracted variable from current step
AssertEqual("$contentType", "application/json; charset=utf-8", "check header Content-Type"). // assert with extracted variable from current step