Skip to content

Commit

Permalink
feat: extract variables
Browse files Browse the repository at this point in the history
  • Loading branch information
debugtalk committed Sep 30, 2021
1 parent d92b466 commit 2a793cf
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 30 deletions.
2 changes: 1 addition & 1 deletion boomer.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (b *Boomer) convertBoomerTask(testcase *TestCase) *boomer.Task {
config := &testcase.Config
for _, step := range testcase.TestSteps {
start := time.Now()
err := runner.runStep(step, config)
_, err := runner.runStep(step, config)
elapsed := time.Since(start).Nanoseconds() / int64(time.Millisecond)

if err == nil {
Expand Down
26 changes: 13 additions & 13 deletions boomer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ import (
)

func TestHttpBoomer(t *testing.T) {
testcase1 := &TestCase{
Config: TConfig{
Name: "TestCase1",
Weight: 2,
},
}
testcase2 := &TestCase{
Config: TConfig{
Name: "TestCase2",
Weight: 3,
},
}
// testcase1 := &TestCase{
// Config: TConfig{
// Name: "TestCase1",
// Weight: 2,
// },
// }
// testcase2 := &TestCase{
// Config: TConfig{
// Name: "TestCase2",
// Weight: 3,
// },
// }

Run(testcase1, testcase2)
// Run(testcase1, testcase2)
}
6 changes: 6 additions & 0 deletions models.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,9 @@ type TestCase struct {
}

type TestCaseSummary struct{}

type StepData struct {
Name string // step name
Success bool // step execution result
ExportVars map[string]interface{} // extract variables
}
14 changes: 14 additions & 0 deletions response.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,20 @@ type ResponseObject struct {
validationResults map[string]interface{}
}

func (v *ResponseObject) Extract(extractors map[string]string) map[string]interface{} {
if extractors == nil {
return nil
}

extractMapping := make(map[string]interface{})
for key, value := range extractors {
extractMapping[key] = v.searchJmespath(value)
}

log.Printf("[Extract] extractMapping: %v", extractMapping)
return extractMapping
}

func (v *ResponseObject) Validate(validators []TValidator, variablesMapping map[string]interface{}) error {
for _, validator := range validators {
// parse check value
Expand Down
58 changes: 44 additions & 14 deletions runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,39 +49,56 @@ func (r *Runner) runCase(testcase *TestCase) error {
config := &testcase.Config
log.Printf("Start to run testcase: %v", config.Name)

extractedVariables := make(map[string]interface{})

for _, step := range testcase.TestSteps {
// override variables
// step variables > extracted variables from previous steps
step.ToStruct().Variables = mergeVariables(step.ToStruct().Variables, extractedVariables)
// step variables > testcase config variables
step.ToStruct().Variables = mergeVariables(step.ToStruct().Variables, config.Variables)

r.runStep(step, config)
stepData, err := r.runStep(step, config)
if err != nil {
return err
}
// update extracted variables
for k, v := range stepData.ExportVars {
extractedVariables[k] = v
}
}

return nil
}

func (r *Runner) runStep(step IStep, config *TConfig) error {
func (r *Runner) runStep(step IStep, config *TConfig) (stepData *StepData, err error) {
log.Printf("run step begin: %v >>>>>>", step.Name())
if tc, ok := step.(*testcaseWithOptionalArgs); ok {
// run referenced testcase
log.Printf("run referenced testcase: %v", tc.step.Name)
// TODO: override testcase config
if err := r.runStepTestCase(tc.step); err != nil {
return err
stepData, err = r.runStepTestCase(tc.step)
if err != nil {
return
}
} else {
// run request
tStep := parseStep(step, config)
if err := r.runStepRequest(tStep); err != nil {
return err
stepData, err = r.runStepRequest(tStep)
if err != nil {
return
}
}
log.Printf("run step end: %v <<<<<<\n", step.Name())
return nil
return
}

func (r *Runner) runStepRequest(step *TStep) error {
func (r *Runner) runStepRequest(step *TStep) (stepData *StepData, err error) {
stepData = &StepData{
Name: step.Name,
Success: false,
}

// prepare request args
var v []interface{}
if len(step.Request.Headers) > 0 {
Expand Down Expand Up @@ -111,23 +128,36 @@ func (r *Runner) runStepRequest(step *TStep) error {
req.Debug = r.debug
resp, err := r.Client.Do(string(step.Request.Method), step.Request.URL, v...)
if err != nil {
return err
return
}
defer resp.Response().Body.Close()

// validate response
// new response object
respObj := NewResponseObject(r.t, resp)

// extract variables from response
extractors := step.Extract
extractMapping := respObj.Extract(extractors)
stepData.ExportVars = extractMapping

// validate response
err = respObj.Validate(step.Validators, step.Variables)
if err != nil {
return err
return
}

return nil
stepData.Success = true
return
}

func (r *Runner) runStepTestCase(step *TStep) error {
func (r *Runner) runStepTestCase(step *TStep) (stepData *StepData, err error) {
stepData = &StepData{
Name: step.Name,
Success: false,
}
testcase := step.TestCase
return r.runCase(testcase)
err = r.runCase(testcase)
return
}

func (r *Runner) GetSummary() *TestCaseSummary {
Expand Down
4 changes: 2 additions & 2 deletions step_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ func TestRunRequestRun(t *testing.T) {
BaseURL: "https://postman-echo.com",
}
runner := NewRunner().SetDebug(true).WithTestingT(t)
if err := runner.runStep(stepGET, config); err != nil {
if _, err := runner.runStep(stepGET, config); err != nil {
t.Fatalf("tStep.Run() error: %s", err)
}
if err := runner.runStep(stepPOSTData, config); err != nil {
if _, err := runner.runStep(stepPOSTData, config); err != nil {
t.Fatalf("tStepPOSTData.Run() error: %s", err)
}
}

0 comments on commit 2a793cf

Please sign in to comment.