mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-12 02:21:29 +08:00
init HttpBommer ✨🍰✨
This commit is contained in:
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"debugtalk"
|
||||
]
|
||||
}
|
||||
2
LICENSE
2
LICENSE
@@ -186,7 +186,7 @@
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
Copyright 2021 debugtalk
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
44
boomer.go
Normal file
44
boomer.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package httpboomer
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/myzhan/boomer"
|
||||
)
|
||||
|
||||
func HttpBoomer() *Boomer {
|
||||
return &Boomer{}
|
||||
}
|
||||
|
||||
type Boomer struct {
|
||||
}
|
||||
|
||||
func (b *Boomer) Run(testcases ...*TestCase) {
|
||||
var taskSlice []*boomer.Task
|
||||
for _, testcase := range testcases {
|
||||
task := convertBoomerTask(testcase)
|
||||
taskSlice = append(taskSlice, task)
|
||||
}
|
||||
boomer.Run(taskSlice...)
|
||||
}
|
||||
|
||||
func convertBoomerTask(testcase *TestCase) *boomer.Task {
|
||||
return &boomer.Task{
|
||||
Name: testcase.Config.Name,
|
||||
Weight: testcase.Config.Weight,
|
||||
Fn: func() {
|
||||
for _, step := range testcase.TestSteps {
|
||||
start := time.Now()
|
||||
err := step.Run()
|
||||
elapsed := time.Since(start).Nanoseconds() / int64(time.Millisecond)
|
||||
|
||||
tStep := step.ToStruct()
|
||||
if err == nil {
|
||||
boomer.RecordSuccess(string(tStep.Request.Method), tStep.Name, elapsed, int64(0))
|
||||
} else {
|
||||
boomer.RecordFailure(string(tStep.Request.Method), tStep.Name, elapsed, err.Error())
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
22
boomer_test.go
Normal file
22
boomer_test.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package httpboomer
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHttpBoomer(t *testing.T) {
|
||||
testcase1 := &TestCase{
|
||||
Config: TConfig{
|
||||
Name: "TestCase1",
|
||||
Weight: 2,
|
||||
},
|
||||
}
|
||||
testcase2 := &TestCase{
|
||||
Config: TConfig{
|
||||
Name: "TestCase2",
|
||||
Weight: 3,
|
||||
},
|
||||
}
|
||||
|
||||
HttpBoomer().Run(testcase1, testcase2)
|
||||
}
|
||||
25
extract.go
Normal file
25
extract.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package httpboomer
|
||||
|
||||
// implements IStep interface
|
||||
type StepRequestExtraction struct {
|
||||
*TStep
|
||||
}
|
||||
|
||||
func (req *StepRequestExtraction) WithJmesPath(jmesPath string, varName string) *StepRequestExtraction {
|
||||
req.TStep.Extract[varName] = jmesPath
|
||||
return req
|
||||
}
|
||||
|
||||
func (req *StepRequestExtraction) Validate() *StepRequestValidation {
|
||||
return &StepRequestValidation{
|
||||
TStep: req.TStep,
|
||||
}
|
||||
}
|
||||
|
||||
func (req *StepRequestExtraction) ToStruct() *TStep {
|
||||
return req.TStep
|
||||
}
|
||||
|
||||
func (req *StepRequestExtraction) Run() error {
|
||||
return req.TStep.Run()
|
||||
}
|
||||
19
go.mod
Normal file
19
go.mod
Normal file
@@ -0,0 +1,19 @@
|
||||
module github.com/httprunner/httpboomer
|
||||
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/StackExchange/wmi v1.2.1 // indirect
|
||||
github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/myzhan/boomer v1.6.0
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/shirou/gopsutil v3.21.8+incompatible // indirect
|
||||
github.com/stretchr/testify v1.7.0 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.9 // indirect
|
||||
github.com/ugorji/go v1.2.6 // indirect
|
||||
github.com/zeromq/goczmq v4.1.0+incompatible // indirect
|
||||
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
|
||||
)
|
||||
44
go.sum
Normal file
44
go.sum
Normal file
@@ -0,0 +1,44 @@
|
||||
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
|
||||
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
|
||||
github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef h1:2JGTg6JapxP9/R33ZaagQtAM4EkkSYnIAlOG5EI8gkM=
|
||||
github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef/go.mod h1:JS7hed4L1fj0hXcyEejnW57/7LCetXggd+vwrRnYeII=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY=
|
||||
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/myzhan/boomer v1.6.0 h1:xjgvmhDjgU9IEKnB7nU1HyoVEfj8SuuU3u6oY3Nugj0=
|
||||
github.com/myzhan/boomer v1.6.0/go.mod h1:Ma68Td5C5EAc1M9XA7yjC/tXg9u5qviNujytnX099ZQ=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/shirou/gopsutil v3.21.8+incompatible h1:sh0foI8tMRlCidUJR+KzqWYWxrkuuPIGiO6Vp+KXdCU=
|
||||
github.com/shirou/gopsutil v3.21.8+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev3vTo=
|
||||
github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs=
|
||||
github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ=
|
||||
github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8=
|
||||
github.com/ugorji/go v1.2.6 h1:tGiWC9HENWE2tqYycIqFTNorMmFRVhNwCpDOpWqnk8E=
|
||||
github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0=
|
||||
github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
|
||||
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
|
||||
github.com/zeromq/goczmq v4.1.0+incompatible h1:cGVQaU6kIwwrGso0Pgbl84tzAz/h7FJ3wYQjSonjFFc=
|
||||
github.com/zeromq/goczmq v4.1.0+incompatible/go.mod h1:1uZybAJoSRCvZMH2rZxEwWBSmC4T7CB/xQOfChwPEzg=
|
||||
github.com/zeromq/gomq v0.0.0-20201031135124-cef4e507bb8e h1:vGjfCnWv/zWeO1ivv4+OUPgTzG/WV1iGfZwVdtUpLkM=
|
||||
github.com/zeromq/gomq v0.0.0-20201031135124-cef4e507bb8e/go.mod h1:SkCxcSQ7BQEA9FvDzbj+3hV6EMhSywyxWnHwUXVIyLY=
|
||||
github.com/zeromq/gomq/zmtp v0.0.0-20201031135124-cef4e507bb8e h1:pjp04/sSr2TYuaPdt+u6Cc1M38Aocp+3er0akr3auFg=
|
||||
github.com/zeromq/gomq/zmtp v0.0.0-20201031135124-cef4e507bb8e/go.mod h1:LBjWEodY/ESvKRwLw3bc7mhn49oiI8qlXUqeqLn0pcU=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210917161153-d61c044b1678 h1:J27LZFQBFoihqXoegpscI10HpjZ7B5WQLLKL2FZXQKw=
|
||||
golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
72
models.go
Normal file
72
models.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package httpboomer
|
||||
|
||||
type Variables map[string]interface{}
|
||||
type Params map[string]interface{}
|
||||
type Headers map[string]string
|
||||
type Cookies map[string]string
|
||||
|
||||
type enumHTTPMethod string
|
||||
|
||||
const (
|
||||
GET enumHTTPMethod = "GET"
|
||||
HEAD enumHTTPMethod = "HEAD"
|
||||
POST enumHTTPMethod = "POST"
|
||||
PUT enumHTTPMethod = "PUT"
|
||||
DELETE enumHTTPMethod = "DELETE"
|
||||
OPTIONS enumHTTPMethod = "OPTIONS"
|
||||
PATCH enumHTTPMethod = "PATCH"
|
||||
)
|
||||
|
||||
type TConfig struct {
|
||||
Name string `json:"name"`
|
||||
Verify bool `json:"verify"`
|
||||
BaseURL string `json:"base_url"`
|
||||
Variables Variables `json:"variables"`
|
||||
Parameters Variables `json:"parameters"`
|
||||
Export []string `json:"export"`
|
||||
Weight int `json:"weight"`
|
||||
}
|
||||
|
||||
type TRequest struct {
|
||||
Method enumHTTPMethod `json:"method"`
|
||||
URL string `json:"url"`
|
||||
Params Params `json:"params"`
|
||||
Headers Headers `json:"headers"`
|
||||
Cookies Cookies `json:"cookies"`
|
||||
Data interface{} `json:"data"`
|
||||
JSON interface{} `json:"json"`
|
||||
Timeout float32 `json:"timeout"`
|
||||
AllowRedirects bool `json:"allow_redirects"`
|
||||
Verify bool `json:"verify"`
|
||||
}
|
||||
|
||||
type TValidator struct {
|
||||
Check string // get value with jmespath
|
||||
Comparator string
|
||||
Expect interface{}
|
||||
Message string
|
||||
}
|
||||
|
||||
type TStep struct {
|
||||
Name string `json:"name"`
|
||||
Request TRequest `json:"request"`
|
||||
Variables Variables `json:"variables"`
|
||||
SetupHooks []string `json:"setup_hooks"`
|
||||
TeardownHooks []string `json:"teardown_hooks"`
|
||||
Extract map[string]string `json:"extract"`
|
||||
Validators []TValidator `json:"validators"`
|
||||
Export []string `json:"export"`
|
||||
}
|
||||
|
||||
// interface for all types of steps
|
||||
type IStep interface {
|
||||
ToStruct() *TStep
|
||||
Run() error
|
||||
}
|
||||
|
||||
type TestCase struct {
|
||||
Config TConfig `json:"config"`
|
||||
TestSteps []IStep `json:"teststeps"`
|
||||
}
|
||||
|
||||
type TestCaseSummary struct{}
|
||||
148
request.go
Normal file
148
request.go
Normal file
@@ -0,0 +1,148 @@
|
||||
package httpboomer
|
||||
|
||||
func RunRequest(name string) *Request {
|
||||
return &Request{
|
||||
TStep: &TStep{
|
||||
Name: name,
|
||||
Variables: make(Variables),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type Request struct {
|
||||
*TStep
|
||||
}
|
||||
|
||||
func (req *Request) WithVariables(variables Variables) *Request {
|
||||
req.TStep.Variables = variables
|
||||
return req
|
||||
}
|
||||
|
||||
func (req *Request) GET(url string) *RequestWithOptionalArgs {
|
||||
req.TStep.Request.Method = GET
|
||||
req.TStep.Request.URL = url
|
||||
return &RequestWithOptionalArgs{
|
||||
TStep: req.TStep,
|
||||
}
|
||||
}
|
||||
|
||||
func (req *Request) HEAD(url string) *RequestWithOptionalArgs {
|
||||
req.TStep.Request.Method = HEAD
|
||||
req.TStep.Request.URL = url
|
||||
return &RequestWithOptionalArgs{
|
||||
TStep: req.TStep,
|
||||
}
|
||||
}
|
||||
|
||||
func (req *Request) POST(url string) *RequestWithOptionalArgs {
|
||||
req.TStep.Request.Method = POST
|
||||
req.TStep.Request.URL = url
|
||||
return &RequestWithOptionalArgs{
|
||||
TStep: req.TStep,
|
||||
}
|
||||
}
|
||||
|
||||
func (req *Request) PUT(url string) *RequestWithOptionalArgs {
|
||||
req.TStep.Request.Method = PUT
|
||||
req.TStep.Request.URL = url
|
||||
return &RequestWithOptionalArgs{
|
||||
TStep: req.TStep,
|
||||
}
|
||||
}
|
||||
|
||||
func (req *Request) DELETE(url string) *RequestWithOptionalArgs {
|
||||
req.TStep.Request.Method = DELETE
|
||||
req.TStep.Request.URL = url
|
||||
return &RequestWithOptionalArgs{
|
||||
TStep: req.TStep,
|
||||
}
|
||||
}
|
||||
|
||||
func (req *Request) OPTIONS(url string) *RequestWithOptionalArgs {
|
||||
req.TStep.Request.Method = OPTIONS
|
||||
req.TStep.Request.URL = url
|
||||
return &RequestWithOptionalArgs{
|
||||
TStep: req.TStep,
|
||||
}
|
||||
}
|
||||
|
||||
func (req *Request) PATCH(url string) *RequestWithOptionalArgs {
|
||||
req.TStep.Request.Method = PATCH
|
||||
req.TStep.Request.URL = url
|
||||
return &RequestWithOptionalArgs{
|
||||
TStep: req.TStep,
|
||||
}
|
||||
}
|
||||
|
||||
func (req *Request) Run() error {
|
||||
return req.TStep.Run()
|
||||
}
|
||||
|
||||
// implements IStep interface
|
||||
type RequestWithOptionalArgs struct {
|
||||
*TStep
|
||||
}
|
||||
|
||||
func (req *RequestWithOptionalArgs) SetVerify(verify bool) *RequestWithOptionalArgs {
|
||||
req.TStep.Request.Verify = verify
|
||||
return req
|
||||
}
|
||||
|
||||
func (req *RequestWithOptionalArgs) SetTimeout(timeout float32) *RequestWithOptionalArgs {
|
||||
req.TStep.Request.Timeout = timeout
|
||||
return req
|
||||
}
|
||||
|
||||
func (req *RequestWithOptionalArgs) SetProxies(proxies map[string]string) *RequestWithOptionalArgs {
|
||||
// TODO
|
||||
return req
|
||||
}
|
||||
|
||||
func (req *RequestWithOptionalArgs) SetAllowRedirects(allowRedirects bool) *RequestWithOptionalArgs {
|
||||
req.TStep.Request.AllowRedirects = allowRedirects
|
||||
return req
|
||||
}
|
||||
|
||||
func (req *RequestWithOptionalArgs) SetAuth(auth map[string]string) *RequestWithOptionalArgs {
|
||||
// TODO
|
||||
return req
|
||||
}
|
||||
|
||||
func (req *RequestWithOptionalArgs) WithParams(params Params) *RequestWithOptionalArgs {
|
||||
req.TStep.Request.Params = params
|
||||
return req
|
||||
}
|
||||
|
||||
func (req *RequestWithOptionalArgs) WithHeaders(headers Headers) *RequestWithOptionalArgs {
|
||||
req.TStep.Request.Headers = headers
|
||||
return req
|
||||
}
|
||||
|
||||
func (req *RequestWithOptionalArgs) WithCookies(cookies Cookies) *RequestWithOptionalArgs {
|
||||
req.TStep.Request.Cookies = cookies
|
||||
return req
|
||||
}
|
||||
|
||||
func (req *RequestWithOptionalArgs) WithData(data interface{}) *RequestWithOptionalArgs {
|
||||
req.TStep.Request.Data = data
|
||||
return req
|
||||
}
|
||||
|
||||
func (req *RequestWithOptionalArgs) WithJSON(json interface{}) *RequestWithOptionalArgs {
|
||||
req.TStep.Request.JSON = json
|
||||
return req
|
||||
}
|
||||
|
||||
func (req *RequestWithOptionalArgs) Validate() *StepRequestValidation {
|
||||
return &StepRequestValidation{
|
||||
TStep: req.TStep,
|
||||
}
|
||||
}
|
||||
|
||||
func (req *RequestWithOptionalArgs) ToStruct() *TStep {
|
||||
return req.TStep
|
||||
}
|
||||
|
||||
func (req *RequestWithOptionalArgs) Run() error {
|
||||
return req.TStep.Run()
|
||||
}
|
||||
79
request_test.go
Normal file
79
request_test.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package httpboomer
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
var (
|
||||
tStepGET = RunRequest("get with params").
|
||||
GET("/get").
|
||||
WithParams(Params{"foo1": "bar1", "foo2": "bar2"}).
|
||||
WithHeaders(Headers{"User-Agent": "HttpBoomer"}).
|
||||
WithCookies(Cookies{"user": "debugtalk"}).
|
||||
Validate().
|
||||
AssertEqual("status_code", 200, "check status code")
|
||||
tStepPOSTData = RunRequest("post form data").
|
||||
POST("/post").
|
||||
WithParams(Params{"foo1": "bar1", "foo2": "bar2"}).
|
||||
WithHeaders(Headers{"User-Agent": "HttpBoomer", "Content-Type": "application/x-www-form-urlencoded"}).
|
||||
WithData("a=1&b=2").
|
||||
WithCookies(Cookies{"user": "debugtalk"}).
|
||||
Validate().
|
||||
AssertEqual("status_code", 200, "check status code")
|
||||
)
|
||||
|
||||
func TestRunRequestGetToStruct(t *testing.T) {
|
||||
tStep := tStepGET.ToStruct()
|
||||
if tStep.Request.Method != GET {
|
||||
t.Fatalf("tStep.Request.Method != GET")
|
||||
}
|
||||
if tStep.Request.URL != "/get" {
|
||||
t.Fatalf("tStep.Request.URL != '/get'")
|
||||
}
|
||||
if tStep.Request.Params["foo1"] != "bar1" || tStep.Request.Params["foo2"] != "bar2" {
|
||||
t.Fatalf("tStep.Request.Params mismatch")
|
||||
}
|
||||
if tStep.Request.Headers["User-Agent"] != "HttpBoomer" {
|
||||
t.Fatalf("tStep.Request.Headers mismatch")
|
||||
}
|
||||
if tStep.Request.Cookies["user"] != "debugtalk" {
|
||||
t.Fatalf("tStep.Request.Cookies mismatch")
|
||||
}
|
||||
if tStep.Validators[0].Check != "status_code" || tStep.Validators[0].Expect != 200 {
|
||||
t.Fatalf("tStep.Validators mismatch")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunRequestPostDataToStruct(t *testing.T) {
|
||||
tStep := tStepPOSTData.ToStruct()
|
||||
if tStep.Request.Method != POST {
|
||||
t.Fatalf("tStep.Request.Method != POST")
|
||||
}
|
||||
if tStep.Request.URL != "/post" {
|
||||
t.Fatalf("tStep.Request.URL != '/post'")
|
||||
}
|
||||
if tStep.Request.Params["foo1"] != "bar1" || tStep.Request.Params["foo2"] != "bar2" {
|
||||
t.Fatalf("tStep.Request.Params mismatch")
|
||||
}
|
||||
if tStep.Request.Headers["User-Agent"] != "HttpBoomer" {
|
||||
t.Fatalf("tStep.Request.Headers mismatch")
|
||||
}
|
||||
if tStep.Request.Cookies["user"] != "debugtalk" {
|
||||
t.Fatalf("tStep.Request.Cookies mismatch")
|
||||
}
|
||||
if tStep.Request.Data != "a=1&b=2" {
|
||||
t.Fatalf("tStep.Request.Data mismatch")
|
||||
}
|
||||
if tStep.Validators[0].Check != "status_code" || tStep.Validators[0].Expect != 200 {
|
||||
t.Fatalf("tStep.Validators mismatch")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunRequestRun(t *testing.T) {
|
||||
if err := tStepGET.Run(); err != nil {
|
||||
t.Fatalf("tStep.Run() error: %s", err)
|
||||
}
|
||||
if err := tStepPOSTData.Run(); err != nil {
|
||||
t.Fatalf("tStepPOSTData.Run() error: %s", err)
|
||||
}
|
||||
}
|
||||
1
response.go
Normal file
1
response.go
Normal file
@@ -0,0 +1 @@
|
||||
package httpboomer
|
||||
34
runner.go
Normal file
34
runner.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package httpboomer
|
||||
|
||||
func HttpRunner() *Runner {
|
||||
return &Runner{}
|
||||
}
|
||||
|
||||
type Runner struct {
|
||||
}
|
||||
|
||||
func (r *Runner) Run(testcases ...*TestCase) error {
|
||||
for _, testcase := range testcases {
|
||||
if err := r.runCase(testcase); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Runner) runCase(testcase *TestCase) error {
|
||||
for _, step := range testcase.TestSteps {
|
||||
if err := r.runStep(step); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Runner) runStep(req IStep) error {
|
||||
return req.Run()
|
||||
}
|
||||
|
||||
func (r *Runner) GetSummary() *TestCaseSummary {
|
||||
return &TestCaseSummary{}
|
||||
}
|
||||
37
runner_test.go
Normal file
37
runner_test.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package httpboomer
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHttpRunner(t *testing.T) {
|
||||
testcase1 := &TestCase{
|
||||
Config: TConfig{
|
||||
Name: "TestCase1",
|
||||
BaseURL: "http://httpbin.org",
|
||||
},
|
||||
TestSteps: []IStep{
|
||||
RunRequest("headers").
|
||||
GET("/headers").
|
||||
Validate().
|
||||
AssertEqual("status_code", 200, "check status code").
|
||||
AssertEqual("headers.Host", "httpbin.org", "check http response host"),
|
||||
RunRequest("user-agent").
|
||||
GET("/user-agent").
|
||||
Validate().
|
||||
AssertEqual("status_code", 200, "check status code").
|
||||
AssertEqual("body.\"user-agent\"", "python-requests", "check User-Agent"),
|
||||
},
|
||||
}
|
||||
testcase2 := &TestCase{
|
||||
Config: TConfig{
|
||||
Name: "TestCase2",
|
||||
Weight: 3,
|
||||
},
|
||||
}
|
||||
|
||||
err := HttpRunner().Run(testcase1, testcase2)
|
||||
if err != nil {
|
||||
t.Fatalf("run testcase error: %v", err)
|
||||
}
|
||||
}
|
||||
5
step.go
Normal file
5
step.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package httpboomer
|
||||
|
||||
func (step *TStep) Run() error {
|
||||
return nil
|
||||
}
|
||||
25
validate.go
Normal file
25
validate.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package httpboomer
|
||||
|
||||
// implements IStep interface
|
||||
type StepRequestValidation struct {
|
||||
*TStep
|
||||
}
|
||||
|
||||
func (req *StepRequestValidation) AssertEqual(jmesPath string, expected interface{}, msg string) *StepRequestValidation {
|
||||
validator := TValidator{
|
||||
Check: jmesPath,
|
||||
Comparator: "equals",
|
||||
Expect: expected,
|
||||
Message: msg,
|
||||
}
|
||||
req.TStep.Validators = append(req.TStep.Validators, validator)
|
||||
return req
|
||||
}
|
||||
|
||||
func (req *StepRequestValidation) ToStruct() *TStep {
|
||||
return req.TStep
|
||||
}
|
||||
|
||||
func (req *StepRequestValidation) Run() error {
|
||||
return req.TStep.Run()
|
||||
}
|
||||
Reference in New Issue
Block a user