refactor: runStep

This commit is contained in:
debugtalk
2021-09-22 21:25:28 +08:00
parent 9fb19da2ac
commit 102b8a94a3
7 changed files with 50 additions and 56 deletions

View File

@@ -29,6 +29,7 @@ func (b *Boomer) Run(testcases ...*TestCase) {
} }
func convertBoomerTask(testcase *TestCase) *boomer.Task { func convertBoomerTask(testcase *TestCase) *boomer.Task {
runner := NewRunner()
return &boomer.Task{ return &boomer.Task{
Name: testcase.Config.Name, Name: testcase.Config.Name,
Weight: testcase.Config.Weight, Weight: testcase.Config.Weight,
@@ -36,7 +37,8 @@ func convertBoomerTask(testcase *TestCase) *boomer.Task {
config := &testcase.Config config := &testcase.Config
for _, step := range testcase.TestSteps { for _, step := range testcase.TestSteps {
start := time.Now() start := time.Now()
err := step.Run(config) tStep := parseStep(step, config)
err := runner.runStep(tStep)
elapsed := time.Since(start).Nanoseconds() / int64(time.Millisecond) elapsed := time.Since(start).Nanoseconds() / int64(time.Millisecond)
if err == nil { if err == nil {

View File

@@ -4,8 +4,7 @@ import "fmt"
// implements IStep interface // implements IStep interface
type stepRequestExtraction struct { type stepRequestExtraction struct {
runner *Runner step *TStep
step *TStep
} }
func (s *stepRequestExtraction) WithJmesPath(jmesPath string, varName string) *stepRequestExtraction { func (s *stepRequestExtraction) WithJmesPath(jmesPath string, varName string) *stepRequestExtraction {
@@ -27,6 +26,6 @@ func (s *stepRequestExtraction) Type() string {
return fmt.Sprintf("request-%v", s.step.Request.Method) return fmt.Sprintf("request-%v", s.step.Request.Method)
} }
func (s *stepRequestExtraction) Run(config *TConfig) error { func (s *stepRequestExtraction) ToStruct() *TStep {
return s.runner.runStep(s.step) return s.step
} }

View File

@@ -58,7 +58,7 @@ type TStep struct {
type IStep interface { type IStep interface {
Name() string Name() string
Type() string Type() string
Run(config *TConfig) error ToStruct() *TStep
} }
type TestCase struct { type TestCase struct {

View File

@@ -1,6 +1,7 @@
package httpboomer package httpboomer
import ( import (
"log"
"net/http" "net/http"
"github.com/imroc/req" "github.com/imroc/req"
@@ -33,15 +34,24 @@ func (r *Runner) Run(testcases ...*TestCase) error {
func (r *Runner) runCase(testcase *TestCase) error { func (r *Runner) runCase(testcase *TestCase) error {
config := &testcase.Config config := &testcase.Config
log.Printf("Start to run testcase: %v", config.Name)
for _, step := range testcase.TestSteps { for _, step := range testcase.TestSteps {
if err := step.Run(config); err != nil { tStep := parseStep(step, config)
if err := r.runStep(tStep); err != nil {
return err return err
} }
} }
return nil return nil
} }
func parseStep(step IStep, config *TConfig) *TStep {
tStep := step.ToStruct()
tStep.Request.URL = config.BaseURL + tStep.Request.URL
return tStep
}
func (r *Runner) runStep(step *TStep) error { func (r *Runner) runStep(step *TStep) error {
log.Printf("run step begin: %v >>>>>>", step.Name)
var v []interface{} var v []interface{}
v = append(v, req.Header(step.Request.Headers)) v = append(v, req.Header(step.Request.Headers))
v = append(v, req.Param(step.Request.Params)) v = append(v, req.Param(step.Request.Params))
@@ -53,11 +63,13 @@ func (r *Runner) runStep(step *TStep) error {
}) })
} }
req.Debug = true
resp, err := r.Client.Do(string(step.Request.Method), step.Request.URL, v...) resp, err := r.Client.Do(string(step.Request.Method), step.Request.URL, v...)
if err != nil { if err != nil {
return err return err
} }
resp.Response().Body.Close() resp.Response().Body.Close()
log.Printf("run step end: %v <<<<<<\n", step.Name)
return nil return nil
} }

52
step.go
View File

@@ -4,7 +4,6 @@ import "fmt"
func Step(name string) *step { func Step(name string) *step {
return &step{ return &step{
runner: defaultRunner,
TStep: &TStep{ TStep: &TStep{
Name: name, Name: name,
Request: &TRequest{}, Request: &TRequest{},
@@ -14,16 +13,9 @@ func Step(name string) *step {
} }
type step struct { type step struct {
runner *Runner
config *TConfig
*TStep *TStep
} }
func (s *step) WithRunner(runner *Runner) *step {
s.runner = runner
return s
}
func (s *step) WithVariables(variables map[string]interface{}) *step { func (s *step) WithVariables(variables map[string]interface{}) *step {
s.TStep.Variables = variables s.TStep.Variables = variables
return s return s
@@ -38,8 +30,7 @@ func (s *step) GET(url string) *requestWithOptionalArgs {
s.TStep.Request.Method = GET s.TStep.Request.Method = GET
s.TStep.Request.URL = url s.TStep.Request.URL = url
return &requestWithOptionalArgs{ return &requestWithOptionalArgs{
runner: s.runner, step: s.TStep,
step: s.TStep,
} }
} }
@@ -47,8 +38,7 @@ func (s *step) HEAD(url string) *requestWithOptionalArgs {
s.TStep.Request.Method = HEAD s.TStep.Request.Method = HEAD
s.TStep.Request.URL = url s.TStep.Request.URL = url
return &requestWithOptionalArgs{ return &requestWithOptionalArgs{
runner: s.runner, step: s.TStep,
step: s.TStep,
} }
} }
@@ -56,8 +46,7 @@ func (s *step) POST(url string) *requestWithOptionalArgs {
s.TStep.Request.Method = POST s.TStep.Request.Method = POST
s.TStep.Request.URL = url s.TStep.Request.URL = url
return &requestWithOptionalArgs{ return &requestWithOptionalArgs{
runner: s.runner, step: s.TStep,
step: s.TStep,
} }
} }
@@ -65,8 +54,7 @@ func (s *step) PUT(url string) *requestWithOptionalArgs {
s.TStep.Request.Method = PUT s.TStep.Request.Method = PUT
s.TStep.Request.URL = url s.TStep.Request.URL = url
return &requestWithOptionalArgs{ return &requestWithOptionalArgs{
runner: s.runner, step: s.TStep,
step: s.TStep,
} }
} }
@@ -74,8 +62,7 @@ func (s *step) DELETE(url string) *requestWithOptionalArgs {
s.TStep.Request.Method = DELETE s.TStep.Request.Method = DELETE
s.TStep.Request.URL = url s.TStep.Request.URL = url
return &requestWithOptionalArgs{ return &requestWithOptionalArgs{
runner: s.runner, step: s.TStep,
step: s.TStep,
} }
} }
@@ -83,8 +70,7 @@ func (s *step) OPTIONS(url string) *requestWithOptionalArgs {
s.TStep.Request.Method = OPTIONS s.TStep.Request.Method = OPTIONS
s.TStep.Request.URL = url s.TStep.Request.URL = url
return &requestWithOptionalArgs{ return &requestWithOptionalArgs{
runner: s.runner, step: s.TStep,
step: s.TStep,
} }
} }
@@ -92,8 +78,7 @@ func (s *step) PATCH(url string) *requestWithOptionalArgs {
s.TStep.Request.Method = PATCH s.TStep.Request.Method = PATCH
s.TStep.Request.URL = url s.TStep.Request.URL = url
return &requestWithOptionalArgs{ return &requestWithOptionalArgs{
runner: s.runner, step: s.TStep,
step: s.TStep,
} }
} }
@@ -101,15 +86,13 @@ func (s *step) PATCH(url string) *requestWithOptionalArgs {
func (s *step) CallRefCase(tc *TestCase) *testcaseWithOptionalArgs { func (s *step) CallRefCase(tc *TestCase) *testcaseWithOptionalArgs {
s.TStep.TestCase = tc s.TStep.TestCase = tc
return &testcaseWithOptionalArgs{ return &testcaseWithOptionalArgs{
runner: s.runner, step: s.TStep,
step: s.TStep,
} }
} }
// implements IStep interface // implements IStep interface
type requestWithOptionalArgs struct { type requestWithOptionalArgs struct {
runner *Runner step *TStep
step *TStep
} }
func (s *requestWithOptionalArgs) SetVerify(verify bool) *requestWithOptionalArgs { func (s *requestWithOptionalArgs) SetVerify(verify bool) *requestWithOptionalArgs {
@@ -169,15 +152,13 @@ func (s *requestWithOptionalArgs) TeardownHook(hook string) *requestWithOptional
func (s *requestWithOptionalArgs) Validate() *stepRequestValidation { func (s *requestWithOptionalArgs) Validate() *stepRequestValidation {
return &stepRequestValidation{ return &stepRequestValidation{
runner: s.runner, step: s.step,
step: s.step,
} }
} }
func (s *requestWithOptionalArgs) Extract() *stepRequestExtraction { func (s *requestWithOptionalArgs) Extract() *stepRequestExtraction {
return &stepRequestExtraction{ return &stepRequestExtraction{
runner: s.runner, step: s.step,
step: s.step,
} }
} }
@@ -189,14 +170,13 @@ func (s *requestWithOptionalArgs) Type() string {
return fmt.Sprintf("request-%v", s.step.Request.Method) return fmt.Sprintf("request-%v", s.step.Request.Method)
} }
func (s *requestWithOptionalArgs) Run(config *TConfig) error { func (s *requestWithOptionalArgs) ToStruct() *TStep {
return s.runner.runStep(s.step) return s.step
} }
// implements IStep interface // implements IStep interface
type testcaseWithOptionalArgs struct { type testcaseWithOptionalArgs struct {
runner *Runner step *TStep
step *TStep
} }
func (s *testcaseWithOptionalArgs) TeardownHook(hook string) *testcaseWithOptionalArgs { func (s *testcaseWithOptionalArgs) TeardownHook(hook string) *testcaseWithOptionalArgs {
@@ -217,6 +197,6 @@ func (s *testcaseWithOptionalArgs) Type() string {
return "testcase" return "testcase"
} }
func (s *testcaseWithOptionalArgs) Run(config *TConfig) error { func (s *testcaseWithOptionalArgs) ToStruct() *TStep {
return s.runner.runCase(s.step.TestCase) return s.step
} }

View File

@@ -6,14 +6,14 @@ import (
var ( var (
stepGET = Step("get with params"). stepGET = Step("get with params").
GET("https://postman-echo.com/get"). GET("/get").
WithParams(map[string]interface{}{"foo1": "bar1", "foo2": "bar2"}). WithParams(map[string]interface{}{"foo1": "bar1", "foo2": "bar2"}).
WithHeaders(map[string]string{"User-Agent": "HttpBoomer"}). WithHeaders(map[string]string{"User-Agent": "HttpBoomer"}).
WithCookies(map[string]string{"user": "debugtalk"}). WithCookies(map[string]string{"user": "debugtalk"}).
Validate(). Validate().
AssertEqual("status_code", 200, "check status code") AssertEqual("status_code", 200, "check status code")
stepPOSTData = Step("post form data"). stepPOSTData = Step("post form data").
POST("https://postman-echo.com/post"). POST("/post").
WithParams(map[string]interface{}{"foo1": "bar1", "foo2": "bar2"}). WithParams(map[string]interface{}{"foo1": "bar1", "foo2": "bar2"}).
WithHeaders(map[string]string{"User-Agent": "HttpBoomer", "Content-Type": "application/x-www-form-urlencoded"}). WithHeaders(map[string]string{"User-Agent": "HttpBoomer", "Content-Type": "application/x-www-form-urlencoded"}).
WithData("a=1&b=2"). WithData("a=1&b=2").
@@ -27,8 +27,8 @@ func TestRunRequestGetToStruct(t *testing.T) {
if tStep.Request.Method != GET { if tStep.Request.Method != GET {
t.Fatalf("tStep.Request.Method != GET") t.Fatalf("tStep.Request.Method != GET")
} }
if tStep.Request.URL != "https://postman-echo.com/get" { if tStep.Request.URL != "/get" {
t.Fatalf("tStep.Request.URL != 'https://postman-echo.com/get'") t.Fatalf("tStep.Request.URL != '/get'")
} }
if tStep.Request.Params["foo1"] != "bar1" || tStep.Request.Params["foo2"] != "bar2" { if tStep.Request.Params["foo1"] != "bar1" || tStep.Request.Params["foo2"] != "bar2" {
t.Fatalf("tStep.Request.Params mismatch") t.Fatalf("tStep.Request.Params mismatch")
@@ -49,8 +49,8 @@ func TestRunRequestPostDataToStruct(t *testing.T) {
if tStep.Request.Method != POST { if tStep.Request.Method != POST {
t.Fatalf("tStep.Request.Method != POST") t.Fatalf("tStep.Request.Method != POST")
} }
if tStep.Request.URL != "https://postman-echo.com/post" { if tStep.Request.URL != "/post" {
t.Fatalf("tStep.Request.URL != 'https://postman-echo.com/post'") t.Fatalf("tStep.Request.URL != '/post'")
} }
if tStep.Request.Params["foo1"] != "bar1" || tStep.Request.Params["foo2"] != "bar2" { if tStep.Request.Params["foo1"] != "bar1" || tStep.Request.Params["foo2"] != "bar2" {
t.Fatalf("tStep.Request.Params mismatch") t.Fatalf("tStep.Request.Params mismatch")
@@ -70,11 +70,13 @@ func TestRunRequestPostDataToStruct(t *testing.T) {
} }
func TestRunRequestRun(t *testing.T) { func TestRunRequestRun(t *testing.T) {
config := &TConfig{} config := &TConfig{
if err := stepGET.Run(config); err != nil { BaseURL: "https://postman-echo.com",
}
if err := defaultRunner.runStep(parseStep(stepGET, config)); err != nil {
t.Fatalf("tStep.Run() error: %s", err) t.Fatalf("tStep.Run() error: %s", err)
} }
if err := stepPOSTData.Run(config); err != nil { if err := defaultRunner.runStep(parseStep(stepPOSTData, config)); err != nil {
t.Fatalf("tStepPOSTData.Run() error: %s", err) t.Fatalf("tStepPOSTData.Run() error: %s", err)
} }
} }

View File

@@ -4,8 +4,7 @@ import "fmt"
// implements IStep interface // implements IStep interface
type stepRequestValidation struct { type stepRequestValidation struct {
runner *Runner step *TStep
step *TStep
} }
func (s *stepRequestValidation) AssertEqual(jmesPath string, expected interface{}, msg string) *stepRequestValidation { func (s *stepRequestValidation) AssertEqual(jmesPath string, expected interface{}, msg string) *stepRequestValidation {
@@ -27,6 +26,6 @@ func (s *stepRequestValidation) Type() string {
return fmt.Sprintf("request-%v", s.step.Request.Method) return fmt.Sprintf("request-%v", s.step.Request.Method)
} }
func (s *stepRequestValidation) Run(config *TConfig) error { func (s *stepRequestValidation) ToStruct() *TStep {
return s.runner.runStep(s.step) return s.step
} }