mirror of
https://github.com/httprunner/httprunner.git
synced 2026-06-03 06:49:38 +08:00
feat: data-driven.
This commit is contained in:
@@ -96,7 +96,7 @@ func loadFromYAML(path string) (*TCase, error) {
|
|||||||
return tc, err
|
return tc, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadFromCSV(path string) []map[string]string {
|
func LoadFromCSV(path string) []map[string]string {
|
||||||
path, err := filepath.Abs(path)
|
path, err := filepath.Abs(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Str("path", path).Err(err).Msg("convert absolute path failed")
|
log.Error().Str("path", path).Err(err).Msg("convert absolute path failed")
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package builtin
|
|||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"github.com/httprunner/hrp"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"time"
|
"time"
|
||||||
@@ -14,7 +15,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,
|
||||||
"getAppVersion": getAppVersion, // test
|
"parameterize": hrp.LoadFromCSV,
|
||||||
|
"P": hrp.LoadFromCSV,
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -45,7 +47,3 @@ 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 getAppVersion() []float64 {
|
|
||||||
return []float64{3.1, 3.3}
|
|
||||||
}
|
|
||||||
|
|||||||
20
parser.go
20
parser.go
@@ -259,25 +259,13 @@ func contains(s []string, e string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func getMappingFunction(funcName string) (interface{}, error) {
|
|
||||||
if function, ok := builtin.Functions[funcName]; ok {
|
|
||||||
// function is builtin
|
|
||||||
return function, nil
|
|
||||||
} else if contains([]string{"parameterize", "P"}, funcName) {
|
|
||||||
// parameterize function
|
|
||||||
return loadFromCSV, nil
|
|
||||||
} else {
|
|
||||||
// function not found
|
|
||||||
return nil, fmt.Errorf("function %s is not found", funcName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// callFunc call function with arguments
|
// callFunc call function with arguments
|
||||||
// only support return at most one result value
|
// only support return at most one result value
|
||||||
func callFunc(funcName string, arguments ...interface{}) (interface{}, error) {
|
func callFunc(funcName string, arguments ...interface{}) (interface{}, error) {
|
||||||
function, err := getMappingFunction(funcName)
|
function, ok := builtin.Functions[funcName]
|
||||||
if err != nil {
|
if !ok {
|
||||||
return nil, err
|
// function not found
|
||||||
|
return nil, fmt.Errorf("function %s is not found", funcName)
|
||||||
}
|
}
|
||||||
funcValue := reflect.ValueOf(function)
|
funcValue := reflect.ValueOf(function)
|
||||||
if funcValue.Kind() != reflect.Func {
|
if funcValue.Kind() != reflect.Func {
|
||||||
|
|||||||
@@ -625,8 +625,11 @@ func TestParseParameters(t *testing.T) {
|
|||||||
expectVars []map[string]interface{}
|
expectVars []map[string]interface{}
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
map[string]interface{}{"username-password": "${parameterize(examples/account.csv)}", "user_agent": []interface{}{"IOS/10.1", "IOS/10.2"}},
|
map[string]interface{}{
|
||||||
[]map[string]interface{}{{"username": "test1", "password": "111111", "user_agent": "IOS/10.1"},
|
"username-password": "${parameterize(examples/account.csv)}",
|
||||||
|
"user_agent": []interface{}{"IOS/10.1", "IOS/10.2"}},
|
||||||
|
[]map[string]interface{}{
|
||||||
|
{"username": "test1", "password": "111111", "user_agent": "IOS/10.1"},
|
||||||
{"username": "test1", "password": "111111", "user_agent": "IOS/10.2"},
|
{"username": "test1", "password": "111111", "user_agent": "IOS/10.2"},
|
||||||
{"username": "test2", "password": "222222", "user_agent": "IOS/10.1"},
|
{"username": "test2", "password": "222222", "user_agent": "IOS/10.1"},
|
||||||
{"username": "test2", "password": "222222", "user_agent": "IOS/10.2"},
|
{"username": "test2", "password": "222222", "user_agent": "IOS/10.2"},
|
||||||
@@ -634,12 +637,23 @@ func TestParseParameters(t *testing.T) {
|
|||||||
{"username": "test3", "password": "333333", "user_agent": "IOS/10.2"}},
|
{"username": "test3", "password": "333333", "user_agent": "IOS/10.2"}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
map[string]interface{}{},
|
map[string]interface{}{
|
||||||
nil,
|
"username-password": [][]interface{}{{"test1", "111111"}, {"test2", "222222"}, {"test3", "333333"}},
|
||||||
|
"user_agent": []interface{}{"IOS/10.1", "IOS/10.2"},
|
||||||
|
"app_version": []interface{}{0.3}},
|
||||||
|
[]map[string]interface{}{
|
||||||
|
{"username": "test1", "password": "111111", "user_agent": "IOS/10.1", "app_version": 0.3},
|
||||||
|
{"username": "test1", "password": "111111", "user_agent": "IOS/10.2", "app_version": 0.3},
|
||||||
|
{"username": "test2", "password": "222222", "user_agent": "IOS/10.1", "app_version": 0.3},
|
||||||
|
{"username": "test2", "password": "222222", "user_agent": "IOS/10.2", "app_version": 0.3},
|
||||||
|
{"username": "test3", "password": "333333", "user_agent": "IOS/10.1", "app_version": 0.3},
|
||||||
|
{"username": "test3", "password": "333333", "user_agent": "IOS/10.2", "app_version": 0.3}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
nil,
|
map[string]interface{}{}, nil,
|
||||||
nil,
|
},
|
||||||
|
{
|
||||||
|
nil, nil,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, data := range testData {
|
for _, data := range testData {
|
||||||
@@ -655,13 +669,19 @@ func TestParseParametersError(t *testing.T) {
|
|||||||
rawVars map[string]interface{}
|
rawVars map[string]interface{}
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
map[string]interface{}{"username_password": "${parameterize(examples/account.csv)}", "user_agent": []interface{}{"IOS/10.1", "IOS/10.2"}},
|
map[string]interface{}{
|
||||||
|
"username_password": "${parameterize(examples/account.csv)}",
|
||||||
|
"user_agent": []interface{}{"IOS/10.1", "IOS/10.2"}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
map[string]interface{}{"username-password": "${parameterize(examples/account.csv)}", "user-agent": []interface{}{"IOS/10.1", "IOS/10.2"}},
|
map[string]interface{}{
|
||||||
|
"username-password": "${parameterize(examples/account.csv)}",
|
||||||
|
"user-agent": []interface{}{"IOS/10.1", "IOS/10.2"}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
map[string]interface{}{"username-password": "${param(examples/account.csv)}", "user_agent": []interface{}{"IOS/10.1", "IOS/10.2"}},
|
map[string]interface{}{
|
||||||
|
"username-password": "${param(examples/account.csv)}",
|
||||||
|
"user_agent": []interface{}{"IOS/10.1", "IOS/10.2"}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, data := range testData {
|
for _, data := range testData {
|
||||||
|
|||||||
Reference in New Issue
Block a user