mirror of
https://github.com/httprunner/httprunner.git
synced 2026-07-10 23:12:41 +08:00
Merge pull request #45 from xucong053/chore/support-rich-interface-request-result-verification-mechanism
feat: add length_less_than, length_less_or_equals, length_greater_than, length_greater_or_equals
This commit is contained in:
@@ -2,6 +2,7 @@ package builtin
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -18,10 +19,14 @@ var Assertions = map[string]func(t assert.TestingT, expected interface{}, actual
|
|||||||
"contains": assert.Contains,
|
"contains": assert.Contains,
|
||||||
"regex_match": assert.Regexp,
|
"regex_match": assert.Regexp,
|
||||||
// custom assertions
|
// custom assertions
|
||||||
"startswith": StartsWith, // check if string starts with substring
|
"startswith": StartsWith, // check if string starts with substring
|
||||||
"endswith": EndsWith, // check if string ends with substring
|
"endswith": EndsWith, // check if string ends with substring
|
||||||
"length_equals": EqualLength,
|
"length_equals": EqualLength,
|
||||||
"length_equal": EqualLength, // alias for length_equals
|
"length_equal": EqualLength, // alias for length_equals
|
||||||
|
"length_less_than": LessThanLength,
|
||||||
|
"length_less_or_equals": LessOrEqualsLength,
|
||||||
|
"length_greater_than": GreaterThanLength,
|
||||||
|
"length_greater_or_equals": GreaterOrEqualsLength,
|
||||||
}
|
}
|
||||||
|
|
||||||
func StartsWith(t assert.TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
|
func StartsWith(t assert.TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||||
@@ -57,6 +62,66 @@ func EqualLength(t assert.TestingT, expected, actual interface{}, msgAndArgs ...
|
|||||||
return assert.Len(t, actual, length, msgAndArgs...)
|
return assert.Len(t, actual, length, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GreaterThanLength(t assert.TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
length, err := convertInt(expected)
|
||||||
|
if err != nil {
|
||||||
|
return assert.Fail(t, fmt.Sprintf("expected type is not int, got %#v", expected), msgAndArgs...)
|
||||||
|
}
|
||||||
|
ok, l := getLen(actual)
|
||||||
|
if !ok {
|
||||||
|
return assert.Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", actual), msgAndArgs...)
|
||||||
|
}
|
||||||
|
if l <= length {
|
||||||
|
return assert.Fail(t, fmt.Sprintf("\"%s\" should be more than %d item(s), but has %d", actual, length, l), msgAndArgs...)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func GreaterOrEqualsLength(t assert.TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
length, err := convertInt(expected)
|
||||||
|
if err != nil {
|
||||||
|
return assert.Fail(t, fmt.Sprintf("expected type is not int, got %#v", expected), msgAndArgs...)
|
||||||
|
}
|
||||||
|
ok, l := getLen(actual)
|
||||||
|
if !ok {
|
||||||
|
return assert.Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", actual), msgAndArgs...)
|
||||||
|
}
|
||||||
|
if l < length {
|
||||||
|
return assert.Fail(t, fmt.Sprintf("\"%s\" should be no less than %d item(s), but has %d", actual, length, l), msgAndArgs...)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func LessThanLength(t assert.TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
length, err := convertInt(expected)
|
||||||
|
if err != nil {
|
||||||
|
return assert.Fail(t, fmt.Sprintf("expected type is not int, got %#v", expected), msgAndArgs...)
|
||||||
|
}
|
||||||
|
ok, l := getLen(actual)
|
||||||
|
if !ok {
|
||||||
|
return assert.Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", actual), msgAndArgs...)
|
||||||
|
}
|
||||||
|
if l >= length {
|
||||||
|
return assert.Fail(t, fmt.Sprintf("\"%s\" should be less than %d item(s), but has %d", actual, length, l), msgAndArgs...)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func LessOrEqualsLength(t assert.TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
length, err := convertInt(expected)
|
||||||
|
if err != nil {
|
||||||
|
return assert.Fail(t, fmt.Sprintf("expected type is not int, got %#v", expected), msgAndArgs...)
|
||||||
|
}
|
||||||
|
ok, l := getLen(actual)
|
||||||
|
if !ok {
|
||||||
|
return assert.Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", actual), msgAndArgs...)
|
||||||
|
}
|
||||||
|
if l > length {
|
||||||
|
return assert.Fail(t, fmt.Sprintf("\"%s\" should be no more than %d item(s), but has %d", actual, length, l), msgAndArgs...)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func convertInt(value interface{}) (int, error) {
|
func convertInt(value interface{}) (int, error) {
|
||||||
switch v := value.(type) {
|
switch v := value.(type) {
|
||||||
case int:
|
case int:
|
||||||
@@ -83,3 +148,15 @@ func convertInt(value interface{}) (int, error) {
|
|||||||
return 0, fmt.Errorf("unsupported int convertion for %v(%T)", v, v)
|
return 0, fmt.Errorf("unsupported int convertion for %v(%T)", v, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getLen try to get length of object.
|
||||||
|
// return (false, 0) if impossible.
|
||||||
|
func getLen(x interface{}) (ok bool, length int) {
|
||||||
|
v := reflect.ValueOf(x)
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
ok = false
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return true, v.Len()
|
||||||
|
}
|
||||||
|
|||||||
@@ -61,3 +61,80 @@ func TestEqualLength(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLessThanLength(t *testing.T) {
|
||||||
|
testData := []struct {
|
||||||
|
raw interface{}
|
||||||
|
expected int
|
||||||
|
}{
|
||||||
|
{"", 1},
|
||||||
|
{[]string{}, 1},
|
||||||
|
{map[string]interface{}{}, 1},
|
||||||
|
{"a", 2},
|
||||||
|
{[]string{"a"}, 2},
|
||||||
|
{map[string]interface{}{"a": 123}, 2},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, data := range testData {
|
||||||
|
if !assert.True(t, LessThanLength(t, data.expected, data.raw)) {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLessOrEqualsLength(t *testing.T) {
|
||||||
|
testData := []struct {
|
||||||
|
raw interface{}
|
||||||
|
expected int
|
||||||
|
}{
|
||||||
|
{"", 1},
|
||||||
|
{[]string{}, 1},
|
||||||
|
{map[string]interface{}{"A": 111}, 1},
|
||||||
|
{"a", 1},
|
||||||
|
{[]string{"a"}, 2},
|
||||||
|
{map[string]interface{}{"a": 123}, 2},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, data := range testData {
|
||||||
|
if !assert.True(t, LessOrEqualsLength(t, data.expected, data.raw)) {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGreaterThanLength(t *testing.T) {
|
||||||
|
testData := []struct {
|
||||||
|
raw interface{}
|
||||||
|
expected int
|
||||||
|
}{
|
||||||
|
{"abcd", 3},
|
||||||
|
{[]string{"a", "b", "c"}, 2},
|
||||||
|
{map[string]interface{}{"a": 123, "b": 223, "c": 323}, 2},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, data := range testData {
|
||||||
|
if !assert.True(t, GreaterThanLength(t, data.expected, data.raw)) {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGreaterOrEqualsLength(t *testing.T) {
|
||||||
|
testData := []struct {
|
||||||
|
raw interface{}
|
||||||
|
expected int
|
||||||
|
}{
|
||||||
|
{"abcd", 3},
|
||||||
|
{[]string{"w"}, 1},
|
||||||
|
{map[string]interface{}{"A": 111}, 1},
|
||||||
|
{"a", 1},
|
||||||
|
{[]string{"a", "b", "c"}, 2},
|
||||||
|
{map[string]interface{}{"a": 123, "b": 223, "c": 323}, 2},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, data := range testData {
|
||||||
|
if !assert.True(t, GreaterOrEqualsLength(t, data.expected, data.raw)) {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
121
validate.go
121
validate.go
@@ -35,6 +35,83 @@ func (s *StepRequestValidation) AssertEqual(jmesPath string, expected interface{
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *StepRequestValidation) AssertGreater(jmesPath string, expected interface{}, msg string) *StepRequestValidation {
|
||||||
|
v := Validator{
|
||||||
|
Check: jmesPath,
|
||||||
|
Assert: "greater_than",
|
||||||
|
Expect: expected,
|
||||||
|
Message: msg,
|
||||||
|
}
|
||||||
|
s.step.Validators = append(s.step.Validators, v)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepRequestValidation) AssertLess(jmesPath string, expected interface{}, msg string) *StepRequestValidation {
|
||||||
|
v := Validator{
|
||||||
|
Check: jmesPath,
|
||||||
|
Assert: "less_than",
|
||||||
|
Expect: expected,
|
||||||
|
Message: msg,
|
||||||
|
}
|
||||||
|
s.step.Validators = append(s.step.Validators, v)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepRequestValidation) AssertGreaterOrEqual(jmesPath string, expected interface{}, msg string) *StepRequestValidation {
|
||||||
|
v := Validator{
|
||||||
|
Check: jmesPath,
|
||||||
|
Assert: "greater_or_equals",
|
||||||
|
Expect: expected,
|
||||||
|
Message: msg,
|
||||||
|
}
|
||||||
|
s.step.Validators = append(s.step.Validators, v)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepRequestValidation) AssertLessOrEqual(jmesPath string, expected interface{}, msg string) *StepRequestValidation {
|
||||||
|
v := Validator{
|
||||||
|
Check: jmesPath,
|
||||||
|
Assert: "less_or_equals",
|
||||||
|
Expect: expected,
|
||||||
|
Message: msg,
|
||||||
|
}
|
||||||
|
s.step.Validators = append(s.step.Validators, v)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepRequestValidation) AssertNotEqual(jmesPath string, expected interface{}, msg string) *StepRequestValidation {
|
||||||
|
v := Validator{
|
||||||
|
Check: jmesPath,
|
||||||
|
Assert: "not_equal",
|
||||||
|
Expect: expected,
|
||||||
|
Message: msg,
|
||||||
|
}
|
||||||
|
s.step.Validators = append(s.step.Validators, v)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepRequestValidation) AssertContains(jmesPath string, expected interface{}, msg string) *StepRequestValidation {
|
||||||
|
v := Validator{
|
||||||
|
Check: jmesPath,
|
||||||
|
Assert: "contains",
|
||||||
|
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,
|
||||||
|
Assert: "regex_match",
|
||||||
|
Expect: expected,
|
||||||
|
Message: msg,
|
||||||
|
}
|
||||||
|
s.step.Validators = append(s.step.Validators, v)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
func (s *StepRequestValidation) AssertStartsWith(jmesPath string, expected interface{}, msg string) *StepRequestValidation {
|
func (s *StepRequestValidation) AssertStartsWith(jmesPath string, expected interface{}, msg string) *StepRequestValidation {
|
||||||
v := Validator{
|
v := Validator{
|
||||||
Check: jmesPath,
|
Check: jmesPath,
|
||||||
@@ -67,3 +144,47 @@ func (s *StepRequestValidation) AssertLengthEqual(jmesPath string, expected inte
|
|||||||
s.step.Validators = append(s.step.Validators, v)
|
s.step.Validators = append(s.step.Validators, v)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *StepRequestValidation) AssertLengthLessThan(jmesPath string, expected interface{}, msg string) *StepRequestValidation {
|
||||||
|
v := Validator{
|
||||||
|
Check: jmesPath,
|
||||||
|
Assert: "length_less_than",
|
||||||
|
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,
|
||||||
|
Assert: "length_less_or_equals",
|
||||||
|
Expect: expected,
|
||||||
|
Message: msg,
|
||||||
|
}
|
||||||
|
s.step.Validators = append(s.step.Validators, v)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepRequestValidation) AssertLengthGreaterThan(jmesPath string, expected interface{}, msg string) *StepRequestValidation {
|
||||||
|
v := Validator{
|
||||||
|
Check: jmesPath,
|
||||||
|
Assert: "length_greater_than",
|
||||||
|
Expect: expected,
|
||||||
|
Message: msg,
|
||||||
|
}
|
||||||
|
s.step.Validators = append(s.step.Validators, v)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepRequestValidation) AssertLengthGreaterOrEquals(jmesPath string, expected interface{}, msg string) *StepRequestValidation {
|
||||||
|
v := Validator{
|
||||||
|
Check: jmesPath,
|
||||||
|
Assert: "length_greater_or_equals",
|
||||||
|
Expect: expected,
|
||||||
|
Message: msg,
|
||||||
|
}
|
||||||
|
s.step.Validators = append(s.step.Validators, v)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user