feat: parse checkItem before searchField

This commit is contained in:
buyuxiang
2022-04-12 20:07:19 +08:00
parent 7259d12562
commit fcb1fb1575
3 changed files with 44 additions and 8 deletions

View File

@@ -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")

View File

@@ -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 {

View File

@@ -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").