mirror of
https://github.com/httprunner/httprunner.git
synced 2026-09-07 08:27:35 +08:00
refactor: TestCase/IConfig models
This commit is contained in:
+10
-6
@@ -6,9 +6,12 @@ HttpRunner 以 `TestCase` 为核心,将任意测试场景抽象为有序步骤
|
|||||||
|
|
||||||
```go
|
```go
|
||||||
type TestCase struct {
|
type TestCase struct {
|
||||||
Config *TConfig `json:"config" yaml:"config"`
|
Config IConfig `json:"config" yaml:"config"`
|
||||||
Steps []*TStep `json:"teststeps" yaml:"teststeps"`
|
TestSteps []IStep `json:"teststeps" yaml:"teststeps"`
|
||||||
TestSteps []IStep `json:"-" yaml:"-"`
|
}
|
||||||
|
|
||||||
|
type IConfig interface {
|
||||||
|
Get() *TConfig
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -18,7 +21,7 @@ type TestCase struct {
|
|||||||
type IStep interface {
|
type IStep interface {
|
||||||
Name() string
|
Name() string
|
||||||
Type() StepType
|
Type() StepType
|
||||||
Struct() *TStep
|
Config() *StepConfig
|
||||||
Run(*SessionRunner) (*StepResult, error)
|
Run(*SessionRunner) (*StepResult, error)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -32,6 +35,7 @@ type IStep interface {
|
|||||||
- [transaction](step_transaction.go):事务机制,用于压测
|
- [transaction](step_transaction.go):事务机制,用于压测
|
||||||
- [rendezvous](step_rendezvous.go):集合点机制,用于压测
|
- [rendezvous](step_rendezvous.go):集合点机制,用于压测
|
||||||
- [mobile_UI](step_mobile_ui.go):移动端 UI 自动化
|
- [mobile_UI](step_mobile_ui.go):移动端 UI 自动化
|
||||||
|
- [shell](step_shell.go):执行 shell 命令
|
||||||
|
|
||||||
基于该机制,我们可以扩展支持新的协议类型,例如 HTTP2/WebSocket/RPC 等;同时也可以支持新的测试类型,例如 UI 自动化。甚至我们还可以在一个测试用例中混合调用多种不同的 Step 类型,例如实现 HTTP/RPC/UI 混合场景。
|
基于该机制,我们可以扩展支持新的协议类型,例如 HTTP2/WebSocket/RPC 等;同时也可以支持新的测试类型,例如 UI 自动化。甚至我们还可以在一个测试用例中混合调用多种不同的 Step 类型,例如实现 HTTP/RPC/UI 混合场景。
|
||||||
|
|
||||||
@@ -53,7 +57,7 @@ type HRPRunner struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *HRPRunner) Run(testcases ...ITestCase) error
|
func (r *HRPRunner) Run(testcases ...ITestCase) error
|
||||||
func (r *HRPRunner) NewCaseRunner(testcase TestCase) (*CaseRunner, error) {
|
func (r *HRPRunner) NewCaseRunner(testcase TestCase) (*CaseRunner, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
重点关注两个方法:
|
重点关注两个方法:
|
||||||
@@ -75,7 +79,7 @@ type CaseRunner struct {
|
|||||||
parametersIterator *ParametersIterator
|
parametersIterator *ParametersIterator
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *CaseRunner) NewSession() *SessionRunner {
|
func (r *CaseRunner) NewSession() *SessionRunner
|
||||||
```
|
```
|
||||||
|
|
||||||
重点关注一个方法:
|
重点关注一个方法:
|
||||||
|
|||||||
+14
-12
@@ -138,9 +138,10 @@ func (b *HRPBoomer) ParseTestCases(testCases []*TestCase) []*TestCase {
|
|||||||
log.Error().Err(err).Msg("failed to create runner")
|
log.Error().Err(err).Msg("failed to create runner")
|
||||||
os.Exit(code.GetErrorCode(err))
|
os.Exit(code.GetErrorCode(err))
|
||||||
}
|
}
|
||||||
caseRunner.Config.Parameters = caseRunner.parametersIterator.outParameters()
|
caseConfig := caseRunner.TestCase.Config.Get()
|
||||||
|
caseConfig.Parameters = caseRunner.parametersIterator.outParameters()
|
||||||
parsedTestCases = append(parsedTestCases, &TestCase{
|
parsedTestCases = append(parsedTestCases, &TestCase{
|
||||||
Config: caseRunner.Config,
|
Config: caseConfig,
|
||||||
TestSteps: caseRunner.TestSteps,
|
TestSteps: caseRunner.TestSteps,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -184,19 +185,20 @@ func (b *HRPBoomer) parseTCases(testCases []*TestCase) (testcases []ITestCase) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if tc.Config.PluginSetting != nil {
|
caseConfig := tc.Config.Get()
|
||||||
tc.Config.PluginSetting.Path = filepath.Join(tempDir, fmt.Sprintf("debugtalk.%s", tc.Config.PluginSetting.Type))
|
if caseConfig.PluginSetting != nil {
|
||||||
err = builtin.Bytes2File(tc.Config.PluginSetting.Content, tc.Config.PluginSetting.Path)
|
caseConfig.PluginSetting.Path = filepath.Join(tempDir, fmt.Sprintf("debugtalk.%s", caseConfig.PluginSetting.Type))
|
||||||
|
err = builtin.Bytes2File(caseConfig.PluginSetting.Content, caseConfig.PluginSetting.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("failed to save plugin file")
|
log.Error().Err(err).Msg("failed to save plugin file")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tc.Config.PluginSetting.Content = nil // remove the content in testcase
|
caseConfig.PluginSetting.Content = nil // remove the content in testcase
|
||||||
}
|
}
|
||||||
|
|
||||||
if tc.Config.Environs != nil {
|
if caseConfig.Environs != nil {
|
||||||
envContent := ""
|
envContent := ""
|
||||||
for k, v := range tc.Config.Environs {
|
for k, v := range caseConfig.Environs {
|
||||||
envContent += fmt.Sprintf("%s=%s\n", k, v)
|
envContent += fmt.Sprintf("%s=%s\n", k, v)
|
||||||
}
|
}
|
||||||
err = os.WriteFile(filepath.Join(tempDir, ".env"), []byte(envContent), 0o644)
|
err = os.WriteFile(filepath.Join(tempDir, ".env"), []byte(envContent), 0o644)
|
||||||
@@ -206,8 +208,8 @@ func (b *HRPBoomer) parseTCases(testCases []*TestCase) (testcases []ITestCase) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tc.Config.Path = filepath.Join(tempDir, "test-case.json")
|
caseConfig.Path = filepath.Join(tempDir, "test-case.json")
|
||||||
err = builtin.Dump2JSON(tc, tc.Config.Path)
|
err = builtin.Dump2JSON(tc, caseConfig.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("failed to dump testcases")
|
log.Error().Err(err).Msg("failed to dump testcases")
|
||||||
return
|
return
|
||||||
@@ -335,8 +337,8 @@ func (b *HRPBoomer) convertBoomerTask(testcase *TestCase, rendezvousList []*Rend
|
|||||||
mutex := sync.Mutex{}
|
mutex := sync.Mutex{}
|
||||||
|
|
||||||
return &boomer.Task{
|
return &boomer.Task{
|
||||||
Name: testcase.Config.Name,
|
Name: testcase.Config.Get().Name,
|
||||||
Weight: testcase.Config.Weight,
|
Weight: testcase.Config.Get().Weight,
|
||||||
Fn: func() {
|
Fn: func() {
|
||||||
testcaseSuccess := true // flag whole testcase result
|
testcaseSuccess := true // flag whole testcase result
|
||||||
transactionSuccess := true // flag current transaction result
|
transactionSuccess := true // flag current transaction result
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ import (
|
|||||||
"github.com/httprunner/httprunner/v4/hrp/pkg/uixt"
|
"github.com/httprunner/httprunner/v4/hrp/pkg/uixt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type IConfig interface {
|
||||||
|
Get() *TConfig
|
||||||
|
}
|
||||||
|
|
||||||
// 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) *TConfig {
|
||||||
return &TConfig{
|
return &TConfig{
|
||||||
@@ -39,6 +43,10 @@ type TConfig struct {
|
|||||||
PluginSetting *PluginConfig `json:"plugin,omitempty" yaml:"plugin,omitempty"` // plugin config
|
PluginSetting *PluginConfig `json:"plugin,omitempty" yaml:"plugin,omitempty"` // plugin config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *TConfig) Get() *TConfig {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
// WithVariables sets variables for current testcase.
|
// WithVariables sets variables for current testcase.
|
||||||
func (c *TConfig) WithVariables(variables map[string]interface{}) *TConfig {
|
func (c *TConfig) WithVariables(variables map[string]interface{}) *TConfig {
|
||||||
c.Variables = variables
|
c.Variables = variables
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
v5.0.0+2411092015
|
v5.0.0+2411092105
|
||||||
|
|||||||
+23
-20
@@ -282,9 +282,10 @@ func (r *HRPRunner) NewCaseRunner(testcase TestCase) (*CaseRunner, error) {
|
|||||||
hrpRunner: r,
|
hrpRunner: r,
|
||||||
parser: newParser(),
|
parser: newParser(),
|
||||||
}
|
}
|
||||||
|
config := testcase.Config.Get()
|
||||||
|
|
||||||
// init parser plugin
|
// init parser plugin
|
||||||
plugin, err := initPlugin(testcase.Config.Path, r.venv, r.pluginLogOn)
|
plugin, err := initPlugin(config.Path, r.venv, r.pluginLogOn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "init plugin failed")
|
return nil, errors.Wrap(err, "init plugin failed")
|
||||||
}
|
}
|
||||||
@@ -297,27 +298,26 @@ func (r *HRPRunner) NewCaseRunner(testcase TestCase) (*CaseRunner, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "parse testcase config failed")
|
return nil, errors.Wrap(err, "parse testcase config failed")
|
||||||
}
|
}
|
||||||
caseRunner.TestCase.Config = parsedConfig
|
|
||||||
|
|
||||||
// set request timeout in seconds
|
// set request timeout in seconds
|
||||||
if testcase.Config.RequestTimeout != 0 {
|
if config.RequestTimeout != 0 {
|
||||||
r.SetRequestTimeout(testcase.Config.RequestTimeout)
|
r.SetRequestTimeout(config.RequestTimeout)
|
||||||
}
|
}
|
||||||
// set testcase timeout in seconds
|
// set testcase timeout in seconds
|
||||||
if testcase.Config.CaseTimeout != 0 {
|
if config.CaseTimeout != 0 {
|
||||||
r.SetCaseTimeout(testcase.Config.CaseTimeout)
|
r.SetCaseTimeout(config.CaseTimeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
// load plugin info to testcase config
|
// load plugin info to testcase config
|
||||||
if plugin != nil {
|
if plugin != nil {
|
||||||
pluginPath, _ := locatePlugin(testcase.Config.Path)
|
pluginPath, _ := locatePlugin(config.Path)
|
||||||
if caseRunner.Config.PluginSetting == nil {
|
if parsedConfig.PluginSetting == nil {
|
||||||
pluginContent, err := readFile(pluginPath)
|
pluginContent, err := readFile(pluginPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
tp := strings.Split(plugin.Path(), ".")
|
tp := strings.Split(plugin.Path(), ".")
|
||||||
caseRunner.Config.PluginSetting = &PluginConfig{
|
parsedConfig.PluginSetting = &PluginConfig{
|
||||||
Path: pluginPath,
|
Path: pluginPath,
|
||||||
Content: pluginContent,
|
Content: pluginContent,
|
||||||
Type: tp[len(tp)-1],
|
Type: tp[len(tp)-1],
|
||||||
@@ -325,6 +325,7 @@ func (r *HRPRunner) NewCaseRunner(testcase TestCase) (*CaseRunner, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
caseRunner.TestCase.Config = parsedConfig
|
||||||
return caseRunner, nil
|
return caseRunner, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,7 +340,7 @@ type CaseRunner struct {
|
|||||||
|
|
||||||
// parseConfig parses testcase config, stores to parsedConfig.
|
// parseConfig parses testcase config, stores to parsedConfig.
|
||||||
func (r *CaseRunner) parseConfig() (parsedConfig *TConfig, err error) {
|
func (r *CaseRunner) parseConfig() (parsedConfig *TConfig, err error) {
|
||||||
cfg := r.TestCase.Config
|
cfg := r.TestCase.Config.Get()
|
||||||
|
|
||||||
parsedConfig = &TConfig{}
|
parsedConfig = &TConfig{}
|
||||||
// deep copy config to avoid data racing
|
// deep copy config to avoid data racing
|
||||||
@@ -541,7 +542,7 @@ func (r *SessionRunner) Start(givenVars map[string]interface{}) (summary *TestCa
|
|||||||
// report GA event
|
// report GA event
|
||||||
sdk.SendGA4Event("hrp_session_runner_start", nil)
|
sdk.SendGA4Event("hrp_session_runner_start", nil)
|
||||||
|
|
||||||
config := r.caseRunner.Config
|
config := r.caseRunner.TestCase.Config.Get()
|
||||||
log.Info().Str("testcase", config.Name).Msg("run testcase start")
|
log.Info().Str("testcase", config.Name).Msg("run testcase start")
|
||||||
|
|
||||||
// update config variables with given variables
|
// update config variables with given variables
|
||||||
@@ -552,14 +553,14 @@ func (r *SessionRunner) Start(givenVars map[string]interface{}) (summary *TestCa
|
|||||||
r.releaseResources()
|
r.releaseResources()
|
||||||
|
|
||||||
summary = r.summary
|
summary = r.summary
|
||||||
summary.Name = r.caseRunner.Config.Name
|
summary.Name = config.Name
|
||||||
summary.Time.Duration = time.Since(summary.Time.StartAt).Seconds()
|
summary.Time.Duration = time.Since(summary.Time.StartAt).Seconds()
|
||||||
exportVars := make(map[string]interface{})
|
exportVars := make(map[string]interface{})
|
||||||
for _, value := range r.caseRunner.Config.Export {
|
for _, value := range config.Export {
|
||||||
exportVars[value] = r.sessionVariables[value]
|
exportVars[value] = r.sessionVariables[value]
|
||||||
}
|
}
|
||||||
summary.InOut.ExportVars = exportVars
|
summary.InOut.ExportVars = exportVars
|
||||||
summary.InOut.ConfigVars = r.caseRunner.Config.Variables
|
summary.InOut.ConfigVars = config.Variables
|
||||||
|
|
||||||
// TODO: move to mobile ui step
|
// TODO: move to mobile ui step
|
||||||
for uuid, client := range uiClients {
|
for uuid, client := range uiClients {
|
||||||
@@ -682,18 +683,19 @@ func (r *SessionRunner) Start(givenVars map[string]interface{}) (summary *TestCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *SessionRunner) parseStep(step IStep) error {
|
func (r *SessionRunner) parseStep(step IStep) error {
|
||||||
|
caseConfig := r.caseRunner.TestCase.Config.Get()
|
||||||
stepConfig := step.Config()
|
stepConfig := step.Config()
|
||||||
|
|
||||||
// update step variables: merges step variables with config variables and session variables
|
// update step variables: merges step variables with config variables and session variables
|
||||||
// variables priority: step variables > session variables (extracted variables from previous steps)
|
// variables priority: step variables > session variables (extracted variables from previous steps)
|
||||||
overrideVars := mergeVariables(stepConfig.Variables, r.sessionVariables)
|
overrideVars := mergeVariables(stepConfig.Variables, r.sessionVariables)
|
||||||
// step variables > testcase config variables
|
// step variables > testcase config variables
|
||||||
overrideVars = mergeVariables(overrideVars, r.caseRunner.Config.Variables)
|
overrideVars = mergeVariables(overrideVars, caseConfig.Variables)
|
||||||
|
|
||||||
// parse step variables
|
// parse step variables
|
||||||
parsedVariables, err := r.caseRunner.parser.ParseVariables(overrideVars)
|
parsedVariables, err := r.caseRunner.parser.ParseVariables(overrideVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Interface("variables", r.caseRunner.Config.Variables).
|
log.Error().Interface("variables", caseConfig.Variables).
|
||||||
Err(err).Msg("parse step variables failed")
|
Err(err).Msg("parse step variables failed")
|
||||||
return errors.Wrap(err, "parse step variables failed")
|
return errors.Wrap(err, "parse step variables failed")
|
||||||
}
|
}
|
||||||
@@ -750,11 +752,12 @@ func (r *SessionRunner) initWithParameters(parameters map[string]interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *SessionRunner) IgnorePopup() bool {
|
func (r *SessionRunner) IgnorePopup() bool {
|
||||||
if r.caseRunner.TestCase.Config.Android != nil {
|
caseConfig := r.caseRunner.TestCase.Config.Get()
|
||||||
return r.caseRunner.TestCase.Config.Android[0].IgnorePopup
|
if caseConfig.Android != nil {
|
||||||
|
return caseConfig.Android[0].IgnorePopup
|
||||||
}
|
}
|
||||||
if r.caseRunner.TestCase.Config.IOS != nil {
|
if caseConfig.IOS != nil {
|
||||||
return r.caseRunner.TestCase.Config.IOS[0].IgnorePopup
|
return caseConfig.IOS[0].IgnorePopup
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -299,7 +299,7 @@ func runStepRequest(r *SessionRunner, step IStep) (stepResult *StepResult, err e
|
|||||||
|
|
||||||
sessionData := newSessionData()
|
sessionData := newSessionData()
|
||||||
parser := r.caseRunner.parser
|
parser := r.caseRunner.parser
|
||||||
config := r.caseRunner.Config
|
config := r.caseRunner.Config.Get()
|
||||||
|
|
||||||
rb := newRequestBuilder(parser, config, stepRequest.Request)
|
rb := newRequestBuilder(parser, config, stepRequest.Request)
|
||||||
rb.req.Method = strings.ToUpper(string(stepRequest.Request.Method))
|
rb.req.Method = strings.ToUpper(string(stepRequest.Request.Method))
|
||||||
|
|||||||
+1
-1
@@ -103,7 +103,7 @@ func runStepShell(r *SessionRunner, step IStep) (stepResult *StepResult, err err
|
|||||||
ContentSize: 0,
|
ContentSize: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
vars := r.caseRunner.Config.Variables
|
vars := r.caseRunner.Config.Get().Variables
|
||||||
for key, value := range vars {
|
for key, value := range vars {
|
||||||
os.Setenv(key, fmt.Sprintf("%v", value))
|
os.Setenv(key, fmt.Sprintf("%v", value))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ func (s *StepTestCaseWithOptionalArgs) Name() string {
|
|||||||
}
|
}
|
||||||
ts, ok := s.TestCase.(*TestCase)
|
ts, ok := s.TestCase.(*TestCase)
|
||||||
if ok {
|
if ok {
|
||||||
return ts.Config.Name
|
return ts.Config.Get().Name
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@@ -68,13 +68,14 @@ func (s *StepTestCaseWithOptionalArgs) Run(r *SessionRunner) (stepResult *StepRe
|
|||||||
return stepResult, err
|
return stepResult, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config := copiedTestCase.Config.Get()
|
||||||
// override testcase config
|
// override testcase config
|
||||||
// override testcase name
|
// override testcase name
|
||||||
if s.StepName != "" {
|
if s.StepName != "" {
|
||||||
copiedTestCase.Config.Name = s.StepName
|
config.Name = s.StepName
|
||||||
}
|
}
|
||||||
// merge & override extractors
|
// merge & override extractors
|
||||||
copiedTestCase.Config.Export = mergeSlices(s.StepExport, copiedTestCase.Config.Export)
|
config.Export = mergeSlices(s.StepExport, config.Export)
|
||||||
|
|
||||||
caseRunner, err := r.caseRunner.hrpRunner.NewCaseRunner(*copiedTestCase)
|
caseRunner, err := r.caseRunner.hrpRunner.NewCaseRunner(*copiedTestCase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ func (s *StepThinkTime) Run(r *SessionRunner) (*StepResult, error) {
|
|||||||
Success: true,
|
Success: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg := r.caseRunner.Config.ThinkTimeSetting
|
cfg := r.caseRunner.Config.Get().ThinkTimeSetting
|
||||||
if cfg == nil {
|
if cfg == nil {
|
||||||
cfg = &ThinkTimeConfig{thinkTimeDefault, nil, 0}
|
cfg = &ThinkTimeConfig{thinkTimeDefault, nil, 0}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -289,7 +289,7 @@ func runStepWebSocket(r *SessionRunner, step IStep) (stepResult *StepResult, err
|
|||||||
|
|
||||||
sessionData := newSessionData()
|
sessionData := newSessionData()
|
||||||
parser := r.caseRunner.parser
|
parser := r.caseRunner.parser
|
||||||
config := r.caseRunner.Config
|
config := r.caseRunner.Config.Get()
|
||||||
|
|
||||||
dummyReq := &Request{
|
dummyReq := &Request{
|
||||||
URL: webSocket.URL,
|
URL: webSocket.URL,
|
||||||
@@ -706,7 +706,7 @@ func (r *SessionRunner) releaseResources() {
|
|||||||
// close websocket connections
|
// close websocket connections
|
||||||
for _, wsConn := range r.ws.wsConnMap {
|
for _, wsConn := range r.ws.wsConnMap {
|
||||||
if wsConn != nil {
|
if wsConn != nil {
|
||||||
log.Info().Str("testcase", r.caseRunner.Config.Name).Msg("websocket disconnected")
|
log.Info().Str("testcase", r.caseRunner.Config.Get().Name).Msg("websocket disconnected")
|
||||||
err := wsConn.Close()
|
err := wsConn.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("websocket disconnection failed")
|
log.Error().Err(err).Msg("websocket disconnection failed")
|
||||||
|
|||||||
+6
-5
@@ -46,8 +46,8 @@ func (path *TestCasePath) GetTestCase() (*TestCase, error) {
|
|||||||
// TestCase is a container for one testcase, which is used for testcase runner.
|
// TestCase is a container for one testcase, which is used for testcase runner.
|
||||||
// TestCase implements ITestCase interface.
|
// TestCase implements ITestCase interface.
|
||||||
type TestCase struct {
|
type TestCase struct {
|
||||||
Config *TConfig `json:"config" yaml:"config"`
|
Config IConfig `json:"config" yaml:"config"`
|
||||||
TestSteps []IStep `json:"teststeps" yaml:"teststeps"`
|
TestSteps []IStep `json:"teststeps" yaml:"teststeps"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tc *TestCase) GetTestCase() (*TestCase, error) {
|
func (tc *TestCase) GetTestCase() (*TestCase, error) {
|
||||||
@@ -126,13 +126,14 @@ func (tc *TestCaseDef) loadISteps() (*TestCase, error) {
|
|||||||
return nil, errors.Wrap(err, "failed to load .env file")
|
return nil, errors.Wrap(err, "failed to load .env file")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config := testCase.Config.Get()
|
||||||
// override testcase config env with variables loaded from .env file
|
// override testcase config env with variables loaded from .env file
|
||||||
// priority: .env file > testcase config env
|
// priority: .env file > testcase config env
|
||||||
if testCase.Config.Environs == nil {
|
if config.Environs == nil {
|
||||||
testCase.Config.Environs = make(map[string]string)
|
config.Environs = make(map[string]string)
|
||||||
}
|
}
|
||||||
for key, value := range envVars {
|
for key, value := range envVars {
|
||||||
testCase.Config.Environs[key] = value
|
config.Environs[key] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user