mirror of
https://github.com/httprunner/httprunner.git
synced 2026-09-05 23:51:25 +08:00
add interface request verification method.
This commit is contained in:
+2
-35
@@ -2,15 +2,12 @@ package hrp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/csv"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (tc *TCase) Dump2JSON(path string) error {
|
func (tc *TCase) Dump2JSON(path string) error {
|
||||||
@@ -96,36 +93,6 @@ func loadFromYAML(path string) (*TCase, error) {
|
|||||||
return tc, err
|
return tc, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadFromCSV(path string) []map[string]string {
|
|
||||||
path, err := filepath.Abs(path)
|
|
||||||
if err != nil {
|
|
||||||
log.Error().Str("path", path).Err(err).Msg("convert absolute path failed")
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
log.Info().Str("path", path).Msg("load csv file")
|
|
||||||
|
|
||||||
file, err := ioutil.ReadFile(path)
|
|
||||||
if err != nil {
|
|
||||||
log.Error().Err(err).Msg("load csv file failed")
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
r := csv.NewReader(strings.NewReader(string(file)))
|
|
||||||
content, err := r.ReadAll()
|
|
||||||
if err != nil {
|
|
||||||
log.Error().Err(err).Msg("parse csv file failed")
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
var result []map[string]string
|
|
||||||
for i := 1; i < len(content); i++ {
|
|
||||||
row := make(map[string]string)
|
|
||||||
for j := 0; j < len(content[i]); j++ {
|
|
||||||
row[content[0][j]] = content[i][j]
|
|
||||||
}
|
|
||||||
result = append(result, row)
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tc *TCase) ToTestCase() (*TestCase, error) {
|
func (tc *TCase) ToTestCase() (*TestCase, error) {
|
||||||
testCase := &TestCase{
|
testCase := &TestCase{
|
||||||
Config: &Config{cfg: tc.Config},
|
Config: &Config{cfg: tc.Config},
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ func GreaterThanLength(t assert.TestingT, expected, actual interface{}, msgAndAr
|
|||||||
if !ok {
|
if !ok {
|
||||||
return assert.Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", actual), msgAndArgs...)
|
return assert.Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", actual), msgAndArgs...)
|
||||||
}
|
}
|
||||||
if l > length {
|
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 assert.Fail(t, fmt.Sprintf("\"%s\" should be more than %d item(s), but has %d", actual, length, l), msgAndArgs...)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@@ -86,7 +86,7 @@ func GreaterOrEqualsLength(t assert.TestingT, expected, actual interface{}, msgA
|
|||||||
if !ok {
|
if !ok {
|
||||||
return assert.Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", actual), msgAndArgs...)
|
return assert.Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", actual), msgAndArgs...)
|
||||||
}
|
}
|
||||||
if l >= length {
|
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 assert.Fail(t, fmt.Sprintf("\"%s\" should be no less than %d item(s), but has %d", actual, length, l), msgAndArgs...)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@@ -101,7 +101,7 @@ func LessThanLength(t assert.TestingT, expected, actual interface{}, msgAndArgs
|
|||||||
if !ok {
|
if !ok {
|
||||||
return assert.Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", actual), msgAndArgs...)
|
return assert.Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", actual), msgAndArgs...)
|
||||||
}
|
}
|
||||||
if l < length {
|
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 assert.Fail(t, fmt.Sprintf("\"%s\" should be less than %d item(s), but has %d", actual, length, l), msgAndArgs...)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@@ -116,7 +116,7 @@ func LessOrEqualsLength(t assert.TestingT, expected, actual interface{}, msgAndA
|
|||||||
if !ok {
|
if !ok {
|
||||||
return assert.Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", actual), msgAndArgs...)
|
return assert.Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", actual), msgAndArgs...)
|
||||||
}
|
}
|
||||||
if l <= length {
|
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 assert.Fail(t, fmt.Sprintf("\"%s\" should be no more than %d item(s), but has %d", actual, length, l), msgAndArgs...)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,10 +2,14 @@ package builtin
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
|
"encoding/csv"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"github.com/httprunner/hrp"
|
"github.com/rs/zerolog/log"
|
||||||
|
"io/ioutil"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -15,8 +19,8 @@ var Functions = map[string]interface{}{
|
|||||||
"gen_random_string": genRandomString, // call with one argument
|
"gen_random_string": genRandomString, // call with one argument
|
||||||
"max": math.Max, // call with two arguments
|
"max": math.Max, // call with two arguments
|
||||||
"md5": MD5,
|
"md5": MD5,
|
||||||
"parameterize": hrp.LoadFromCSV,
|
"parameterize": LoadFromCSV,
|
||||||
"P": hrp.LoadFromCSV,
|
"P": LoadFromCSV,
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -47,3 +51,33 @@ func MD5(str string) string {
|
|||||||
hasher.Write([]byte(str))
|
hasher.Write([]byte(str))
|
||||||
return hex.EncodeToString(hasher.Sum(nil))
|
return hex.EncodeToString(hasher.Sum(nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func LoadFromCSV(path string) []map[string]string {
|
||||||
|
path, err := filepath.Abs(path)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Str("path", path).Err(err).Msg("convert absolute path failed")
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
log.Info().Str("path", path).Msg("load csv file")
|
||||||
|
|
||||||
|
file, err := ioutil.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("load csv file failed")
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
r := csv.NewReader(strings.NewReader(string(file)))
|
||||||
|
content, err := r.ReadAll()
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("parse csv file failed")
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
var result []map[string]string
|
||||||
|
for i := 1; i < len(content); i++ {
|
||||||
|
row := make(map[string]string)
|
||||||
|
for j := 0; j < len(content[i]); j++ {
|
||||||
|
row[content[0][j]] = content[i][j]
|
||||||
|
}
|
||||||
|
result = append(result, row)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|||||||
+44
@@ -67,3 +67,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