mirror of
https://github.com/httprunner/httprunner.git
synced 2026-09-05 07:26:55 +08:00
feat: support setting global testcase timeout and step timeout
This commit is contained in:
+2
-1
@@ -1,9 +1,10 @@
|
|||||||
# Release History
|
# Release History
|
||||||
|
|
||||||
## v4.1.5 (2022-06-22)
|
## v4.1.5 (2022-06-26)
|
||||||
|
|
||||||
**go version**
|
**go version**
|
||||||
|
|
||||||
|
- feat: support setting global testcase timeout and step timeout
|
||||||
- change: set http request timeout default to 120s
|
- change: set http request timeout default to 120s
|
||||||
- fix: insert response cookies into request for redirect requests
|
- fix: insert response cookies into request for redirect requests
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package hrp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
|
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
|
||||||
)
|
)
|
||||||
@@ -28,6 +29,7 @@ type TConfig struct {
|
|||||||
ParametersSetting *TParamsConfig `json:"parameters_setting,omitempty" yaml:"parameters_setting,omitempty"`
|
ParametersSetting *TParamsConfig `json:"parameters_setting,omitempty" yaml:"parameters_setting,omitempty"`
|
||||||
ThinkTimeSetting *ThinkTimeConfig `json:"think_time,omitempty" yaml:"think_time,omitempty"`
|
ThinkTimeSetting *ThinkTimeConfig `json:"think_time,omitempty" yaml:"think_time,omitempty"`
|
||||||
WebSocketSetting *WebSocketConfig `json:"websocket,omitempty" yaml:"websocket,omitempty"`
|
WebSocketSetting *WebSocketConfig `json:"websocket,omitempty" yaml:"websocket,omitempty"`
|
||||||
|
Timeout float64 `json:"timeout,omitempty" yaml:"timeout,omitempty"` // global timeout in seconds
|
||||||
Export []string `json:"export,omitempty" yaml:"export,omitempty"`
|
Export []string `json:"export,omitempty" yaml:"export,omitempty"`
|
||||||
Weight int `json:"weight,omitempty" yaml:"weight,omitempty"`
|
Weight int `json:"weight,omitempty" yaml:"weight,omitempty"`
|
||||||
Path string `json:"path,omitempty" yaml:"path,omitempty"` // testcase file path
|
Path string `json:"path,omitempty" yaml:"path,omitempty"` // testcase file path
|
||||||
@@ -69,6 +71,12 @@ func (c *TConfig) SetThinkTime(strategy thinkTimeStrategy, cfg interface{}, limi
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetTimeout sets testcase timeout in seconds.
|
||||||
|
func (c *TConfig) SetTimeout(timeout time.Duration) *TConfig {
|
||||||
|
c.Timeout = timeout.Seconds()
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
// ExportVars specifies variable names to export for current testcase.
|
// ExportVars specifies variable names to export for current testcase.
|
||||||
func (c *TConfig) ExportVars(vars ...string) *TConfig {
|
func (c *TConfig) ExportVars(vars ...string) *TConfig {
|
||||||
c.Export = vars
|
c.Export = vars
|
||||||
|
|||||||
@@ -143,6 +143,13 @@ func (r *HRPRunner) SetProxyUrl(proxyUrl string) *HRPRunner {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetTimeout configures global timeout in seconds.
|
||||||
|
func (r *HRPRunner) SetTimeout(timeout time.Duration) *HRPRunner {
|
||||||
|
log.Info().Float64("timeout(seconds)", timeout.Seconds()).Msg("[init] SetTimeout")
|
||||||
|
r.httpClient.Timeout = timeout
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
// SetSaveTests configures whether to save summary of tests.
|
// SetSaveTests configures whether to save summary of tests.
|
||||||
func (r *HRPRunner) SetSaveTests(saveTests bool) *HRPRunner {
|
func (r *HRPRunner) SetSaveTests(saveTests bool) *HRPRunner {
|
||||||
log.Info().Bool("saveTests", saveTests).Msg("[init] SetSaveTests")
|
log.Info().Bool("saveTests", saveTests).Msg("[init] SetSaveTests")
|
||||||
@@ -260,6 +267,12 @@ func (r *HRPRunner) newCaseRunner(testcase *TestCase) (*testCaseRunner, error) {
|
|||||||
return nil, errors.Wrap(err, "parse testcase config failed")
|
return nil, errors.Wrap(err, "parse testcase config failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set testcase timeout in seconds
|
||||||
|
if runner.testCase.Config.Timeout != 0 {
|
||||||
|
timeout := time.Duration(runner.testCase.Config.Timeout*1000) * time.Millisecond
|
||||||
|
runner.hrpRunner.SetTimeout(timeout)
|
||||||
|
}
|
||||||
|
|
||||||
return runner, nil
|
return runner, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+22
-9
@@ -49,7 +49,7 @@ type Request struct {
|
|||||||
Body interface{} `json:"body,omitempty" yaml:"body,omitempty"`
|
Body interface{} `json:"body,omitempty" yaml:"body,omitempty"`
|
||||||
Json interface{} `json:"json,omitempty" yaml:"json,omitempty"`
|
Json interface{} `json:"json,omitempty" yaml:"json,omitempty"`
|
||||||
Data interface{} `json:"data,omitempty" yaml:"data,omitempty"`
|
Data interface{} `json:"data,omitempty" yaml:"data,omitempty"`
|
||||||
Timeout float32 `json:"timeout,omitempty" yaml:"timeout,omitempty"`
|
Timeout float64 `json:"timeout,omitempty" yaml:"timeout,omitempty"` // timeout in seconds
|
||||||
AllowRedirects bool `json:"allow_redirects,omitempty" yaml:"allow_redirects,omitempty"`
|
AllowRedirects bool `json:"allow_redirects,omitempty" yaml:"allow_redirects,omitempty"`
|
||||||
Verify bool `json:"verify,omitempty" yaml:"verify,omitempty"`
|
Verify bool `json:"verify,omitempty" yaml:"verify,omitempty"`
|
||||||
}
|
}
|
||||||
@@ -325,14 +325,22 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err
|
|||||||
rb.req = rb.req.WithContext(ctx)
|
rb.req = rb.req.WithContext(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// select HTTP client
|
||||||
|
var client *http.Client
|
||||||
|
if step.Request.HTTP2 {
|
||||||
|
client = r.hrpRunner.http2Client
|
||||||
|
} else {
|
||||||
|
client = r.hrpRunner.httpClient
|
||||||
|
}
|
||||||
|
|
||||||
|
// set step timeout
|
||||||
|
if step.Request.Timeout != 0 {
|
||||||
|
client.Timeout = time.Duration(step.Request.Timeout*1000) * time.Millisecond
|
||||||
|
}
|
||||||
|
|
||||||
// do request action
|
// do request action
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
var resp *http.Response
|
resp, err := client.Do(rb.req)
|
||||||
if step.Request.HTTP2 {
|
|
||||||
resp, err = r.hrpRunner.http2Client.Do(rb.req)
|
|
||||||
} else {
|
|
||||||
resp, err = r.hrpRunner.httpClient.Do(rb.req)
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stepResult, errors.Wrap(err, "do request failed")
|
return stepResult, errors.Wrap(err, "do request failed")
|
||||||
}
|
}
|
||||||
@@ -726,30 +734,35 @@ type StepRequestWithOptionalArgs struct {
|
|||||||
|
|
||||||
// SetVerify sets whether to verify SSL for current HTTP request.
|
// SetVerify sets whether to verify SSL for current HTTP request.
|
||||||
func (s *StepRequestWithOptionalArgs) SetVerify(verify bool) *StepRequestWithOptionalArgs {
|
func (s *StepRequestWithOptionalArgs) SetVerify(verify bool) *StepRequestWithOptionalArgs {
|
||||||
|
log.Info().Bool("verify", verify).Msg("set step request verify")
|
||||||
s.step.Request.Verify = verify
|
s.step.Request.Verify = verify
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTimeout sets timeout for current HTTP request.
|
// SetTimeout sets timeout for current HTTP request.
|
||||||
func (s *StepRequestWithOptionalArgs) SetTimeout(timeout float32) *StepRequestWithOptionalArgs {
|
func (s *StepRequestWithOptionalArgs) SetTimeout(timeout time.Duration) *StepRequestWithOptionalArgs {
|
||||||
s.step.Request.Timeout = timeout
|
log.Info().Float64("timeout(seconds)", timeout.Seconds()).Msg("set step request timeout")
|
||||||
|
s.step.Request.Timeout = timeout.Seconds()
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetProxies sets proxies for current HTTP request.
|
// SetProxies sets proxies for current HTTP request.
|
||||||
func (s *StepRequestWithOptionalArgs) SetProxies(proxies map[string]string) *StepRequestWithOptionalArgs {
|
func (s *StepRequestWithOptionalArgs) SetProxies(proxies map[string]string) *StepRequestWithOptionalArgs {
|
||||||
|
log.Info().Interface("proxies", proxies).Msg("set step request proxies")
|
||||||
// TODO
|
// TODO
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAllowRedirects sets whether to allow redirects for current HTTP request.
|
// SetAllowRedirects sets whether to allow redirects for current HTTP request.
|
||||||
func (s *StepRequestWithOptionalArgs) SetAllowRedirects(allowRedirects bool) *StepRequestWithOptionalArgs {
|
func (s *StepRequestWithOptionalArgs) SetAllowRedirects(allowRedirects bool) *StepRequestWithOptionalArgs {
|
||||||
|
log.Info().Bool("allowRedirects", allowRedirects).Msg("set step request allowRedirects")
|
||||||
s.step.Request.AllowRedirects = allowRedirects
|
s.step.Request.AllowRedirects = allowRedirects
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAuth sets auth for current HTTP request.
|
// SetAuth sets auth for current HTTP request.
|
||||||
func (s *StepRequestWithOptionalArgs) SetAuth(auth map[string]string) *StepRequestWithOptionalArgs {
|
func (s *StepRequestWithOptionalArgs) SetAuth(auth map[string]string) *StepRequestWithOptionalArgs {
|
||||||
|
log.Info().Interface("auth", auth).Msg("set step request auth")
|
||||||
// TODO
|
// TODO
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package hrp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
@@ -172,3 +173,58 @@ func TestRunRequestStatOn(t *testing.T) {
|
|||||||
t.Fatal()
|
t.Fatal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRunCaseWithTimeout(t *testing.T) {
|
||||||
|
r := NewRunner(t)
|
||||||
|
|
||||||
|
// global timeout
|
||||||
|
testcase1 := &TestCase{
|
||||||
|
Config: NewConfig("TestCase1").
|
||||||
|
SetTimeout(2 * time.Second). // set global timeout to 2s
|
||||||
|
SetBaseURL("http://httpbin.org"),
|
||||||
|
TestSteps: []IStep{
|
||||||
|
NewStep("step1").
|
||||||
|
GET("/delay/1").
|
||||||
|
Validate().
|
||||||
|
AssertEqual("status_code", 200, "check status code"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err := r.Run(testcase1)
|
||||||
|
if !assert.NoError(t, err) { // assert no error
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
testcase2 := &TestCase{
|
||||||
|
Config: NewConfig("TestCase2").
|
||||||
|
SetTimeout(2 * time.Second). // set global timeout to 2s
|
||||||
|
SetBaseURL("http://httpbin.org"),
|
||||||
|
TestSteps: []IStep{
|
||||||
|
NewStep("step1").
|
||||||
|
GET("/delay/3").
|
||||||
|
Validate().
|
||||||
|
AssertEqual("status_code", 200, "check status code"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err = r.Run(testcase2)
|
||||||
|
if !assert.Error(t, err) { // assert error
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
// step timeout
|
||||||
|
testcase3 := &TestCase{
|
||||||
|
Config: NewConfig("TestCase3").
|
||||||
|
SetTimeout(2 * time.Second).
|
||||||
|
SetBaseURL("http://httpbin.org"),
|
||||||
|
TestSteps: []IStep{
|
||||||
|
NewStep("step2").
|
||||||
|
GET("/delay/3").
|
||||||
|
SetTimeout(4*time.Second). // set step timeout to 4s
|
||||||
|
Validate().
|
||||||
|
AssertEqual("status_code", 200, "check status code"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err = r.Run(testcase3)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user