mirror of
https://github.com/httprunner/httprunner.git
synced 2026-09-05 07:26:55 +08:00
feat: data-driven.
This commit is contained in:
@@ -76,7 +76,8 @@ func (b *hrpBoomer) convertBoomerTask(testcase *TestCase) *boomer.Task {
|
|||||||
if err := copier.Copy(caseConfig, cfg); err != nil {
|
if err := copier.Copy(caseConfig, cfg); err != nil {
|
||||||
log.Error().Err(err).Msg("copy config data failed")
|
log.Error().Err(err).Msg("copy config data failed")
|
||||||
}
|
}
|
||||||
for _, it := range cfg.ParametersSetting.Iterator {
|
// iterate through all parameter iterators and update case variables
|
||||||
|
for _, it := range cfg.ParametersSetting.Iterators {
|
||||||
if it.HasNext() {
|
if it.HasNext() {
|
||||||
caseConfig.Variables = mergeVariables(it.Next(), caseConfig.Variables)
|
caseConfig.Variables = mergeVariables(it.Next(), caseConfig.Variables)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ type TConfig struct {
|
|||||||
type TParamsConfig struct {
|
type TParamsConfig struct {
|
||||||
Strategy interface{} `json:"strategy,omitempty" yaml:"strategy,omitempty"`
|
Strategy interface{} `json:"strategy,omitempty" yaml:"strategy,omitempty"`
|
||||||
Iteration int `json:"iteration,omitempty" yaml:"iteration,omitempty"`
|
Iteration int `json:"iteration,omitempty" yaml:"iteration,omitempty"`
|
||||||
Iterator []*Iterator `json:"parameterIterator,omitempty" yaml:"parameterIterator,omitempty"`
|
Iterators []*Iterator `json:"parameterIterator,omitempty" yaml:"parameterIterator,omitempty"` //保存参数的迭代器
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -606,41 +606,42 @@ func initParameterIterator(cfg *TConfig, mode string) (err error) {
|
|||||||
}
|
}
|
||||||
// parse config parameters setting
|
// parse config parameters setting
|
||||||
if cfg.ParametersSetting == nil {
|
if cfg.ParametersSetting == nil {
|
||||||
cfg.ParametersSetting = &TParamsConfig{Iterator: []*Iterator{}}
|
cfg.ParametersSetting = &TParamsConfig{Iterators: []*Iterator{}}
|
||||||
}
|
}
|
||||||
|
// boomer模式下不限制迭代次数
|
||||||
if mode == "boomer" {
|
if mode == "boomer" {
|
||||||
cfg.ParametersSetting.Iteration = -1
|
cfg.ParametersSetting.Iteration = -1
|
||||||
}
|
}
|
||||||
rawValue := reflect.ValueOf(cfg.ParametersSetting.Strategy)
|
rawValue := reflect.ValueOf(cfg.ParametersSetting.Strategy)
|
||||||
switch rawValue.Kind() {
|
switch rawValue.Kind() {
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
// strategy: ["random", "sequential"]
|
// strategy: ["random", "sequential"], 每个参数对应一个迭代器,每个迭代器随机、顺序选取元素互不影响
|
||||||
if len(parameters) != rawValue.Len() {
|
if len(parameters) != rawValue.Len() {
|
||||||
return errors.New("parameters and strategy should have the same length")
|
return errors.New("parameters and strategy should have the same length")
|
||||||
} else {
|
} else {
|
||||||
for i := 0; i < rawValue.Len(); i++ {
|
for i := 0; i < rawValue.Len(); i++ {
|
||||||
cfg.ParametersSetting.Iterator = append(
|
cfg.ParametersSetting.Iterators = append(
|
||||||
cfg.ParametersSetting.Iterator,
|
cfg.ParametersSetting.Iterators,
|
||||||
newIterator(parameters[i], rawValue.Index(i).Interface().(string), cfg.ParametersSetting.Iteration),
|
newIterator(parameters[i], rawValue.Index(i).Interface().(string), cfg.ParametersSetting.Iteration),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
// strategy: "random"
|
// strategy: random, 仅生成一个的迭代器,该迭代器在参数笛卡尔积slice中随机选取元素
|
||||||
if len(rawValue.String()) == 0 {
|
if len(rawValue.String()) == 0 {
|
||||||
cfg.ParametersSetting.Strategy = strategySequential
|
cfg.ParametersSetting.Strategy = strategySequential
|
||||||
} else {
|
} else {
|
||||||
cfg.ParametersSetting.Strategy = strings.ToLower(rawValue.String())
|
cfg.ParametersSetting.Strategy = strings.ToLower(rawValue.String())
|
||||||
}
|
}
|
||||||
cfg.ParametersSetting.Iterator = append(
|
cfg.ParametersSetting.Iterators = append(
|
||||||
cfg.ParametersSetting.Iterator,
|
cfg.ParametersSetting.Iterators,
|
||||||
newIterator(genCartesianProduct(parameters), cfg.ParametersSetting.Strategy.(string), cfg.ParametersSetting.Iteration),
|
newIterator(genCartesianProduct(parameters), cfg.ParametersSetting.Strategy.(string), cfg.ParametersSetting.Iteration),
|
||||||
)
|
)
|
||||||
default:
|
default:
|
||||||
// default strategy: sequential
|
// default strategy: sequential, 仅生成一个的迭代器,该迭代器在参数笛卡尔积slice中顺序选取元素
|
||||||
cfg.ParametersSetting.Strategy = strategySequential
|
cfg.ParametersSetting.Strategy = strategySequential
|
||||||
cfg.ParametersSetting.Iterator = append(
|
cfg.ParametersSetting.Iterators = append(
|
||||||
cfg.ParametersSetting.Iterator,
|
cfg.ParametersSetting.Iterators,
|
||||||
newIterator(genCartesianProduct(parameters), cfg.ParametersSetting.Strategy.(string), cfg.ParametersSetting.Iteration),
|
newIterator(genCartesianProduct(parameters), cfg.ParametersSetting.Strategy.(string), cfg.ParametersSetting.Iteration),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,8 +143,9 @@ func (r *caseRunner) run() error {
|
|||||||
}
|
}
|
||||||
cfg := config.ToStruct()
|
cfg := config.ToStruct()
|
||||||
log.Info().Str("testcase", config.Name()).Msg("run testcase start")
|
log.Info().Str("testcase", config.Name()).Msg("run testcase start")
|
||||||
for it := cfg.ParametersSetting.Iterator[0]; it.HasNext(); {
|
for it := cfg.ParametersSetting.Iterators[0]; it.HasNext(); {
|
||||||
for _, it = range cfg.ParametersSetting.Iterator {
|
// iterate through all parameter iterators and update case variables
|
||||||
|
for _, it = range cfg.ParametersSetting.Iterators {
|
||||||
if it.HasNext() {
|
if it.HasNext() {
|
||||||
cfg.Variables = mergeVariables(it.Next(), cfg.Variables)
|
cfg.Variables = mergeVariables(it.Next(), cfg.Variables)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user