mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-13 17:29:56 +08:00
feat: parse checkItem before searchField
This commit is contained in:
@@ -91,7 +91,7 @@ type responseObject struct {
|
||||
|
||||
const textExtractorSubRegexp string = `(.*)`
|
||||
|
||||
func (v *responseObject) extractField(value string) interface{} {
|
||||
func (v *responseObject) searchField(value string) interface{} {
|
||||
var result interface{}
|
||||
if strings.Contains(value, textExtractorSubRegexp) {
|
||||
result = v.searchRegexp(value)
|
||||
@@ -108,7 +108,7 @@ func (v *responseObject) Extract(extractors map[string]string) map[string]interf
|
||||
|
||||
extractMapping := make(map[string]interface{})
|
||||
for key, value := range extractors {
|
||||
extractedValue := v.extractField(value)
|
||||
extractedValue := v.searchField(value)
|
||||
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
|
||||
@@ -127,14 +127,16 @@ func (v *responseObject) Validate(iValidators []interface{}, variablesMapping ma
|
||||
checkItem := validator.Check
|
||||
var checkValue interface{}
|
||||
if strings.Contains(checkItem, "$") {
|
||||
// reference variable
|
||||
// parse reference variables in checkItem
|
||||
checkValue, err = v.parser.Parse(checkItem, variablesMapping)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// regExp or jmesPath
|
||||
checkValue = v.extractField(checkItem)
|
||||
checkValue = checkItem
|
||||
}
|
||||
if searchCheckValue, ok := checkValue.(string); ok && checkSearchField(searchCheckValue) {
|
||||
checkValue = v.searchField(searchCheckValue)
|
||||
}
|
||||
|
||||
// get assert method
|
||||
@@ -187,6 +189,15 @@ func (v *responseObject) Validate(iValidators []interface{}, variablesMapping ma
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkSearchField(expr string) bool {
|
||||
return strings.Contains(expr, "proto") ||
|
||||
strings.Contains(expr, "status_code") ||
|
||||
strings.Contains(expr, "headers") ||
|
||||
strings.Contains(expr, "cookies") ||
|
||||
strings.Contains(expr, "body") ||
|
||||
strings.Contains(expr, textExtractorSubRegexp)
|
||||
}
|
||||
|
||||
func (v *responseObject) searchJmespath(expr string) interface{} {
|
||||
checkValue, err := jmespath.Search(expr, v.respObjMeta)
|
||||
if err != nil {
|
||||
@@ -220,7 +231,7 @@ func (v *responseObject) searchRegexp(expr string) interface{} {
|
||||
return expr
|
||||
}
|
||||
match := regexpCompile.FindStringSubmatch(bodyStr)
|
||||
if match != nil || len(match) > 1 {
|
||||
if len(match) > 1 {
|
||||
return match[1] //return first matched result in parentheses
|
||||
}
|
||||
log.Error().Str("expr", expr).Msg("search regexp failed")
|
||||
|
||||
@@ -9,6 +9,30 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSearchJmespath(t *testing.T) {
|
||||
testText := `{"a": {"b": "foo"}, "c": "bar", "d": {"e": [{"f": "foo"}, {"f": "bar"}]}}`
|
||||
testData := []struct {
|
||||
raw string
|
||||
expected string
|
||||
}{
|
||||
{"body.a.b", "foo"},
|
||||
{"body.c", "bar"},
|
||||
{"body.d.e[0].f", "foo"},
|
||||
{"body.d.e[1].f", "bar"},
|
||||
}
|
||||
resp := http.Response{}
|
||||
resp.Body = io.NopCloser(strings.NewReader(testText))
|
||||
respObj, err := newResponseObject(t, newParser(), &resp)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
for _, data := range testData {
|
||||
if !assert.Equal(t, data.expected, respObj.searchJmespath(data.raw)) {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSearchRegexp(t *testing.T) {
|
||||
testText := `hrp aims to be a one-stop solution for HTTP(S) testing, covering API testing, load testing and digital experience monitoring (DEM).`
|
||||
testData := []struct {
|
||||
|
||||
@@ -13,6 +13,7 @@ func TestCaseBasicRequest(t *testing.T) {
|
||||
SetVerifySSL(false),
|
||||
TestSteps: []hrp.IStep{
|
||||
hrp.NewStep("get with params").
|
||||
WithVariables(map[string]interface{}{"headers_key": "\"Content-Type\"", "body_key": "foo1"}).
|
||||
GET("/get").
|
||||
WithParams(map[string]interface{}{"foo1": "bar1", "foo2": "bar2"}).
|
||||
WithHeaders(map[string]string{
|
||||
@@ -20,8 +21,8 @@ func TestCaseBasicRequest(t *testing.T) {
|
||||
}).
|
||||
Validate().
|
||||
AssertEqual("status_code", 200, "check status code").
|
||||
AssertEqual("headers.\"Content-Type\"", "application/json; charset=utf-8", "check header Content-Type").
|
||||
AssertEqual("body.args.foo1", "bar1", "check args foo1").
|
||||
AssertEqual("headers.$headers_key", "application/json; charset=utf-8", "check header Content-Type").
|
||||
AssertEqual("body.args.$body_key", "bar1", "check args foo1").
|
||||
AssertEqual("body.args.foo2", "bar2", "check args foo2"),
|
||||
hrp.NewStep("post raw text").
|
||||
POST("/post").
|
||||
|
||||
Reference in New Issue
Block a user