mirror of
https://github.com/httprunner/httprunner.git
synced 2026-06-02 06:19:34 +08:00
Merge pull request #1223 from bbx-winner/master
feat: support HTTP/2 protocol
This commit is contained in:
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
- feat: add `--profile` flag for har2case to support overwrite headers/cookies with specified yaml/json profile file
|
- feat: add `--profile` flag for har2case to support overwrite headers/cookies with specified yaml/json profile file
|
||||||
- feat: support run testcases in specified folder path, including testcases in sub folders
|
- feat: support run testcases in specified folder path, including testcases in sub folders
|
||||||
|
- feat: support HTTP/2 protocol
|
||||||
- change: integrate [sentry sdk][sentry sdk] for panic reporting and analysis
|
- change: integrate [sentry sdk][sentry sdk] for panic reporting and analysis
|
||||||
- change: lock funplugin version when creating scaffold project
|
- change: lock funplugin version when creating scaffold project
|
||||||
- fix: call referenced api/testcase with relative path
|
- fix: call referenced api/testcase with relative path
|
||||||
|
|||||||
1
go.mod
1
go.mod
@@ -19,6 +19,7 @@ require (
|
|||||||
github.com/rs/zerolog v1.26.1
|
github.com/rs/zerolog v1.26.1
|
||||||
github.com/spf13/cobra v1.2.1
|
github.com/spf13/cobra v1.2.1
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
|
golang.org/x/net v0.0.0-20220225172249-27dd8689420f
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ func newResponseObject(t *testing.T, parser *Parser, resp *http.Response) (*resp
|
|||||||
}
|
}
|
||||||
|
|
||||||
respObjMeta := respObjMeta{
|
respObjMeta := respObjMeta{
|
||||||
|
Proto: resp.Proto,
|
||||||
StatusCode: resp.StatusCode,
|
StatusCode: resp.StatusCode,
|
||||||
Headers: headers,
|
Headers: headers,
|
||||||
Cookies: cookies,
|
Cookies: cookies,
|
||||||
@@ -74,6 +75,7 @@ func newResponseObject(t *testing.T, parser *Parser, resp *http.Response) (*resp
|
|||||||
}
|
}
|
||||||
|
|
||||||
type respObjMeta struct {
|
type respObjMeta struct {
|
||||||
|
Proto string `json:"proto"`
|
||||||
StatusCode int `json:"status_code"`
|
StatusCode int `json:"status_code"`
|
||||||
Headers map[string]string `json:"headers"`
|
Headers map[string]string `json:"headers"`
|
||||||
Cookies map[string]string `json:"cookies"`
|
Cookies map[string]string `json:"cookies"`
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
"golang.org/x/net/http2"
|
||||||
|
|
||||||
"github.com/httprunner/httprunner/hrp/internal/builtin"
|
"github.com/httprunner/httprunner/hrp/internal/builtin"
|
||||||
"github.com/httprunner/httprunner/hrp/internal/sdk"
|
"github.com/httprunner/httprunner/hrp/internal/sdk"
|
||||||
@@ -31,12 +32,18 @@ func NewRunner(t *testing.T) *HRPRunner {
|
|||||||
t: t,
|
t: t,
|
||||||
failfast: true, // default to failfast
|
failfast: true, // default to failfast
|
||||||
genHTMLReport: false,
|
genHTMLReport: false,
|
||||||
client: &http.Client{
|
httpClient: &http.Client{
|
||||||
Transport: &http.Transport{
|
Transport: &http.Transport{
|
||||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
},
|
},
|
||||||
Timeout: 30 * time.Second,
|
Timeout: 30 * time.Second,
|
||||||
},
|
},
|
||||||
|
http2Client: &http.Client{
|
||||||
|
Transport: &http2.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
|
},
|
||||||
|
Timeout: 30 * time.Second,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,13 +54,18 @@ type HRPRunner struct {
|
|||||||
pluginLogOn bool
|
pluginLogOn bool
|
||||||
saveTests bool
|
saveTests bool
|
||||||
genHTMLReport bool
|
genHTMLReport bool
|
||||||
client *http.Client
|
httpClient *http.Client
|
||||||
|
http2Client *http.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetClientTransport configures transport of http client for high concurrency load testing
|
// SetClientTransport configures transport of http client for high concurrency load testing
|
||||||
func (r *HRPRunner) SetClientTransport(maxConns int, disableKeepAlive bool, disableCompression bool) *HRPRunner {
|
func (r *HRPRunner) SetClientTransport(maxConns int, disableKeepAlive bool, disableCompression bool) *HRPRunner {
|
||||||
log.Info().Int("maxConns", maxConns).Msg("[init] SetClientTransport")
|
log.Info().
|
||||||
r.client.Transport = &http.Transport{
|
Int("maxConns", maxConns).
|
||||||
|
Bool("disableKeepAlive", disableKeepAlive).
|
||||||
|
Bool("disableCompression", disableCompression).
|
||||||
|
Msg("[init] SetClientTransport")
|
||||||
|
r.httpClient.Transport = &http.Transport{
|
||||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
DialContext: (&net.Dialer{}).DialContext,
|
DialContext: (&net.Dialer{}).DialContext,
|
||||||
MaxIdleConns: 0,
|
MaxIdleConns: 0,
|
||||||
@@ -61,6 +73,10 @@ func (r *HRPRunner) SetClientTransport(maxConns int, disableKeepAlive bool, disa
|
|||||||
DisableKeepAlives: disableKeepAlive,
|
DisableKeepAlives: disableKeepAlive,
|
||||||
DisableCompression: disableCompression,
|
DisableCompression: disableCompression,
|
||||||
}
|
}
|
||||||
|
r.http2Client.Transport = &http2.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
|
DisableCompression: disableCompression,
|
||||||
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +109,7 @@ func (r *HRPRunner) SetProxyUrl(proxyUrl string) *HRPRunner {
|
|||||||
log.Error().Err(err).Str("proxyUrl", proxyUrl).Msg("[init] invalid proxyUrl")
|
log.Error().Err(err).Str("proxyUrl", proxyUrl).Msg("[init] invalid proxyUrl")
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
r.client.Transport = &http.Transport{
|
r.httpClient.Transport = &http.Transport{
|
||||||
Proxy: http.ProxyURL(p),
|
Proxy: http.ProxyURL(p),
|
||||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,16 +86,6 @@ func isPreRendezvousAllReleased(rendezvous *Rendezvous, testCase *TCase) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rendezvous creates a new rendezvous
|
|
||||||
func (s *StepRequest) Rendezvous(name string) *StepRendezvous {
|
|
||||||
s.step.Rendezvous = &Rendezvous{
|
|
||||||
Name: name,
|
|
||||||
}
|
|
||||||
return &StepRendezvous{
|
|
||||||
step: s.step,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithUserNumber sets the user number needed to release the current rendezvous
|
// WithUserNumber sets the user number needed to release the current rendezvous
|
||||||
func (s *StepRendezvous) WithUserNumber(number int64) *StepRendezvous {
|
func (s *StepRendezvous) WithUserNumber(number int64) *StepRendezvous {
|
||||||
s.step.Rendezvous.Number = number
|
s.step.Rendezvous.Number = number
|
||||||
|
|||||||
@@ -16,26 +16,26 @@ func TestRunCaseWithRendezvous(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
TestSteps: []IStep{
|
TestSteps: []IStep{
|
||||||
NewStep("test negative number").
|
NewStep("test negative number").
|
||||||
Rendezvous("test negative number").
|
SetRendezvous("test negative number").
|
||||||
WithUserNumber(-1),
|
WithUserNumber(-1),
|
||||||
NewStep("test overflow number").
|
NewStep("test overflow number").
|
||||||
Rendezvous("test overflow number").
|
SetRendezvous("test overflow number").
|
||||||
WithUserNumber(1000000),
|
WithUserNumber(1000000),
|
||||||
NewStep("test negative percent").
|
NewStep("test negative percent").
|
||||||
Rendezvous("test very low percent").
|
SetRendezvous("test very low percent").
|
||||||
WithUserPercent(-0.5),
|
WithUserPercent(-0.5),
|
||||||
NewStep("test very low percent").
|
NewStep("test very low percent").
|
||||||
Rendezvous("test very low percent").
|
SetRendezvous("test very low percent").
|
||||||
WithUserPercent(0.00001),
|
WithUserPercent(0.00001),
|
||||||
NewStep("test overflow percent").
|
NewStep("test overflow percent").
|
||||||
Rendezvous("test overflow percent").
|
SetRendezvous("test overflow percent").
|
||||||
WithUserPercent(1.5),
|
WithUserPercent(1.5),
|
||||||
NewStep("test conflict params").
|
NewStep("test conflict params").
|
||||||
Rendezvous("test conflict params").
|
SetRendezvous("test conflict params").
|
||||||
WithUserNumber(1).
|
WithUserNumber(1).
|
||||||
WithUserPercent(0.123),
|
WithUserPercent(0.123),
|
||||||
NewStep("test negative timeout").
|
NewStep("test negative timeout").
|
||||||
Rendezvous("test negative timeout").
|
SetRendezvous("test negative timeout").
|
||||||
WithTimeout(-1000),
|
WithTimeout(-1000),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ const (
|
|||||||
type Request struct {
|
type Request struct {
|
||||||
Method HTTPMethod `json:"method" yaml:"method"` // required
|
Method HTTPMethod `json:"method" yaml:"method"` // required
|
||||||
URL string `json:"url" yaml:"url"` // required
|
URL string `json:"url" yaml:"url"` // required
|
||||||
|
HTTP2 bool `json:"http2,omitempty" yaml:"http2,omitempty"`
|
||||||
Params map[string]interface{} `json:"params,omitempty" yaml:"params,omitempty"`
|
Params map[string]interface{} `json:"params,omitempty" yaml:"params,omitempty"`
|
||||||
Headers map[string]string `json:"headers,omitempty" yaml:"headers,omitempty"`
|
Headers map[string]string `json:"headers,omitempty" yaml:"headers,omitempty"`
|
||||||
Cookies map[string]string `json:"cookies,omitempty" yaml:"cookies,omitempty"`
|
Cookies map[string]string `json:"cookies,omitempty" yaml:"cookies,omitempty"`
|
||||||
@@ -56,17 +57,23 @@ func newRequestBuilder(parser *Parser, config *TConfig, stepRequest *Request) *r
|
|||||||
var requestMap map[string]interface{}
|
var requestMap map[string]interface{}
|
||||||
_ = json.Unmarshal(jsonRequest, &requestMap)
|
_ = json.Unmarshal(jsonRequest, &requestMap)
|
||||||
|
|
||||||
|
request := &http.Request{
|
||||||
|
Header: make(http.Header),
|
||||||
|
}
|
||||||
|
if stepRequest.HTTP2 {
|
||||||
|
request.ProtoMajor = 2
|
||||||
|
request.ProtoMinor = 0
|
||||||
|
} else {
|
||||||
|
request.ProtoMajor = 1
|
||||||
|
request.ProtoMinor = 1
|
||||||
|
}
|
||||||
|
|
||||||
return &requestBuilder{
|
return &requestBuilder{
|
||||||
stepRequest: stepRequest,
|
stepRequest: stepRequest,
|
||||||
req: &http.Request{
|
req: request,
|
||||||
Header: make(http.Header),
|
config: config,
|
||||||
Proto: "HTTP/1.1",
|
parser: parser,
|
||||||
ProtoMajor: 1,
|
requestMap: requestMap,
|
||||||
ProtoMinor: 1,
|
|
||||||
},
|
|
||||||
config: config,
|
|
||||||
parser: parser,
|
|
||||||
requestMap: requestMap,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,7 +313,13 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err
|
|||||||
|
|
||||||
// do request action
|
// do request action
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
resp, err := r.hrpRunner.client.Do(rb.req)
|
var resp *http.Response
|
||||||
|
if step.Request.HTTP2 {
|
||||||
|
resp, err = r.hrpRunner.http2Client.Do(rb.req)
|
||||||
|
} else {
|
||||||
|
resp, err = r.hrpRunner.httpClient.Do(rb.req)
|
||||||
|
}
|
||||||
|
|
||||||
stepResult.Elapsed = time.Since(start).Milliseconds()
|
stepResult.Elapsed = time.Since(start).Milliseconds()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stepResult, errors.Wrap(err, "do request failed")
|
return stepResult, errors.Wrap(err, "do request failed")
|
||||||
@@ -465,11 +478,24 @@ func (s *StepRequest) SetupHook(hook string) *StepRequest {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HTTP2 enables HTTP/2 protocol
|
||||||
|
func (s *StepRequest) HTTP2() *StepRequest {
|
||||||
|
s.step.Request = &Request{
|
||||||
|
HTTP2: true,
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
// GET makes a HTTP GET request.
|
// GET makes a HTTP GET request.
|
||||||
func (s *StepRequest) GET(url string) *StepRequestWithOptionalArgs {
|
func (s *StepRequest) GET(url string) *StepRequestWithOptionalArgs {
|
||||||
s.step.Request = &Request{
|
if s.step.Request != nil {
|
||||||
Method: httpGET,
|
s.step.Request.Method = httpGET
|
||||||
URL: url,
|
s.step.Request.URL = url
|
||||||
|
} else {
|
||||||
|
s.step.Request = &Request{
|
||||||
|
Method: httpGET,
|
||||||
|
URL: url,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return &StepRequestWithOptionalArgs{
|
return &StepRequestWithOptionalArgs{
|
||||||
step: s.step,
|
step: s.step,
|
||||||
@@ -478,9 +504,14 @@ func (s *StepRequest) GET(url string) *StepRequestWithOptionalArgs {
|
|||||||
|
|
||||||
// HEAD makes a HTTP HEAD request.
|
// HEAD makes a HTTP HEAD request.
|
||||||
func (s *StepRequest) HEAD(url string) *StepRequestWithOptionalArgs {
|
func (s *StepRequest) HEAD(url string) *StepRequestWithOptionalArgs {
|
||||||
s.step.Request = &Request{
|
if s.step.Request != nil {
|
||||||
Method: httpHEAD,
|
s.step.Request.Method = httpHEAD
|
||||||
URL: url,
|
s.step.Request.URL = url
|
||||||
|
} else {
|
||||||
|
s.step.Request = &Request{
|
||||||
|
Method: httpHEAD,
|
||||||
|
URL: url,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return &StepRequestWithOptionalArgs{
|
return &StepRequestWithOptionalArgs{
|
||||||
step: s.step,
|
step: s.step,
|
||||||
@@ -489,9 +520,14 @@ func (s *StepRequest) HEAD(url string) *StepRequestWithOptionalArgs {
|
|||||||
|
|
||||||
// POST makes a HTTP POST request.
|
// POST makes a HTTP POST request.
|
||||||
func (s *StepRequest) POST(url string) *StepRequestWithOptionalArgs {
|
func (s *StepRequest) POST(url string) *StepRequestWithOptionalArgs {
|
||||||
s.step.Request = &Request{
|
if s.step.Request != nil {
|
||||||
Method: httpPOST,
|
s.step.Request.Method = httpPOST
|
||||||
URL: url,
|
s.step.Request.URL = url
|
||||||
|
} else {
|
||||||
|
s.step.Request = &Request{
|
||||||
|
Method: httpPOST,
|
||||||
|
URL: url,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return &StepRequestWithOptionalArgs{
|
return &StepRequestWithOptionalArgs{
|
||||||
step: s.step,
|
step: s.step,
|
||||||
@@ -500,9 +536,14 @@ func (s *StepRequest) POST(url string) *StepRequestWithOptionalArgs {
|
|||||||
|
|
||||||
// PUT makes a HTTP PUT request.
|
// PUT makes a HTTP PUT request.
|
||||||
func (s *StepRequest) PUT(url string) *StepRequestWithOptionalArgs {
|
func (s *StepRequest) PUT(url string) *StepRequestWithOptionalArgs {
|
||||||
s.step.Request = &Request{
|
if s.step.Request != nil {
|
||||||
Method: httpPUT,
|
s.step.Request.Method = httpPUT
|
||||||
URL: url,
|
s.step.Request.URL = url
|
||||||
|
} else {
|
||||||
|
s.step.Request = &Request{
|
||||||
|
Method: httpPUT,
|
||||||
|
URL: url,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return &StepRequestWithOptionalArgs{
|
return &StepRequestWithOptionalArgs{
|
||||||
step: s.step,
|
step: s.step,
|
||||||
@@ -511,9 +552,14 @@ func (s *StepRequest) PUT(url string) *StepRequestWithOptionalArgs {
|
|||||||
|
|
||||||
// DELETE makes a HTTP DELETE request.
|
// DELETE makes a HTTP DELETE request.
|
||||||
func (s *StepRequest) DELETE(url string) *StepRequestWithOptionalArgs {
|
func (s *StepRequest) DELETE(url string) *StepRequestWithOptionalArgs {
|
||||||
s.step.Request = &Request{
|
if s.step.Request != nil {
|
||||||
Method: httpDELETE,
|
s.step.Request.Method = httpDELETE
|
||||||
URL: url,
|
s.step.Request.URL = url
|
||||||
|
} else {
|
||||||
|
s.step.Request = &Request{
|
||||||
|
Method: httpDELETE,
|
||||||
|
URL: url,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return &StepRequestWithOptionalArgs{
|
return &StepRequestWithOptionalArgs{
|
||||||
step: s.step,
|
step: s.step,
|
||||||
@@ -522,9 +568,14 @@ func (s *StepRequest) DELETE(url string) *StepRequestWithOptionalArgs {
|
|||||||
|
|
||||||
// OPTIONS makes a HTTP OPTIONS request.
|
// OPTIONS makes a HTTP OPTIONS request.
|
||||||
func (s *StepRequest) OPTIONS(url string) *StepRequestWithOptionalArgs {
|
func (s *StepRequest) OPTIONS(url string) *StepRequestWithOptionalArgs {
|
||||||
s.step.Request = &Request{
|
if s.step.Request != nil {
|
||||||
Method: httpOPTIONS,
|
s.step.Request.Method = httpOPTIONS
|
||||||
URL: url,
|
s.step.Request.URL = url
|
||||||
|
} else {
|
||||||
|
s.step.Request = &Request{
|
||||||
|
Method: httpOPTIONS,
|
||||||
|
URL: url,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return &StepRequestWithOptionalArgs{
|
return &StepRequestWithOptionalArgs{
|
||||||
step: s.step,
|
step: s.step,
|
||||||
@@ -533,9 +584,14 @@ func (s *StepRequest) OPTIONS(url string) *StepRequestWithOptionalArgs {
|
|||||||
|
|
||||||
// PATCH makes a HTTP PATCH request.
|
// PATCH makes a HTTP PATCH request.
|
||||||
func (s *StepRequest) PATCH(url string) *StepRequestWithOptionalArgs {
|
func (s *StepRequest) PATCH(url string) *StepRequestWithOptionalArgs {
|
||||||
s.step.Request = &Request{
|
if s.step.Request != nil {
|
||||||
Method: httpPATCH,
|
s.step.Request.Method = httpPATCH
|
||||||
URL: url,
|
s.step.Request.URL = url
|
||||||
|
} else {
|
||||||
|
s.step.Request = &Request{
|
||||||
|
Method: httpPATCH,
|
||||||
|
URL: url,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return &StepRequestWithOptionalArgs{
|
return &StepRequestWithOptionalArgs{
|
||||||
step: s.step,
|
step: s.step,
|
||||||
@@ -600,6 +656,16 @@ func (s *StepRequest) SetThinkTime(time float64) *StepThinkTime {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetRendezvous creates a new rendezvous
|
||||||
|
func (s *StepRequest) SetRendezvous(name string) *StepRendezvous {
|
||||||
|
s.step.Rendezvous = &Rendezvous{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
return &StepRendezvous{
|
||||||
|
step: s.step,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// StepRequestWithOptionalArgs implements IStep interface.
|
// StepRequestWithOptionalArgs implements IStep interface.
|
||||||
type StepRequestWithOptionalArgs struct {
|
type StepRequestWithOptionalArgs struct {
|
||||||
step *TStep
|
step *TStep
|
||||||
|
|||||||
54
hrp/tests/protocol_test.go
Normal file
54
hrp/tests/protocol_test.go
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/httprunner/httprunner/hrp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestProtocol(t *testing.T) {
|
||||||
|
testcase := &hrp.TestCase{
|
||||||
|
Config: hrp.NewConfig("run request with different protocol types").
|
||||||
|
SetBaseURL("https://postman-echo.com"),
|
||||||
|
TestSteps: []hrp.IStep{
|
||||||
|
hrp.NewStep("HTTP/1.1 get").
|
||||||
|
GET("/get").
|
||||||
|
WithParams(map[string]interface{}{"foo1": "foo1", "foo2": "foo2"}).
|
||||||
|
WithHeaders(map[string]string{"User-Agent": "HttpRunnerPlus"}).
|
||||||
|
Validate().
|
||||||
|
AssertEqual("status_code", 200, "check status code").
|
||||||
|
AssertEqual("proto", "HTTP/1.1", "check protocol type").
|
||||||
|
AssertLengthEqual("body.args.foo1", 4, "check param foo1"),
|
||||||
|
hrp.NewStep("HTTP/1.1 post").
|
||||||
|
POST("/post").
|
||||||
|
WithHeaders(map[string]string{"User-Agent": "HttpRunnerPlus"}).
|
||||||
|
WithBody(map[string]interface{}{"foo1": "foo1", "foo2": "foo2"}).
|
||||||
|
Validate().
|
||||||
|
AssertEqual("status_code", 200, "check status code").
|
||||||
|
AssertEqual("proto", "HTTP/1.1", "check protocol type").
|
||||||
|
AssertLengthEqual("body.json.foo1", 4, "check body foo1"),
|
||||||
|
hrp.NewStep("HTTP/2 get").
|
||||||
|
HTTP2().
|
||||||
|
GET("/get").
|
||||||
|
WithParams(map[string]interface{}{"foo1": "foo1", "foo2": "foo2"}).
|
||||||
|
WithHeaders(map[string]string{"User-Agent": "HttpRunnerPlus"}).
|
||||||
|
Validate().
|
||||||
|
AssertEqual("status_code", 200, "check status code").
|
||||||
|
AssertEqual("proto", "HTTP/2.0", "check protocol type").
|
||||||
|
AssertLengthEqual("body.args.foo1", 4, "check param foo1"),
|
||||||
|
hrp.NewStep("HTTP/2 post").
|
||||||
|
HTTP2().
|
||||||
|
POST("/post").
|
||||||
|
WithHeaders(map[string]string{"User-Agent": "HttpRunnerPlus"}).
|
||||||
|
WithBody(map[string]interface{}{"foo1": "foo1", "foo2": "foo2"}).
|
||||||
|
Validate().
|
||||||
|
AssertEqual("status_code", 200, "check status code").
|
||||||
|
AssertEqual("proto", "HTTP/2.0", "check protocol type").
|
||||||
|
AssertLengthEqual("body.json.foo1", 4, "check body foo1"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err := hrp.NewRunner(t).Run(testcase)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("run testcase error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,50 +6,47 @@ import (
|
|||||||
"github.com/httprunner/httprunner/hrp"
|
"github.com/httprunner/httprunner/hrp"
|
||||||
)
|
)
|
||||||
|
|
||||||
const rendezvousTestJSONPath = "rendezvous_test.json"
|
|
||||||
|
|
||||||
var rendezvousTestcase = &hrp.TestCase{
|
|
||||||
Config: hrp.NewConfig("run request with functions").
|
|
||||||
SetBaseURL("https://postman-echo.com").
|
|
||||||
WithVariables(map[string]interface{}{
|
|
||||||
"n": 5,
|
|
||||||
"a": 12.3,
|
|
||||||
"b": 3.45,
|
|
||||||
}),
|
|
||||||
TestSteps: []hrp.IStep{
|
|
||||||
hrp.NewStep("waiting for all users in the beginning").
|
|
||||||
Rendezvous("rendezvous0"),
|
|
||||||
hrp.NewStep("rendezvous before get").
|
|
||||||
Rendezvous("rendezvous1").
|
|
||||||
WithUserNumber(50).
|
|
||||||
WithTimeout(3000),
|
|
||||||
hrp.NewStep("get with params").
|
|
||||||
GET("/get").
|
|
||||||
WithParams(map[string]interface{}{"foo1": "foo1", "foo2": "foo2"}).
|
|
||||||
WithHeaders(map[string]string{"User-Agent": "HttpRunnerPlus"}).
|
|
||||||
Extract().
|
|
||||||
WithJmesPath("body.args.foo1", "varFoo1").
|
|
||||||
Validate().
|
|
||||||
AssertEqual("status_code", 200, "check status code"),
|
|
||||||
hrp.NewStep("rendezvous before post").
|
|
||||||
Rendezvous("rendezvous2").
|
|
||||||
WithUserNumber(20).
|
|
||||||
WithTimeout(2000),
|
|
||||||
hrp.NewStep("post json data with functions").
|
|
||||||
POST("/post").
|
|
||||||
WithHeaders(map[string]string{"User-Agent": "HttpRunnerPlus"}).
|
|
||||||
WithBody(map[string]interface{}{"foo1": "foo1", "foo2": "foo2"}).
|
|
||||||
Validate().
|
|
||||||
AssertEqual("status_code", 200, "check status code").
|
|
||||||
AssertLengthEqual("body.json.foo1", 4, "check args foo1").
|
|
||||||
AssertEqual("body.json.foo2", "foo2", "check args foo2"),
|
|
||||||
hrp.NewStep("waiting for all users in the end").
|
|
||||||
Rendezvous("rendezvous3"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRendezvous(t *testing.T) {
|
func TestRendezvous(t *testing.T) {
|
||||||
err := hrp.NewRunner(t).Run(rendezvousTestcase)
|
testcase := &hrp.TestCase{
|
||||||
|
Config: hrp.NewConfig("run request with rendezvous").
|
||||||
|
SetBaseURL("https://postman-echo.com").
|
||||||
|
WithVariables(map[string]interface{}{
|
||||||
|
"n": 5,
|
||||||
|
"a": 12.3,
|
||||||
|
"b": 3.45,
|
||||||
|
}),
|
||||||
|
TestSteps: []hrp.IStep{
|
||||||
|
hrp.NewStep("waiting for all users in the beginning").
|
||||||
|
SetRendezvous("rendezvous0"),
|
||||||
|
hrp.NewStep("rendezvous before get").
|
||||||
|
SetRendezvous("rendezvous1").
|
||||||
|
WithUserNumber(50).
|
||||||
|
WithTimeout(3000),
|
||||||
|
hrp.NewStep("get with params").
|
||||||
|
GET("/get").
|
||||||
|
WithParams(map[string]interface{}{"foo1": "foo1", "foo2": "foo2"}).
|
||||||
|
WithHeaders(map[string]string{"User-Agent": "HttpRunnerPlus"}).
|
||||||
|
Extract().
|
||||||
|
WithJmesPath("body.args.foo1", "varFoo1").
|
||||||
|
Validate().
|
||||||
|
AssertEqual("status_code", 200, "check status code"),
|
||||||
|
hrp.NewStep("rendezvous before post").
|
||||||
|
SetRendezvous("rendezvous2").
|
||||||
|
WithUserNumber(20).
|
||||||
|
WithTimeout(2000),
|
||||||
|
hrp.NewStep("post json data with functions").
|
||||||
|
POST("/post").
|
||||||
|
WithHeaders(map[string]string{"User-Agent": "HttpRunnerPlus"}).
|
||||||
|
WithBody(map[string]interface{}{"foo1": "foo1", "foo2": "foo2"}).
|
||||||
|
Validate().
|
||||||
|
AssertEqual("status_code", 200, "check status code").
|
||||||
|
AssertLengthEqual("body.json.foo1", 4, "check args foo1").
|
||||||
|
AssertEqual("body.json.foo2", "foo2", "check args foo2"),
|
||||||
|
hrp.NewStep("waiting for all users in the end").
|
||||||
|
SetRendezvous("rendezvous3"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err := hrp.NewRunner(t).Run(testcase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("run testcase error: %v", err)
|
t.Fatalf("run testcase error: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user