mirror of
https://github.com/httprunner/httprunner.git
synced 2026-07-06 23:11:21 +08:00
refactor: NewConfig
This commit is contained in:
@@ -57,15 +57,14 @@ func (b *hrpBoomer) Quit() {
|
|||||||
|
|
||||||
func (b *hrpBoomer) convertBoomerTask(testcase *TestCase) *boomer.Task {
|
func (b *hrpBoomer) convertBoomerTask(testcase *TestCase) *boomer.Task {
|
||||||
return &boomer.Task{
|
return &boomer.Task{
|
||||||
Name: testcase.Config.Name,
|
Name: testcase.Config.ToStruct().Name,
|
||||||
Weight: testcase.Config.Weight,
|
Weight: testcase.Config.ToStruct().Weight,
|
||||||
Fn: func() {
|
Fn: func() {
|
||||||
runner := NewRunner(nil).SetDebug(b.debug)
|
runner := NewRunner(nil).SetDebug(b.debug)
|
||||||
config := testcase.Config
|
|
||||||
for _, step := range testcase.TestSteps {
|
for _, step := range testcase.TestSteps {
|
||||||
var err error
|
var err error
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
stepData, err := runner.runStep(step, config)
|
stepData, err := runner.runStep(step, testcase.Config)
|
||||||
elapsed := time.Since(start).Nanoseconds() / int64(time.Millisecond)
|
elapsed := time.Since(start).Nanoseconds() / int64(time.Millisecond)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
b.RecordSuccess(step.Type(), step.Name(), elapsed, stepData.responseLength)
|
b.RecordSuccess(step.Type(), step.Name(), elapsed, stepData.responseLength)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
func (tc *TestCase) ToTCase() (*TCase, error) {
|
func (tc *TestCase) ToTCase() (*TCase, error) {
|
||||||
tCase := TCase{
|
tCase := TCase{
|
||||||
Config: tc.Config,
|
Config: tc.Config.ToStruct(),
|
||||||
}
|
}
|
||||||
for _, step := range tc.TestSteps {
|
for _, step := range tc.TestSteps {
|
||||||
tCase.TestSteps = append(tCase.TestSteps, step.ToStruct())
|
tCase.TestSteps = append(tCase.TestSteps, step.ToStruct())
|
||||||
@@ -105,7 +105,7 @@ func loadFromYAML(path string) (*TCase, error) {
|
|||||||
|
|
||||||
func (tc *TCase) ToTestCase() (*TestCase, error) {
|
func (tc *TCase) ToTestCase() (*TestCase, error) {
|
||||||
testCase := &TestCase{
|
testCase := &TestCase{
|
||||||
Config: tc.Config,
|
Config: &Config{cfg: tc.Config},
|
||||||
}
|
}
|
||||||
for _, step := range tc.TestSteps {
|
for _, step := range tc.TestSteps {
|
||||||
if step.Request != nil {
|
if step.Request != nil {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ One-stop solution for HTTP(S) testing.
|
|||||||
|
|
||||||
### Synopsis
|
### Synopsis
|
||||||
|
|
||||||
hrp (HttpRunner+) is the next generation for HttpRunner. Enjoy! ✨ 🚀 ✨
|
hrp (HttpRunner+) is the one-stop solution for HTTP(S) testing. Enjoy! ✨ 🚀 ✨
|
||||||
|
|
||||||
License: Apache-2.0
|
License: Apache-2.0
|
||||||
Github: https://github.com/httprunner/hrp
|
Github: https://github.com/httprunner/hrp
|
||||||
@@ -22,4 +22,4 @@ Copyright 2021 debugtalk
|
|||||||
* [hrp har2case](hrp_har2case.md) - Convert HAR to json/yaml testcase files
|
* [hrp har2case](hrp_har2case.md) - Convert HAR to json/yaml testcase files
|
||||||
* [hrp run](hrp_run.md) - run API test
|
* [hrp run](hrp_run.md) - run API test
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 7-Dec-2021
|
###### Auto generated by spf13/cobra on 8-Dec-2021
|
||||||
|
|||||||
@@ -39,4 +39,4 @@ hrp boom [flags]
|
|||||||
|
|
||||||
* [hrp](hrp.md) - One-stop solution for HTTP(S) testing.
|
* [hrp](hrp.md) - One-stop solution for HTTP(S) testing.
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 7-Dec-2021
|
###### Auto generated by spf13/cobra on 8-Dec-2021
|
||||||
|
|||||||
@@ -23,4 +23,4 @@ hrp har2case harPath... [flags]
|
|||||||
|
|
||||||
* [hrp](hrp.md) - One-stop solution for HTTP(S) testing.
|
* [hrp](hrp.md) - One-stop solution for HTTP(S) testing.
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 7-Dec-2021
|
###### Auto generated by spf13/cobra on 8-Dec-2021
|
||||||
|
|||||||
@@ -30,4 +30,4 @@ hrp run path... [flags]
|
|||||||
|
|
||||||
* [hrp](hrp.md) - One-stop solution for HTTP(S) testing.
|
* [hrp](hrp.md) - One-stop solution for HTTP(S) testing.
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 7-Dec-2021
|
###### Auto generated by spf13/cobra on 8-Dec-2021
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ func (h *har) load() (*Har, error) {
|
|||||||
|
|
||||||
func (h *har) prepareConfig() *hrp.TConfig {
|
func (h *har) prepareConfig() *hrp.TConfig {
|
||||||
return hrp.NewConfig("testcase description").
|
return hrp.NewConfig("testcase description").
|
||||||
SetVerifySSL(false)
|
SetVerifySSL(false).ToStruct()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *har) prepareTestSteps() ([]*hrp.TStep, error) {
|
func (h *har) prepareTestSteps() ([]*hrp.TStep, error) {
|
||||||
|
|||||||
@@ -78,6 +78,12 @@ type TCase struct {
|
|||||||
TestSteps []*TStep `json:"teststeps" yaml:"teststeps"`
|
TestSteps []*TStep `json:"teststeps" yaml:"teststeps"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IConfig represents interface for testcase config.
|
||||||
|
type IConfig interface {
|
||||||
|
Name() string
|
||||||
|
ToStruct() *TConfig
|
||||||
|
}
|
||||||
|
|
||||||
// IStep represents interface for all types for teststeps.
|
// IStep represents interface for all types for teststeps.
|
||||||
type IStep interface {
|
type IStep interface {
|
||||||
Name() string
|
Name() string
|
||||||
@@ -94,7 +100,7 @@ type ITestCase interface {
|
|||||||
// TestCase is a container for one testcase.
|
// TestCase is a container for one testcase.
|
||||||
// used for testcase runner
|
// used for testcase runner
|
||||||
type TestCase struct {
|
type TestCase struct {
|
||||||
Config *TConfig
|
Config IConfig
|
||||||
TestSteps []IStep
|
TestSteps []IStep
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
30
runner.go
30
runner.go
@@ -104,7 +104,7 @@ func (r *hrpRunner) runCase(testcase *TestCase) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info().Str("testcase", config.Name).Msg("run testcase start")
|
log.Info().Str("testcase", config.Name()).Msg("run testcase start")
|
||||||
|
|
||||||
for _, step := range testcase.TestSteps {
|
for _, step := range testcase.TestSteps {
|
||||||
_, err := r.runStep(step, config)
|
_, err := r.runStep(step, config)
|
||||||
@@ -113,11 +113,11 @@ func (r *hrpRunner) runCase(testcase *TestCase) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info().Str("testcase", config.Name).Msg("run testcase end")
|
log.Info().Str("testcase", config.Name()).Msg("run testcase end")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *hrpRunner) runStep(step IStep, config *TConfig) (stepResult *stepData, err error) {
|
func (r *hrpRunner) runStep(step IStep, config IConfig) (stepResult *stepData, err error) {
|
||||||
// step type priority order: transaction > rendezvous > testcase > request
|
// step type priority order: transaction > rendezvous > testcase > request
|
||||||
if stepTran, ok := step.(*stepTransaction); ok {
|
if stepTran, ok := step.(*stepTransaction); ok {
|
||||||
// transaction
|
// transaction
|
||||||
@@ -146,17 +146,18 @@ func (r *hrpRunner) runStep(step IStep, config *TConfig) (stepResult *stepData,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfg := config.ToStruct()
|
||||||
stepVariables := copiedStep.Variables
|
stepVariables := copiedStep.Variables
|
||||||
// override variables
|
// override variables
|
||||||
// step variables > session variables (extracted variables from previous steps)
|
// step variables > session variables (extracted variables from previous steps)
|
||||||
stepVariables = mergeVariables(stepVariables, r.sessionVariables)
|
stepVariables = mergeVariables(stepVariables, r.sessionVariables)
|
||||||
// step variables > testcase config variables
|
// step variables > testcase config variables
|
||||||
stepVariables = mergeVariables(stepVariables, config.Variables)
|
stepVariables = mergeVariables(stepVariables, cfg.Variables)
|
||||||
|
|
||||||
// parse step variables
|
// parse step variables
|
||||||
parsedVariables, err := parseVariables(stepVariables)
|
parsedVariables, err := parseVariables(stepVariables)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Interface("variables", config.Variables).Err(err).Msg("parse step variables failed")
|
log.Error().Interface("variables", cfg.Variables).Err(err).Msg("parse step variables failed")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
copiedStep.Variables = parsedVariables // avoid data racing
|
copiedStep.Variables = parsedVariables // avoid data racing
|
||||||
@@ -172,7 +173,7 @@ func (r *hrpRunner) runStep(step IStep, config *TConfig) (stepResult *stepData,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// run request
|
// run request
|
||||||
copiedStep.Request.URL = buildURL(config.BaseURL, copiedStep.Request.URL) // avoid data racing
|
copiedStep.Request.URL = buildURL(cfg.BaseURL, copiedStep.Request.URL) // avoid data racing
|
||||||
stepResult, err = r.runStepRequest(copiedStep)
|
stepResult, err = r.runStepRequest(copiedStep)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("run request step failed")
|
log.Error().Err(err).Msg("run request step failed")
|
||||||
@@ -368,28 +369,29 @@ func (r *hrpRunner) runStepTestCase(step *TStep) (stepResult *stepData, err erro
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *hrpRunner) parseConfig(config *TConfig) error {
|
func (r *hrpRunner) parseConfig(config IConfig) error {
|
||||||
|
cfg := config.ToStruct()
|
||||||
// parse config variables
|
// parse config variables
|
||||||
parsedVariables, err := parseVariables(config.Variables)
|
parsedVariables, err := parseVariables(cfg.Variables)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Interface("variables", config.Variables).Err(err).Msg("parse config variables failed")
|
log.Error().Interface("variables", cfg.Variables).Err(err).Msg("parse config variables failed")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
config.Variables = parsedVariables
|
cfg.Variables = parsedVariables
|
||||||
|
|
||||||
// parse config name
|
// parse config name
|
||||||
parsedName, err := parseString(config.Name, config.Variables)
|
parsedName, err := parseString(cfg.Name, cfg.Variables)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
config.Name = convertString(parsedName)
|
cfg.Name = convertString(parsedName)
|
||||||
|
|
||||||
// parse config base url
|
// parse config base url
|
||||||
parsedBaseURL, err := parseString(config.BaseURL, config.Variables)
|
parsedBaseURL, err := parseString(cfg.BaseURL, cfg.Variables)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
config.BaseURL = convertString(parsedBaseURL)
|
cfg.BaseURL = convertString(parsedBaseURL)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
50
step.go
50
step.go
@@ -3,49 +3,65 @@ package hrp
|
|||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
// NewConfig returns a new constructed testcase config with specified testcase name.
|
// NewConfig returns a new constructed testcase config with specified testcase name.
|
||||||
func NewConfig(name string) *TConfig {
|
func NewConfig(name string) *Config {
|
||||||
return &TConfig{
|
return &Config{
|
||||||
Name: name,
|
cfg: &TConfig{
|
||||||
Variables: make(map[string]interface{}),
|
Name: name,
|
||||||
|
Variables: make(map[string]interface{}),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
cfg *TConfig
|
||||||
|
}
|
||||||
|
|
||||||
// WithVariables sets variables for current testcase.
|
// WithVariables sets variables for current testcase.
|
||||||
func (c *TConfig) WithVariables(variables map[string]interface{}) *TConfig {
|
func (c *Config) WithVariables(variables map[string]interface{}) *Config {
|
||||||
c.Variables = variables
|
c.cfg.Variables = variables
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetBaseURL sets base URL for current testcase.
|
// SetBaseURL sets base URL for current testcase.
|
||||||
func (c *TConfig) SetBaseURL(baseURL string) *TConfig {
|
func (c *Config) SetBaseURL(baseURL string) *Config {
|
||||||
c.BaseURL = baseURL
|
c.cfg.BaseURL = baseURL
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetVerifySSL sets whether to verify SSL for current testcase.
|
// SetVerifySSL sets whether to verify SSL for current testcase.
|
||||||
func (c *TConfig) SetVerifySSL(verify bool) *TConfig {
|
func (c *Config) SetVerifySSL(verify bool) *Config {
|
||||||
c.Verify = verify
|
c.cfg.Verify = verify
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithParameters sets parameters for current testcase.
|
// WithParameters sets parameters for current testcase.
|
||||||
func (c *TConfig) WithParameters(parameters map[string]interface{}) *TConfig {
|
func (c *Config) WithParameters(parameters map[string]interface{}) *Config {
|
||||||
c.Parameters = parameters
|
c.cfg.Parameters = parameters
|
||||||
return c
|
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 *Config) ExportVars(vars ...string) *Config {
|
||||||
c.Export = vars
|
c.cfg.Export = vars
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetWeight sets weight for current testcase, which is used in load testing.
|
// SetWeight sets weight for current testcase, which is used in load testing.
|
||||||
func (c *TConfig) SetWeight(weight int) *TConfig {
|
func (c *Config) SetWeight(weight int) *Config {
|
||||||
c.Weight = weight
|
c.cfg.Weight = weight
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name returns config name, this implements IConfig interface.
|
||||||
|
func (c *Config) Name() string {
|
||||||
|
return c.cfg.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToStruct returns *TConfig, this implements IConfig interface.
|
||||||
|
func (c *Config) ToStruct() *TConfig {
|
||||||
|
return c.cfg
|
||||||
|
}
|
||||||
|
|
||||||
// NewStep returns a new constructed teststep with specified step name.
|
// NewStep returns a new constructed teststep with specified step name.
|
||||||
func NewStep(name string) *TStep {
|
func NewStep(name string) *TStep {
|
||||||
return &TStep{
|
return &TStep{
|
||||||
@@ -267,7 +283,7 @@ func (s *stepTestCaseWithOptionalArgs) Name() string {
|
|||||||
if s.step.Name != "" {
|
if s.step.Name != "" {
|
||||||
return s.step.Name
|
return s.step.Name
|
||||||
}
|
}
|
||||||
return s.step.TestCase.Config.Name
|
return s.step.TestCase.Config.Name()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stepTestCaseWithOptionalArgs) Type() string {
|
func (s *stepTestCaseWithOptionalArgs) Type() string {
|
||||||
|
|||||||
Reference in New Issue
Block a user