Merge pull request #42 from bbx-winner/byx/dev

fix: contains assertion bug; feat: add type_match, contained_by, string_equals assertion methods
This commit is contained in:
bbx-winner
2022-01-05 18:48:06 +08:00
committed by GitHub
6 changed files with 107 additions and 4 deletions

44
docs/BUILTIN.md Normal file
View File

@@ -0,0 +1,44 @@
# Builtin
## Assertion Methods
### Usage
In "teststeps" of each json/yaml testcase, the "validate" part contains four fields: "check", "assert", "expect" and
"msg", when using assertion methods, method name should be put in "assert" field. The assertion result of "check"
element will be checked out using the regulation you put in "assert" field and compared with the element in "expect"
field.
### Method List
- equals: assert the element to check equals the expected element.
- equal: alias for equals.
- greater_than: assert the element to check is greater than the expected element.
- less_than: assert the element to check is less than the expected element.
- greater_or_equals: assert the element to check is greater than or equal with the expected element.
- less_or_equals: assert the element to check is less than or equal with the expected element.
- not_equal: assert the element to check is not equal with the expected element.
- contained_by: assert the expected element contains the element to check.
- regex_match: assert the element to check matches the expected element using regex.
- type_match: assert the element to check matches the expected element in type.
- startswith: assert the element to check starts with the expected element.
- endswith: assert the element to check ends with the expected element.
- length_equals: assert the length of the element to check is equal with the expected element.
- length_equal: alias for length_equals.
- contains: assert the element to check contains the expected element.
- string_equals: assert the string is equal with the expected string.
## Common Functions
### Usage
The common functions are useful during the variables configuration, you can use "${FUNCTION_NAME}" to call the specific
function to define variables.
### Function List
- get_timestamp: get the thirteen-digit timestamp of current time. (call without argument)
- sleep: sleep n seconds to simulate the thinking time. (call with one argument n)
- gen_random_string: get the n-digit random string. (call with one argument n)
- max: get the maximum of two numbers m and n. (call with two argument m and n)
- md5: get the MD5 of the input string s. (call with one argument s)

View File

@@ -2,6 +2,7 @@
## v0.3.1 (2021-12-30)
- feat: add more plentiful response assertion methods
- feat: set ulimit to 10240 before load testing
- fix: concurrent map writes in load testing

View File

@@ -19,14 +19,18 @@ func TestCaseCallFunction(t *testing.T) {
TestSteps: []hrp.IStep{
hrp.NewStep("get with params").
GET("/get").
WithParams(map[string]interface{}{"foo1": "${gen_random_string($n)}", "foo2": "${max($a, $b)}"}).
WithParams(map[string]interface{}{"foo1": "${gen_random_string($n)}", "foo2": "${max($a, $b)}", "foo3": "Foo3"}).
WithHeaders(map[string]string{"User-Agent": "HttpRunnerPlus"}).
Extract().
WithJmesPath("body.args.foo1", "varFoo1").
Validate().
AssertEqual("status_code", 200, "check status code").
AssertLengthEqual("body.args.foo1", 5, "check args foo1").
AssertEqual("body.args.foo2", "12.3", "check args foo2"), // notice: request params value will be converted to string
AssertEqual("body.args.foo2", "12.3", "check args foo2").
AssertTypeMatch("body.args.foo3", "str", "check args foo3 is type string").
AssertStringEqual("body.args.foo3", "foo3", "check args foo3 case-insensitivity").
AssertContains("body.args.foo3", "Foo", "check contains ").
AssertContainedBy("body.args.foo3", "this is Foo3 test", "check contained by"), // notice: request params value will be converted to string
hrp.NewStep("post json data with functions").
POST("/post").
WithHeaders(map[string]string{"User-Agent": "HttpRunnerPlus"}).

View File

@@ -16,8 +16,9 @@ var Assertions = map[string]func(t assert.TestingT, expected interface{}, actual
"greater_or_equals": assert.GreaterOrEqual,
"less_or_equals": assert.LessOrEqual,
"not_equal": assert.NotEqual,
"contains": assert.Contains,
"contained_by": assert.Contains,
"regex_match": assert.Regexp,
"type_match": assert.IsType,
// custom assertions
"startswith": StartsWith, // check if string starts with substring
"endswith": EndsWith, // check if string ends with substring
@@ -27,6 +28,8 @@ var Assertions = map[string]func(t assert.TestingT, expected interface{}, actual
"length_less_or_equals": LessOrEqualsLength,
"length_greater_than": GreaterThanLength,
"length_greater_or_equals": GreaterOrEqualsLength,
"contains": Contains,
"string_equals": EqualString,
}
func StartsWith(t assert.TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
@@ -149,6 +152,23 @@ func convertInt(value interface{}) (int, error) {
}
}
// Contains assert whether actual element contains expected element
func Contains(t assert.TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
return assert.Contains(t, actual, expected, msgAndArgs)
}
func EqualString(t assert.TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
if !assert.IsType(t, "string", actual, msgAndArgs) {
return false
}
if !assert.IsType(t, "string", expected, msgAndArgs) {
return false
}
actualString := actual.(string)
expectedString := expected.(string)
return assert.True(t, strings.EqualFold(actualString, expectedString), msgAndArgs)
}
// getLen try to get length of object.
// return (false, 0) if impossible.
func getLen(x interface{}) (ok bool, length int) {

View File

@@ -19,7 +19,7 @@ var Functions = map[string]interface{}{
"sleep": sleep, // call with one argument
"gen_random_string": genRandomString, // call with one argument
"max": math.Max, // call with two arguments
"md5": MD5,
"md5": MD5, // call with one argument
"parameterize": loadFromCSV,
"P": loadFromCSV,
}

View File

@@ -101,6 +101,17 @@ func (s *StepRequestValidation) AssertContains(jmesPath string, expected interfa
return s
}
func (s *StepRequestValidation) AssertTypeMatch(jmesPath string, expected interface{}, msg string) *StepRequestValidation {
v := Validator{
Check: jmesPath,
Assert: "type_match",
Expect: expected,
Message: msg,
}
s.step.Validators = append(s.step.Validators, v)
return s
}
func (s *StepRequestValidation) AssertRegexp(jmesPath string, expected interface{}, msg string) *StepRequestValidation {
v := Validator{
Check: jmesPath,
@@ -145,6 +156,18 @@ func (s *StepRequestValidation) AssertLengthEqual(jmesPath string, expected inte
return s
}
func (s *StepRequestValidation) AssertContainedBy(jmesPath string, expected interface{}, msg string) *StepRequestValidation {
v := Validator{
Check: jmesPath,
Assert: "contained_by",
Expect: expected,
Message: msg,
}
s.step.Validators = append(s.step.Validators, v)
return s
}
func (s *StepRequestValidation) AssertLengthLessThan(jmesPath string, expected interface{}, msg string) *StepRequestValidation {
v := Validator{
Check: jmesPath,
@@ -156,6 +179,17 @@ func (s *StepRequestValidation) AssertLengthLessThan(jmesPath string, expected i
return s
}
func (s *StepRequestValidation) AssertStringEqual(jmesPath string, expected interface{}, msg string) *StepRequestValidation {
v := Validator{
Check: jmesPath,
Assert: "string_equals",
Expect: expected,
Message: msg,
}
s.step.Validators = append(s.step.Validators, v)
return s
}
func (s *StepRequestValidation) AssertLengthLessOrEquals(jmesPath string, expected interface{}, msg string) *StepRequestValidation {
v := Validator{
Check: jmesPath,