mirror of
https://github.com/httprunner/httprunner.git
synced 2026-07-06 23:11:21 +08:00
refactor: TestCaseSessionRunner
This commit is contained in:
@@ -96,7 +96,6 @@ func (b *HRPBoomer) convertBoomerTask(testcase *TestCase, rendezvousList []*Rend
|
|||||||
Weight: config.Weight,
|
Weight: config.Weight,
|
||||||
Fn: func() {
|
Fn: func() {
|
||||||
sessionRunner := hrpRunner.NewSessionRunner(testcase)
|
sessionRunner := hrpRunner.NewSessionRunner(testcase)
|
||||||
sessionRunner.init()
|
|
||||||
sessionRunner.parser.plugin = plugin
|
sessionRunner.parser.plugin = plugin
|
||||||
|
|
||||||
testcaseSuccess := true // flag whole testcase result
|
testcaseSuccess := true // flag whole testcase result
|
||||||
@@ -136,7 +135,7 @@ func (b *HRPBoomer) convertBoomerTask(testcase *TestCase, rendezvousList []*Rend
|
|||||||
testcaseSuccess = false
|
testcaseSuccess = false
|
||||||
transactionSuccess = false
|
transactionSuccess = false
|
||||||
|
|
||||||
if sessionRunner.hrpRunner.failfast {
|
if hrpRunner.failfast {
|
||||||
log.Error().Msg("abort running due to failfast setting")
|
log.Error().Msg("abort running due to failfast setting")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ import (
|
|||||||
"github.com/httprunner/httprunner/hrp/internal/builtin"
|
"github.com/httprunner/httprunner/hrp/internal/builtin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newParser() *parser {
|
func newParser() *Parser {
|
||||||
return &parser{}
|
return &Parser{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type parser struct {
|
type Parser struct {
|
||||||
plugin funplugin.IPlugin // plugin is used to call functions
|
plugin funplugin.IPlugin // plugin is used to call functions
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,9 +42,9 @@ func buildURL(baseURL, stepURL string) string {
|
|||||||
return uStep.String()
|
return uStep.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) parseHeaders(rawHeaders map[string]string, variablesMapping map[string]interface{}) (map[string]string, error) {
|
func (p *Parser) ParseHeaders(rawHeaders map[string]string, variablesMapping map[string]interface{}) (map[string]string, error) {
|
||||||
parsedHeaders := make(map[string]string)
|
parsedHeaders := make(map[string]string)
|
||||||
headers, err := p.parseData(rawHeaders, variablesMapping)
|
headers, err := p.Parse(rawHeaders, variablesMapping)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rawHeaders, err
|
return rawHeaders, err
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ func convertString(raw interface{}) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) parseData(raw interface{}, variablesMapping map[string]interface{}) (interface{}, error) {
|
func (p *Parser) Parse(raw interface{}, variablesMapping map[string]interface{}) (interface{}, error) {
|
||||||
rawValue := reflect.ValueOf(raw)
|
rawValue := reflect.ValueOf(raw)
|
||||||
switch rawValue.Kind() {
|
switch rawValue.Kind() {
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
@@ -75,11 +75,11 @@ func (p *parser) parseData(raw interface{}, variablesMapping map[string]interfac
|
|||||||
// other string
|
// other string
|
||||||
value := rawValue.String()
|
value := rawValue.String()
|
||||||
value = strings.TrimSpace(value)
|
value = strings.TrimSpace(value)
|
||||||
return p.parseString(value, variablesMapping)
|
return p.ParseString(value, variablesMapping)
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
parsedSlice := make([]interface{}, rawValue.Len())
|
parsedSlice := make([]interface{}, rawValue.Len())
|
||||||
for i := 0; i < rawValue.Len(); i++ {
|
for i := 0; i < rawValue.Len(); i++ {
|
||||||
parsedValue, err := p.parseData(rawValue.Index(i).Interface(), variablesMapping)
|
parsedValue, err := p.Parse(rawValue.Index(i).Interface(), variablesMapping)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return raw, err
|
return raw, err
|
||||||
}
|
}
|
||||||
@@ -89,12 +89,12 @@ func (p *parser) parseData(raw interface{}, variablesMapping map[string]interfac
|
|||||||
case reflect.Map: // convert any map to map[string]interface{}
|
case reflect.Map: // convert any map to map[string]interface{}
|
||||||
parsedMap := make(map[string]interface{})
|
parsedMap := make(map[string]interface{})
|
||||||
for _, k := range rawValue.MapKeys() {
|
for _, k := range rawValue.MapKeys() {
|
||||||
parsedKey, err := p.parseString(k.String(), variablesMapping)
|
parsedKey, err := p.ParseString(k.String(), variablesMapping)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return raw, err
|
return raw, err
|
||||||
}
|
}
|
||||||
v := rawValue.MapIndex(k)
|
v := rawValue.MapIndex(k)
|
||||||
parsedValue, err := p.parseData(v.Interface(), variablesMapping)
|
parsedValue, err := p.Parse(v.Interface(), variablesMapping)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return raw, err
|
return raw, err
|
||||||
}
|
}
|
||||||
@@ -131,8 +131,8 @@ var (
|
|||||||
regexCompileNumber = regexp.MustCompile(regexNumber) // parse number
|
regexCompileNumber = regexp.MustCompile(regexNumber) // parse number
|
||||||
)
|
)
|
||||||
|
|
||||||
// parseString parse string with variables
|
// ParseString parse string with variables
|
||||||
func (p *parser) parseString(raw string, variablesMapping map[string]interface{}) (interface{}, error) {
|
func (p *Parser) ParseString(raw string, variablesMapping map[string]interface{}) (interface{}, error) {
|
||||||
matchStartPosition := 0
|
matchStartPosition := 0
|
||||||
parsedString := ""
|
parsedString := ""
|
||||||
remainedString := raw
|
remainedString := raw
|
||||||
@@ -171,12 +171,12 @@ func (p *parser) parseString(raw string, variablesMapping map[string]interface{}
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return raw, err
|
return raw, err
|
||||||
}
|
}
|
||||||
parsedArgs, err := p.parseData(arguments, variablesMapping)
|
parsedArgs, err := p.Parse(arguments, variablesMapping)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return raw, err
|
return raw, err
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := p.callFunc(funcName, parsedArgs.([]interface{})...)
|
result, err := p.CallFunc(funcName, parsedArgs.([]interface{})...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Str("funcName", funcName).Interface("arguments", arguments).
|
log.Error().Str("funcName", funcName).Interface("arguments", arguments).
|
||||||
Err(err).Msg("call function failed")
|
Err(err).Msg("call function failed")
|
||||||
@@ -237,9 +237,9 @@ func (p *parser) parseString(raw string, variablesMapping map[string]interface{}
|
|||||||
return parsedString, nil
|
return parsedString, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// callFunc calls function with arguments
|
// CallFunc calls function with arguments
|
||||||
// only support return at most one result value
|
// only support return at most one result value
|
||||||
func (p *parser) callFunc(funcName string, arguments ...interface{}) (interface{}, error) {
|
func (p *Parser) CallFunc(funcName string, arguments ...interface{}) (interface{}, error) {
|
||||||
// call with plugin function
|
// call with plugin function
|
||||||
if p.plugin != nil && p.plugin.Has(funcName) {
|
if p.plugin != nil && p.plugin.Has(funcName) {
|
||||||
return p.plugin.Call(funcName, arguments...)
|
return p.plugin.Call(funcName, arguments...)
|
||||||
@@ -342,38 +342,6 @@ func mergeSlices(slice, overriddenSlice []string) []string {
|
|||||||
return slice
|
return slice
|
||||||
}
|
}
|
||||||
|
|
||||||
// extend teststep with api, teststep will merge and override referenced api
|
|
||||||
func extendWithAPI(testStep *TStep, overriddenStep *API) {
|
|
||||||
// override api name
|
|
||||||
if testStep.Name == "" {
|
|
||||||
testStep.Name = overriddenStep.Name
|
|
||||||
}
|
|
||||||
// merge & override request
|
|
||||||
testStep.Request = overriddenStep.Request
|
|
||||||
// merge & override variables
|
|
||||||
testStep.Variables = mergeVariables(testStep.Variables, overriddenStep.Variables)
|
|
||||||
// merge & override extractors
|
|
||||||
testStep.Extract = mergeMap(testStep.Extract, overriddenStep.Extract)
|
|
||||||
// merge & override validators
|
|
||||||
testStep.Validators = mergeValidators(testStep.Validators, overriddenStep.Validators)
|
|
||||||
// merge & override setupHooks
|
|
||||||
testStep.SetupHooks = mergeSlices(testStep.SetupHooks, overriddenStep.SetupHooks)
|
|
||||||
// merge & override teardownHooks
|
|
||||||
testStep.TeardownHooks = mergeSlices(testStep.TeardownHooks, overriddenStep.TeardownHooks)
|
|
||||||
}
|
|
||||||
|
|
||||||
// extend referenced testcase with teststep, teststep config merge and override referenced testcase config
|
|
||||||
func extendWithTestCase(testStep *TStep, overriddenTestCase *TestCase) {
|
|
||||||
// override testcase name
|
|
||||||
if testStep.Name != "" {
|
|
||||||
overriddenTestCase.Config.Name = testStep.Name
|
|
||||||
}
|
|
||||||
// merge & override variables
|
|
||||||
overriddenTestCase.Config.Variables = mergeVariables(testStep.Variables, overriddenTestCase.Config.Variables)
|
|
||||||
// merge & override extractors
|
|
||||||
overriddenTestCase.Config.Export = mergeSlices(testStep.Export, overriddenTestCase.Config.Export)
|
|
||||||
}
|
|
||||||
|
|
||||||
var eval = goval.NewEvaluator()
|
var eval = goval.NewEvaluator()
|
||||||
|
|
||||||
// literalEval parse string to number if possible
|
// literalEval parse string to number if possible
|
||||||
@@ -420,7 +388,7 @@ func parseFunctionArguments(argsStr string) ([]interface{}, error) {
|
|||||||
return arguments, nil
|
return arguments, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) parseVariables(variables map[string]interface{}) (map[string]interface{}, error) {
|
func (p *Parser) ParseVariables(variables map[string]interface{}) (map[string]interface{}, error) {
|
||||||
parsedVariables := make(map[string]interface{})
|
parsedVariables := make(map[string]interface{})
|
||||||
var traverseRounds int
|
var traverseRounds int
|
||||||
|
|
||||||
@@ -458,7 +426,7 @@ func (p *parser) parseVariables(variables map[string]interface{}) (map[string]in
|
|||||||
return variables, fmt.Errorf("variable not defined: %v", undefinedVars)
|
return variables, fmt.Errorf("variable not defined: %v", undefinedVars)
|
||||||
}
|
}
|
||||||
|
|
||||||
parsedValue, err := p.parseData(varValue, parsedVariables)
|
parsedValue, err := p.Parse(varValue, parsedVariables)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -588,7 +556,7 @@ func parseParameters(parameters map[string]interface{}, variablesMapping map[str
|
|||||||
case reflect.String:
|
case reflect.String:
|
||||||
// e.g. username-password: ${parameterize(examples/hrp/account.csv)} -> [{"username": "test1", "password": "111111"}, {"username": "test2", "password": "222222"}]
|
// e.g. username-password: ${parameterize(examples/hrp/account.csv)} -> [{"username": "test1", "password": "111111"}, {"username": "test2", "password": "222222"}]
|
||||||
var parsedParameterContent interface{}
|
var parsedParameterContent interface{}
|
||||||
parsedParameterContent, err = newParser().parseString(rawValue.String(), variablesMapping)
|
parsedParameterContent, err = newParser().ParseString(rawValue.String(), variablesMapping)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Interface("parameterContent", rawValue).Msg("[parseParameters] parse parameter content error")
|
log.Error().Interface("parameterContent", rawValue).Msg("[parseParameters] parse parameter content error")
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ func TestParseDataStringWithVariables(t *testing.T) {
|
|||||||
|
|
||||||
parser := newParser()
|
parser := newParser()
|
||||||
for _, data := range testData {
|
for _, data := range testData {
|
||||||
parsedData, err := parser.parseData(data.expr, variablesMapping)
|
parsedData, err := parser.Parse(data.expr, variablesMapping)
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
@@ -188,7 +188,7 @@ func TestParseDataStringWithUndefinedVariables(t *testing.T) {
|
|||||||
|
|
||||||
parser := newParser()
|
parser := newParser()
|
||||||
for _, data := range testData {
|
for _, data := range testData {
|
||||||
parsedData, err := parser.parseData(data.expr, variablesMapping)
|
parsedData, err := parser.Parse(data.expr, variablesMapping)
|
||||||
if !assert.Error(t, err) {
|
if !assert.Error(t, err) {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
@@ -233,7 +233,7 @@ func TestParseDataStringWithVariablesAbnormal(t *testing.T) {
|
|||||||
|
|
||||||
parser := newParser()
|
parser := newParser()
|
||||||
for _, data := range testData {
|
for _, data := range testData {
|
||||||
parsedData, err := parser.parseData(data.expr, variablesMapping)
|
parsedData, err := parser.Parse(data.expr, variablesMapping)
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
@@ -264,7 +264,7 @@ func TestParseDataMapWithVariables(t *testing.T) {
|
|||||||
|
|
||||||
parser := newParser()
|
parser := newParser()
|
||||||
for _, data := range testData {
|
for _, data := range testData {
|
||||||
parsedData, err := parser.parseData(data.expr, variablesMapping)
|
parsedData, err := parser.Parse(data.expr, variablesMapping)
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
@@ -298,7 +298,7 @@ func TestParseHeaders(t *testing.T) {
|
|||||||
|
|
||||||
parser := newParser()
|
parser := newParser()
|
||||||
for _, data := range testData {
|
for _, data := range testData {
|
||||||
parsedHeaders, err := parser.parseHeaders(data.rawHeaders, variablesMapping)
|
parsedHeaders, err := parser.ParseHeaders(data.rawHeaders, variablesMapping)
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
@@ -444,14 +444,14 @@ func TestCallBuiltinFunction(t *testing.T) {
|
|||||||
parser := newParser()
|
parser := newParser()
|
||||||
|
|
||||||
// call function without arguments
|
// call function without arguments
|
||||||
_, err := parser.callFunc("get_timestamp")
|
_, err := parser.CallFunc("get_timestamp")
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
|
|
||||||
// call function with one argument
|
// call function with one argument
|
||||||
timeStart := time.Now()
|
timeStart := time.Now()
|
||||||
_, err = parser.callFunc("sleep", 1)
|
_, err = parser.CallFunc("sleep", 1)
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
@@ -460,7 +460,7 @@ func TestCallBuiltinFunction(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// call function with one argument
|
// call function with one argument
|
||||||
result, err := parser.callFunc("gen_random_string", 10)
|
result, err := parser.CallFunc("gen_random_string", 10)
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
@@ -469,7 +469,7 @@ func TestCallBuiltinFunction(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// call function with two argument
|
// call function with two argument
|
||||||
result, err = parser.callFunc("max", float64(10), 9.99)
|
result, err = parser.CallFunc("max", float64(10), 9.99)
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
@@ -556,7 +556,7 @@ func TestParseDataStringWithFunctions(t *testing.T) {
|
|||||||
|
|
||||||
parser := newParser()
|
parser := newParser()
|
||||||
for _, data := range testData1 {
|
for _, data := range testData1 {
|
||||||
value, err := parser.parseData(data.expr, variablesMapping)
|
value, err := parser.Parse(data.expr, variablesMapping)
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
@@ -575,7 +575,7 @@ func TestParseDataStringWithFunctions(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, data := range testData2 {
|
for _, data := range testData2 {
|
||||||
value, err := parser.parseData(data.expr, variablesMapping)
|
value, err := parser.Parse(data.expr, variablesMapping)
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
@@ -623,7 +623,7 @@ func TestParseVariables(t *testing.T) {
|
|||||||
|
|
||||||
parser := newParser()
|
parser := newParser()
|
||||||
for _, data := range testData {
|
for _, data := range testData {
|
||||||
value, err := parser.parseVariables(data.rawVars)
|
value, err := parser.ParseVariables(data.rawVars)
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
@@ -654,7 +654,7 @@ func TestParseVariablesAbnormal(t *testing.T) {
|
|||||||
|
|
||||||
parser := newParser()
|
parser := newParser()
|
||||||
for _, data := range testData {
|
for _, data := range testData {
|
||||||
value, err := parser.parseVariables(data.rawVars)
|
value, err := parser.ParseVariables(data.rawVars)
|
||||||
if !assert.Error(t, err) {
|
if !assert.Error(t, err) {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import (
|
|||||||
"github.com/httprunner/httprunner/hrp/internal/json"
|
"github.com/httprunner/httprunner/hrp/internal/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newResponseObject(t *testing.T, parser *parser, resp *http.Response) (*responseObject, error) {
|
func newResponseObject(t *testing.T, parser *Parser, resp *http.Response) (*responseObject, error) {
|
||||||
// prepare response headers
|
// prepare response headers
|
||||||
headers := make(map[string]string)
|
headers := make(map[string]string)
|
||||||
for k, v := range resp.Header {
|
for k, v := range resp.Header {
|
||||||
@@ -82,7 +82,7 @@ type respObjMeta struct {
|
|||||||
|
|
||||||
type responseObject struct {
|
type responseObject struct {
|
||||||
t *testing.T
|
t *testing.T
|
||||||
parser *parser
|
parser *Parser
|
||||||
respObjMeta interface{}
|
respObjMeta interface{}
|
||||||
validationResults []*ValidationResult
|
validationResults []*ValidationResult
|
||||||
}
|
}
|
||||||
@@ -126,7 +126,7 @@ func (v *responseObject) Validate(iValidators []interface{}, variablesMapping ma
|
|||||||
var checkValue interface{}
|
var checkValue interface{}
|
||||||
if strings.Contains(checkItem, "$") {
|
if strings.Contains(checkItem, "$") {
|
||||||
// reference variable
|
// reference variable
|
||||||
checkValue, err = v.parser.parseData(checkItem, variablesMapping)
|
checkValue, err = v.parser.Parse(checkItem, variablesMapping)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -143,7 +143,7 @@ func (v *responseObject) Validate(iValidators []interface{}, variablesMapping ma
|
|||||||
}
|
}
|
||||||
|
|
||||||
// parse expected value
|
// parse expected value
|
||||||
expectValue, err := v.parser.parseData(validator.Expect, variablesMapping)
|
expectValue, err := v.parser.Parse(validator.Expect, variablesMapping)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,11 +151,11 @@ func (r *HRPRunner) Run(testcases ...ITestCase) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sessionRunner := r.NewSessionRunner(testcase)
|
sessionRunner := r.NewSessionRunner(testcase)
|
||||||
if err = sessionRunner.Run(); err != nil {
|
if err = sessionRunner.Start(); err != nil {
|
||||||
log.Error().Err(err).Msg("[Run] run testcase failed")
|
log.Error().Err(err).Msg("[Run] run testcase failed")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
caseSummary := sessionRunner.getSummary()
|
caseSummary := sessionRunner.GetSummary()
|
||||||
s.appendCaseSummary(caseSummary)
|
s.appendCaseSummary(caseSummary)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -191,5 +191,6 @@ func (r *HRPRunner) NewSessionRunner(testcase *TestCase) *SessionRunner {
|
|||||||
parser: newParser(),
|
parser: newParser(),
|
||||||
summary: newSummary(),
|
summary: newSummary(),
|
||||||
}
|
}
|
||||||
|
sessionRunner.init()
|
||||||
return sessionRunner
|
return sessionRunner
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
_ "embed"
|
_ "embed"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jinzhu/copier"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
@@ -14,7 +13,7 @@ import (
|
|||||||
type SessionRunner struct {
|
type SessionRunner struct {
|
||||||
testCase *TestCase
|
testCase *TestCase
|
||||||
hrpRunner *HRPRunner
|
hrpRunner *HRPRunner
|
||||||
parser *parser
|
parser *Parser
|
||||||
sessionVariables map[string]interface{}
|
sessionVariables map[string]interface{}
|
||||||
// transactions stores transaction timing info.
|
// transactions stores transaction timing info.
|
||||||
// key is transaction name, value is map of transaction type and time, e.g. start time and end time.
|
// key is transaction name, value is map of transaction type and time, e.g. start time and end time.
|
||||||
@@ -31,8 +30,20 @@ func (r *SessionRunner) init() {
|
|||||||
r.summary.Name = r.testCase.Config.Name
|
r.summary.Name = r.testCase.Config.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run runs the test steps in sequential order.
|
func (r *SessionRunner) GetParser() *Parser {
|
||||||
func (r *SessionRunner) Run() error {
|
return r.parser
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *SessionRunner) GetConfig() *TConfig {
|
||||||
|
return r.testCase.Config
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *SessionRunner) LogOn() bool {
|
||||||
|
return r.hrpRunner.requestsLogOn
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start runs the test steps in sequential order.
|
||||||
|
func (r *SessionRunner) Start() error {
|
||||||
config := r.testCase.Config
|
config := r.testCase.Config
|
||||||
log.Info().Str("testcase", config.Name).Msg("run testcase start")
|
log.Info().Str("testcase", config.Name).Msg("run testcase start")
|
||||||
|
|
||||||
@@ -68,48 +79,46 @@ func (r *SessionRunner) Run() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *SessionRunner) overrideVariables(step *TStep) (*TStep, error) {
|
func (r *SessionRunner) UpdateSession(vars map[string]interface{}) {
|
||||||
// copy step and config to avoid data racing
|
for k, v := range vars {
|
||||||
copiedStep := &TStep{}
|
r.sessionVariables[k] = v
|
||||||
if err := copier.Copy(copiedStep, step); err != nil {
|
|
||||||
log.Error().Err(err).Msg("copy step data failed")
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stepVariables := copiedStep.Variables
|
|
||||||
// override variables
|
|
||||||
// step variables > session variables (extracted variables from previous steps)
|
|
||||||
stepVariables = mergeVariables(stepVariables, r.sessionVariables)
|
|
||||||
// step variables > testcase config variables
|
|
||||||
stepVariables = mergeVariables(stepVariables, r.testCase.Config.Variables)
|
|
||||||
|
|
||||||
// parse step variables
|
|
||||||
parsedVariables, err := r.parser.parseVariables(stepVariables)
|
|
||||||
if err != nil {
|
|
||||||
log.Error().Interface("variables", r.testCase.Config.Variables).Err(err).Msg("parse step variables failed")
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
copiedStep.Variables = parsedVariables // avoid data racing
|
|
||||||
return copiedStep, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *SessionRunner) overrideConfig(step *TStep) {
|
// UpdateSummary appends step result to summary
|
||||||
// override headers
|
func (r *SessionRunner) UpdateSummary(stepResult *StepResult) {
|
||||||
if r.testCase.Config.Headers != nil {
|
r.summary.Records = append(r.summary.Records, stepResult)
|
||||||
step.Request.Headers = mergeMap(step.Request.Headers, r.testCase.Config.Headers)
|
r.summary.Stat.Total += 1
|
||||||
|
if stepResult.Success {
|
||||||
|
r.summary.Stat.Successes += 1
|
||||||
|
} else {
|
||||||
|
r.summary.Stat.Failures += 1
|
||||||
|
// update summary result to failed
|
||||||
|
r.summary.Success = false
|
||||||
}
|
}
|
||||||
// parse step request url
|
}
|
||||||
requestUrl, err := r.parser.parseString(step.Request.URL, step.Variables)
|
|
||||||
|
// MergeStepVariables merges step variables with config variables and session variables
|
||||||
|
func (r *SessionRunner) MergeStepVariables(vars map[string]interface{}) (map[string]interface{}, error) {
|
||||||
|
// override variables
|
||||||
|
// step variables > session variables (extracted variables from previous steps)
|
||||||
|
overrideVars := mergeVariables(vars, r.sessionVariables)
|
||||||
|
// step variables > testcase config variables
|
||||||
|
overrideVars = mergeVariables(overrideVars, r.testCase.Config.Variables)
|
||||||
|
|
||||||
|
// parse step variables
|
||||||
|
parsedVariables, err := r.parser.ParseVariables(overrideVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("parse request url failed")
|
log.Error().Interface("variables", r.testCase.Config.Variables).
|
||||||
requestUrl = step.Variables
|
Err(err).Msg("parse step variables failed")
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
step.Request.URL = buildURL(r.testCase.Config.BaseURL, convertString(requestUrl)) // avoid data racing
|
return parsedVariables, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *SessionRunner) parseConfig(cfg *TConfig) error {
|
func (r *SessionRunner) parseConfig(cfg *TConfig) error {
|
||||||
// parse config variables
|
// parse config variables
|
||||||
parsedVariables, err := r.parser.parseVariables(cfg.Variables)
|
parsedVariables, err := r.parser.ParseVariables(cfg.Variables)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Interface("variables", cfg.Variables).Err(err).Msg("parse config variables failed")
|
log.Error().Interface("variables", cfg.Variables).Err(err).Msg("parse config variables failed")
|
||||||
return err
|
return err
|
||||||
@@ -117,14 +126,14 @@ func (r *SessionRunner) parseConfig(cfg *TConfig) error {
|
|||||||
cfg.Variables = parsedVariables
|
cfg.Variables = parsedVariables
|
||||||
|
|
||||||
// parse config name
|
// parse config name
|
||||||
parsedName, err := r.parser.parseString(cfg.Name, cfg.Variables)
|
parsedName, err := r.parser.ParseString(cfg.Name, cfg.Variables)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cfg.Name = convertString(parsedName)
|
cfg.Name = convertString(parsedName)
|
||||||
|
|
||||||
// parse config base url
|
// parse config base url
|
||||||
parsedBaseURL, err := r.parser.parseString(cfg.BaseURL, cfg.Variables)
|
parsedBaseURL, err := r.parser.ParseString(cfg.BaseURL, cfg.Variables)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -136,7 +145,7 @@ func (r *SessionRunner) parseConfig(cfg *TConfig) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *SessionRunner) getSummary() *TestCaseSummary {
|
func (r *SessionRunner) GetSummary() *TestCaseSummary {
|
||||||
caseSummary := r.summary
|
caseSummary := r.summary
|
||||||
caseSummary.Time.StartAt = r.startTime
|
caseSummary.Time.StartAt = r.startTime
|
||||||
caseSummary.Time.Duration = time.Since(r.startTime).Seconds()
|
caseSummary.Time.Duration = time.Since(r.startTime).Seconds()
|
||||||
|
|||||||
@@ -107,3 +107,23 @@ func (s *StepAPIWithOptionalArgs) Run(r *SessionRunner) (*StepResult, error) {
|
|||||||
stepResult.StepType = stepTypeAPI
|
stepResult.StepType = stepTypeAPI
|
||||||
return stepResult, nil
|
return stepResult, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extend teststep with api, teststep will merge and override referenced api
|
||||||
|
func extendWithAPI(testStep *TStep, overriddenStep *API) {
|
||||||
|
// override api name
|
||||||
|
if testStep.Name == "" {
|
||||||
|
testStep.Name = overriddenStep.Name
|
||||||
|
}
|
||||||
|
// merge & override request
|
||||||
|
testStep.Request = overriddenStep.Request
|
||||||
|
// merge & override variables
|
||||||
|
testStep.Variables = mergeVariables(testStep.Variables, overriddenStep.Variables)
|
||||||
|
// merge & override extractors
|
||||||
|
testStep.Extract = mergeMap(testStep.Extract, overriddenStep.Extract)
|
||||||
|
// merge & override validators
|
||||||
|
testStep.Validators = mergeValidators(testStep.Validators, overriddenStep.Validators)
|
||||||
|
// merge & override setupHooks
|
||||||
|
testStep.SetupHooks = mergeSlices(testStep.SetupHooks, overriddenStep.SetupHooks)
|
||||||
|
// merge & override teardownHooks
|
||||||
|
testStep.TeardownHooks = mergeSlices(testStep.TeardownHooks, overriddenStep.TeardownHooks)
|
||||||
|
}
|
||||||
|
|||||||
@@ -51,42 +51,55 @@ type Request struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err error) {
|
func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err error) {
|
||||||
|
|
||||||
step, err = r.overrideVariables(step)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
r.overrideConfig(step)
|
|
||||||
|
|
||||||
log.Info().Str("step", step.Name).Msg("run step start")
|
log.Info().Str("step", step.Name).Msg("run step start")
|
||||||
|
|
||||||
stepResult = &StepResult{
|
stepResult = &StepResult{
|
||||||
Name: step.Name,
|
Name: step.Name,
|
||||||
StepType: stepTypeRequest,
|
StepType: stepTypeRequest,
|
||||||
Success: false,
|
Success: false,
|
||||||
ContentSize: 0,
|
ContentSize: 0,
|
||||||
}
|
}
|
||||||
sessionData := newSessionData()
|
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
|
// update testcase summary
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("run request step failed")
|
log.Error().Err(err).Msg("run request step failed")
|
||||||
stepResult.Attachment = err.Error()
|
stepResult.Attachment = err.Error()
|
||||||
r.summary.Success = false
|
|
||||||
} else {
|
} else {
|
||||||
|
// update extracted variables
|
||||||
|
r.UpdateSession(stepResult.ExportVars)
|
||||||
log.Info().
|
log.Info().
|
||||||
Str("step", step.Name).
|
Str("step", step.Name).
|
||||||
Bool("success", stepResult.Success).
|
Bool("success", stepResult.Success).
|
||||||
Interface("exportVars", stepResult.ExportVars).
|
Interface("exportVars", stepResult.ExportVars).
|
||||||
Msg("run step end")
|
Msg("run step end")
|
||||||
}
|
}
|
||||||
|
r.UpdateSummary(stepResult)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
sessionData := newSessionData()
|
||||||
|
parser := r.GetParser()
|
||||||
|
config := r.GetConfig()
|
||||||
|
|
||||||
|
// override step variables
|
||||||
|
stepVariables, err := r.MergeStepVariables(step.Variables)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// convert request struct to map
|
// convert request struct to map
|
||||||
jsonRequest, _ := json.Marshal(&step.Request)
|
jsonRequest, _ := json.Marshal(&step.Request)
|
||||||
var requestMap map[string]interface{}
|
var requestMap map[string]interface{}
|
||||||
_ = json.Unmarshal(jsonRequest, &requestMap)
|
_ = json.Unmarshal(jsonRequest, &requestMap)
|
||||||
|
|
||||||
rawUrl := step.Request.URL
|
// parse step request url
|
||||||
|
requestUrl, err := r.parser.ParseString(step.Request.URL, stepVariables)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("parse request url failed")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rawUrl := buildURL(r.testCase.Config.BaseURL, convertString(requestUrl))
|
||||||
|
|
||||||
method := step.Request.Method
|
method := step.Request.Method
|
||||||
req := &http.Request{
|
req := &http.Request{
|
||||||
Method: string(method),
|
Method: string(method),
|
||||||
@@ -97,8 +110,14 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// prepare request headers
|
// prepare request headers
|
||||||
if len(step.Request.Headers) > 0 {
|
stepHeaders := step.Request.Headers
|
||||||
headers, err := r.parser.parseHeaders(step.Request.Headers, step.Variables)
|
if config.Headers != nil {
|
||||||
|
// override headers
|
||||||
|
stepHeaders = mergeMap(stepHeaders, config.Headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(stepHeaders) > 0 {
|
||||||
|
headers, err := parser.ParseHeaders(stepHeaders, stepVariables)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stepResult, errors.Wrap(err, "parse headers failed")
|
return stepResult, errors.Wrap(err, "parse headers failed")
|
||||||
}
|
}
|
||||||
@@ -121,7 +140,7 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err
|
|||||||
// prepare request params
|
// prepare request params
|
||||||
var queryParams url.Values
|
var queryParams url.Values
|
||||||
if len(step.Request.Params) > 0 {
|
if len(step.Request.Params) > 0 {
|
||||||
params, err := r.parser.parseData(step.Request.Params, step.Variables)
|
params, err := parser.Parse(step.Request.Params, stepVariables)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stepResult, errors.Wrap(err, "parse request params failed")
|
return stepResult, errors.Wrap(err, "parse request params failed")
|
||||||
}
|
}
|
||||||
@@ -146,7 +165,7 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err
|
|||||||
|
|
||||||
// prepare request cookies
|
// prepare request cookies
|
||||||
for cookieName, cookieValue := range step.Request.Cookies {
|
for cookieName, cookieValue := range step.Request.Cookies {
|
||||||
value, err := r.parser.parseData(cookieValue, step.Variables)
|
value, err := parser.Parse(cookieValue, stepVariables)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stepResult, errors.Wrap(err, "parse cookie value failed")
|
return stepResult, errors.Wrap(err, "parse cookie value failed")
|
||||||
}
|
}
|
||||||
@@ -158,7 +177,7 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err
|
|||||||
|
|
||||||
// prepare request body
|
// prepare request body
|
||||||
if step.Request.Body != nil {
|
if step.Request.Body != nil {
|
||||||
data, err := r.parser.parseData(step.Request.Body, step.Variables)
|
data, err := parser.Parse(step.Request.Body, stepVariables)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stepResult, err
|
return stepResult, err
|
||||||
}
|
}
|
||||||
@@ -232,19 +251,19 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err
|
|||||||
req.Host = u.Host
|
req.Host = u.Host
|
||||||
|
|
||||||
// add request object to step variables, could be used in setup hooks
|
// add request object to step variables, could be used in setup hooks
|
||||||
step.Variables["hrp_step_name"] = step.Name
|
stepVariables["hrp_step_name"] = step.Name
|
||||||
step.Variables["hrp_step_request"] = requestMap
|
stepVariables["hrp_step_request"] = requestMap
|
||||||
|
|
||||||
// deal with setup hooks
|
// deal with setup hooks
|
||||||
for _, setupHook := range step.SetupHooks {
|
for _, setupHook := range step.SetupHooks {
|
||||||
_, err = r.parser.parseData(setupHook, step.Variables)
|
_, err = parser.Parse(setupHook, stepVariables)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stepResult, errors.Wrap(err, "run setup hooks failed")
|
return stepResult, errors.Wrap(err, "run setup hooks failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// log & print request
|
// log & print request
|
||||||
if r.hrpRunner.requestsLogOn {
|
if r.LogOn() {
|
||||||
if err := printRequest(req); err != nil {
|
if err := printRequest(req); err != nil {
|
||||||
return stepResult, err
|
return stepResult, err
|
||||||
}
|
}
|
||||||
@@ -266,25 +285,25 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// log & print response
|
// log & print response
|
||||||
if r.hrpRunner.requestsLogOn {
|
if r.LogOn() {
|
||||||
if err := printResponse(resp); err != nil {
|
if err := printResponse(resp); err != nil {
|
||||||
return stepResult, err
|
return stepResult, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// new response object
|
// new response object
|
||||||
respObj, err := newResponseObject(r.hrpRunner.t, r.parser, resp)
|
respObj, err := newResponseObject(r.hrpRunner.t, parser, resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrap(err, "init ResponseObject error")
|
err = errors.Wrap(err, "init ResponseObject error")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// add response object to step variables, could be used in teardown hooks
|
// add response object to step variables, could be used in teardown hooks
|
||||||
step.Variables["hrp_step_response"] = respObj.respObjMeta
|
stepVariables["hrp_step_response"] = respObj.respObjMeta
|
||||||
|
|
||||||
// deal with teardown hooks
|
// deal with teardown hooks
|
||||||
for _, teardownHook := range step.TeardownHooks {
|
for _, teardownHook := range step.TeardownHooks {
|
||||||
_, err = r.parser.parseData(teardownHook, step.Variables)
|
_, err = parser.Parse(teardownHook, stepVariables)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stepResult, errors.Wrap(err, "run teardown hooks failed")
|
return stepResult, errors.Wrap(err, "run teardown hooks failed")
|
||||||
}
|
}
|
||||||
@@ -298,13 +317,8 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err
|
|||||||
extractMapping := respObj.Extract(extractors)
|
extractMapping := respObj.Extract(extractors)
|
||||||
stepResult.ExportVars = extractMapping
|
stepResult.ExportVars = extractMapping
|
||||||
|
|
||||||
// update extracted variables
|
|
||||||
for k, v := range stepResult.ExportVars {
|
|
||||||
r.sessionVariables[k] = v
|
|
||||||
}
|
|
||||||
|
|
||||||
// override step variables with extracted variables
|
// override step variables with extracted variables
|
||||||
stepVariables := mergeVariables(step.Variables, extractMapping)
|
stepVariables = mergeVariables(stepVariables, extractMapping)
|
||||||
|
|
||||||
// validate response
|
// validate response
|
||||||
err = respObj.Validate(step.Validators, stepVariables)
|
err = respObj.Validate(step.Validators, stepVariables)
|
||||||
@@ -316,15 +330,6 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err
|
|||||||
stepResult.ContentSize = resp.ContentLength
|
stepResult.ContentSize = resp.ContentLength
|
||||||
stepResult.Data = sessionData
|
stepResult.Data = sessionData
|
||||||
|
|
||||||
// append step result to summary
|
|
||||||
r.summary.Records = append(r.summary.Records, stepResult)
|
|
||||||
r.summary.Stat.Total += 1
|
|
||||||
if stepResult.Success {
|
|
||||||
r.summary.Stat.Successes += 1
|
|
||||||
} else {
|
|
||||||
r.summary.Stat.Failures += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return stepResult, err
|
return stepResult, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,18 +44,19 @@ func (s *StepTestCaseWithOptionalArgs) ToStruct() *TStep {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *StepTestCaseWithOptionalArgs) Run(r *SessionRunner) (*StepResult, error) {
|
func (s *StepTestCaseWithOptionalArgs) Run(r *SessionRunner) (*StepResult, error) {
|
||||||
copiedStep, err := r.overrideVariables(s.step)
|
stepVariables, err := r.MergeStepVariables(s.step.Variables)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
s.step.Variables = stepVariables
|
||||||
|
|
||||||
log.Info().Str("testcase", copiedStep.Name).Msg("run referenced testcase")
|
log.Info().Str("testcase", s.step.Name).Msg("run referenced testcase")
|
||||||
stepResult := &StepResult{
|
stepResult := &StepResult{
|
||||||
Name: copiedStep.Name,
|
Name: s.step.Name,
|
||||||
StepType: stepTypeTestCase,
|
StepType: stepTypeTestCase,
|
||||||
Success: false,
|
Success: false,
|
||||||
}
|
}
|
||||||
testcase := copiedStep.TestCase.(*TestCase)
|
testcase := s.step.TestCase.(*TestCase)
|
||||||
|
|
||||||
// copy testcase to avoid data racing
|
// copy testcase to avoid data racing
|
||||||
copiedTestCase := &TestCase{}
|
copiedTestCase := &TestCase{}
|
||||||
@@ -64,21 +65,21 @@ func (s *StepTestCaseWithOptionalArgs) Run(r *SessionRunner) (*StepResult, error
|
|||||||
return stepResult, err
|
return stepResult, err
|
||||||
}
|
}
|
||||||
// override testcase config
|
// override testcase config
|
||||||
extendWithTestCase(copiedStep, copiedTestCase)
|
extendWithTestCase(s.step, copiedTestCase)
|
||||||
|
|
||||||
sessionRunner := r.hrpRunner.NewSessionRunner(copiedTestCase)
|
sessionRunner := r.hrpRunner.NewSessionRunner(copiedTestCase)
|
||||||
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
err = sessionRunner.Run()
|
err = sessionRunner.Start()
|
||||||
stepResult.Elapsed = time.Since(start).Milliseconds()
|
stepResult.Elapsed = time.Since(start).Milliseconds()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("run referenced testcase step failed")
|
log.Error().Err(err).Msg("run referenced testcase step failed")
|
||||||
log.Info().Str("step", copiedStep.Name).Bool("success", false).Msg("run step end")
|
log.Info().Str("step", s.step.Name).Bool("success", false).Msg("run step end")
|
||||||
stepResult.Attachment = err.Error()
|
stepResult.Attachment = err.Error()
|
||||||
r.summary.Success = false
|
r.summary.Success = false
|
||||||
return stepResult, err
|
return stepResult, err
|
||||||
}
|
}
|
||||||
summary := sessionRunner.getSummary()
|
summary := sessionRunner.GetSummary()
|
||||||
stepResult.Data = summary
|
stepResult.Data = summary
|
||||||
// export testcase export variables
|
// export testcase export variables
|
||||||
stepResult.ExportVars = sessionRunner.summary.InOut.ExportVars
|
stepResult.ExportVars = sessionRunner.summary.InOut.ExportVars
|
||||||
@@ -96,10 +97,22 @@ func (s *StepTestCaseWithOptionalArgs) Run(r *SessionRunner) (*StepResult, error
|
|||||||
r.summary.Stat.Failures += summary.Stat.Failures
|
r.summary.Stat.Failures += summary.Stat.Failures
|
||||||
|
|
||||||
log.Info().
|
log.Info().
|
||||||
Str("step", copiedStep.Name).
|
Str("step", s.step.Name).
|
||||||
Bool("success", true).
|
Bool("success", true).
|
||||||
Interface("exportVars", stepResult.ExportVars).
|
Interface("exportVars", stepResult.ExportVars).
|
||||||
Msg("run step end")
|
Msg("run step end")
|
||||||
|
|
||||||
return stepResult, nil
|
return stepResult, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extend referenced testcase with teststep, teststep config merge and override referenced testcase config
|
||||||
|
func extendWithTestCase(testStep *TStep, overriddenTestCase *TestCase) {
|
||||||
|
// override testcase name
|
||||||
|
if testStep.Name != "" {
|
||||||
|
overriddenTestCase.Config.Name = testStep.Name
|
||||||
|
}
|
||||||
|
// merge & override variables
|
||||||
|
overriddenTestCase.Config.Variables = mergeVariables(testStep.Variables, overriddenTestCase.Config.Variables)
|
||||||
|
// merge & override extractors
|
||||||
|
overriddenTestCase.Config.Export = mergeSlices(testStep.Export, overriddenTestCase.Config.Export)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user