From bbe33e0dd091262f0546c6f95d397f85354ce13c Mon Sep 17 00:00:00 2001 From: debugtalk Date: Sat, 9 Oct 2021 16:39:25 +0800 Subject: [PATCH] feat: dump2YAML --- convert.go | 31 ++++++++++++++++ convert_test.go | 94 +++++++++++++++++++++++++++---------------------- go.mod | 1 + models.go | 64 ++++++++++++++++----------------- 4 files changed, 115 insertions(+), 75 deletions(-) diff --git a/convert.go b/convert.go index 94c06577..654e3976 100644 --- a/convert.go +++ b/convert.go @@ -1,10 +1,13 @@ package httpboomer import ( + "bytes" "encoding/json" "io/ioutil" "log" "path/filepath" + + "gopkg.in/yaml.v3" ) func (tc *TestCase) toStruct() *TCase { @@ -33,3 +36,31 @@ func (tc *TestCase) dump2JSON(path string) error { } return nil } + +func (tc *TestCase) dump2YAML(path string) error { + path, err := filepath.Abs(path) + if err != nil { + log.Printf("convert absolute path error: %v, path: %v", err, path) + return err + } + log.Printf("dump testcase to yaml path: %s", path) + + // init yaml encoder + buffer := new(bytes.Buffer) + encoder := yaml.NewEncoder(buffer) + encoder.SetIndent(4) + + // encode + tcStruct := tc.toStruct() + err = encoder.Encode(tcStruct) + if err != nil { + return err + } + + err = ioutil.WriteFile(path, buffer.Bytes(), 0644) + if err != nil { + log.Printf("dump yaml path error: %v", err) + return err + } + return nil +} diff --git a/convert_test.go b/convert_test.go index c21a3384..c3f8e45b 100644 --- a/convert_test.go +++ b/convert_test.go @@ -6,50 +6,58 @@ import ( "github.com/stretchr/testify/assert" ) +var demoTestCase = &TestCase{ + Config: TConfig{ + Name: "demo with complex mechanisms", + BaseURL: "https://postman-echo.com", + Variables: map[string]interface{}{ // global level variables + "n": 5, + "a": 12.3, + "b": 3.45, + "varFoo1": "${gen_random_string($n)}", + "varFoo2": "${max($a, $b)}", // 12.3; eval with built-in function + }, + }, + TestSteps: []IStep{ + Step("get with params"). + WithVariables(map[string]interface{}{ // step level variables + "n": 3, // inherit config level variables if not set in step level, a/varFoo1 + "b": 34.5, // override config level variable if existed, n/b/varFoo2 + "varFoo2": "${max($a, $b)}", // 34.5; override variable b and eval again + }). + GET("/get"). + WithParams(map[string]interface{}{"foo1": "$varFoo1", "foo2": "$varFoo2"}). // request with params + WithHeaders(map[string]string{"User-Agent": "HttpBoomer"}). // request with headers + Extract(). + WithJmesPath("body.args.foo1", "varFoo1"). // extract variable with jmespath + Validate(). + AssertEqual("status_code", 200, "check response status code"). // validate response status code + AssertStartsWith("headers.\"Content-Type\"", "application/json", ""). // validate response header + AssertLengthEqual("body.args.foo1", 5, "check args foo1"). // validate response body with jmespath + AssertLengthEqual("$varFoo1", 5, "check args foo1"). // assert with extracted variable from current step + AssertEqual("body.args.foo2", "34.5", "check args foo2"), // notice: request params value will be converted to string + Step("post json data"). + POST("/post"). + WithJSON(map[string]interface{}{ + "foo1": "$varFoo1", // reference former extracted variable + "foo2": "${max($a, $b)}", // 12.3; step level variables are independent, variable b is 3.45 here + }). + Validate(). + AssertEqual("status_code", 200, "check status code"). + AssertLengthEqual("body.json.foo1", 5, "check args foo1"). + AssertEqual("body.json.foo2", 12.3, "check args foo2"), + }, +} + func TestDump2JSON(t *testing.T) { - testcase := &TestCase{ - Config: TConfig{ - Name: "demo with complex mechanisms", - BaseURL: "https://postman-echo.com", - Variables: map[string]interface{}{ // global level variables - "n": 5, - "a": 12.3, - "b": 3.45, - "varFoo1": "${gen_random_string($n)}", - "varFoo2": "${max($a, $b)}", // 12.3; eval with built-in function - }, - }, - TestSteps: []IStep{ - Step("get with params"). - WithVariables(map[string]interface{}{ // step level variables - "n": 3, // inherit config level variables if not set in step level, a/varFoo1 - "b": 34.5, // override config level variable if existed, n/b/varFoo2 - "varFoo2": "${max($a, $b)}", // 34.5; override variable b and eval again - }). - GET("/get"). - WithParams(map[string]interface{}{"foo1": "$varFoo1", "foo2": "$varFoo2"}). // request with params - WithHeaders(map[string]string{"User-Agent": "HttpBoomer"}). // request with headers - Extract(). - WithJmesPath("body.args.foo1", "varFoo1"). // extract variable with jmespath - Validate(). - AssertEqual("status_code", 200, "check response status code"). // validate response status code - AssertStartsWith("headers.\"Content-Type\"", "application/json", ""). // validate response header - AssertLengthEqual("body.args.foo1", 5, "check args foo1"). // validate response body with jmespath - AssertLengthEqual("$varFoo1", 5, "check args foo1"). // assert with extracted variable from current step - AssertEqual("body.args.foo2", "34.5", "check args foo2"), // notice: request params value will be converted to string - Step("post json data"). - POST("/post"). - WithJSON(map[string]interface{}{ - "foo1": "$varFoo1", // reference former extracted variable - "foo2": "${max($a, $b)}", // 12.3; step level variables are independent, variable b is 3.45 here - }). - Validate(). - AssertEqual("status_code", 200, "check status code"). - AssertLengthEqual("body.json.foo1", 5, "check args foo1"). - AssertEqual("body.json.foo2", 12.3, "check args foo2"), - }, - } - err := testcase.dump2JSON("test.json") + err := demoTestCase.dump2JSON("demo.json") + if !assert.NoError(t, err) { + t.Fail() + } +} + +func TestDump2YAML(t *testing.T) { + err := demoTestCase.dump2YAML("demo.yml") if !assert.NoError(t, err) { t.Fail() } diff --git a/go.mod b/go.mod index bb99ed69..c7cfc1b5 100644 --- a/go.mod +++ b/go.mod @@ -20,4 +20,5 @@ require ( github.com/zeromq/gomq v0.0.0-20201031135124-cef4e507bb8e // indirect github.com/zeromq/gomq/zmtp v0.0.0-20201031135124-cef4e507bb8e // indirect golang.org/x/sys v0.0.0-20210917161153-d61c044b1678 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b ) diff --git a/models.go b/models.go index c3716b5b..8b0e8e75 100644 --- a/models.go +++ b/models.go @@ -13,51 +13,51 @@ const ( ) type TConfig struct { - Name string `json:"name"` - Verify bool `json:"verify,omitempty"` - BaseURL string `json:"base_url,omitempty"` - Variables map[string]interface{} `json:"variables,omitempty"` - Parameters map[string]interface{} `json:"parameters,omitempty"` - Export []string `json:"export,omitempty"` - Weight int `json:"weight,omitempty"` + Name string `json:"name" yaml:"name"` + Verify bool `json:"verify,omitempty" yaml:"verify,omitempty"` + BaseURL string `json:"base_url,omitempty" yaml:"base_url,omitempty"` + Variables map[string]interface{} `json:"variables,omitempty" yaml:"variables,omitempty"` + Parameters map[string]interface{} `json:"parameters,omitempty" yaml:"parameters,omitempty"` + Export []string `json:"export,omitempty" yaml:"export,omitempty"` + Weight int `json:"weight,omitempty" yaml:"weight,omitempty"` } type TRequest struct { - Method enumHTTPMethod `json:"method"` - URL string `json:"url"` - Params map[string]interface{} `json:"params,omitempty"` - Headers map[string]string `json:"headers,omitempty"` - Cookies map[string]string `json:"cookies,omitempty"` - Data interface{} `json:"data,omitempty"` - JSON interface{} `json:"json,omitempty"` - Timeout float32 `json:"timeout,omitempty"` - AllowRedirects bool `json:"allow_redirects,omitempty"` - Verify bool `json:"verify,omitempty"` + Method enumHTTPMethod `json:"method" yaml:"method"` + URL string `json:"url" yaml:"url"` + Params map[string]interface{} `json:"params,omitempty" yaml:"params,omitempty"` + Headers map[string]string `json:"headers,omitempty" yaml:"headers,omitempty"` + Cookies map[string]string `json:"cookies,omitempty" yaml:"cookies,omitempty"` + Data interface{} `json:"data,omitempty" yaml:"data,omitempty"` + JSON interface{} `json:"json,omitempty" yaml:"json,omitempty"` + Timeout float32 `json:"timeout,omitempty" yaml:"timeout,omitempty"` + AllowRedirects bool `json:"allow_redirects,omitempty" yaml:"allow_redirects,omitempty"` + Verify bool `json:"verify,omitempty" yaml:"verify,omitempty"` } type TValidator struct { - Check string `json:"check,omitempty"` // get value with jmespath - Assert string `json:"assert,omitempty"` - Expect interface{} `json:"expect,omitempty"` - Message string `json:"msg,omitempty"` + Check string `json:"check,omitempty" yaml:"check,omitempty"` // get value with jmespath + Assert string `json:"assert,omitempty" yaml:"assert,omitempty"` + Expect interface{} `json:"expect,omitempty" yaml:"expect,omitempty"` + Message string `json:"msg,omitempty" yaml:"msg,omitempty"` } type TStep struct { - Name string `json:"name"` - Request *TRequest `json:"request,omitempty"` - TestCase *TestCase `json:"testcase,omitempty"` - Variables map[string]interface{} `json:"variables,omitempty"` - SetupHooks []string `json:"setup_hooks,omitempty"` - TeardownHooks []string `json:"teardown_hooks,omitempty"` - Extract map[string]string `json:"extract,omitempty"` - Validators []TValidator `json:"validate,omitempty"` - Export []string `json:"export,omitempty"` + Name string `json:"name" yaml:"name"` + Request *TRequest `json:"request,omitempty" yaml:"request,omitempty"` + TestCase *TestCase `json:"testcase,omitempty" yaml:"testcase,omitempty"` + Variables map[string]interface{} `json:"variables,omitempty" yaml:"variables,omitempty"` + SetupHooks []string `json:"setup_hooks,omitempty" yaml:"setup_hooks,omitempty"` + TeardownHooks []string `json:"teardown_hooks,omitempty" yaml:"teardown_hooks,omitempty"` + Extract map[string]string `json:"extract,omitempty" yaml:"extract,omitempty"` + Validators []TValidator `json:"validate,omitempty" yaml:"validate,omitempty"` + Export []string `json:"export,omitempty" yaml:"export,omitempty"` } // used for testcase json loading and dumping type TCase struct { - Config TConfig `json:"config"` - TestSteps []*TStep `json:"teststeps"` + Config TConfig `json:"config" yaml:"config"` + TestSteps []*TStep `json:"teststeps" yaml:"teststeps"` } // interface for all types of steps