mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-10 17:43:00 +08:00
refactor: update summary in controller
This commit is contained in:
@@ -6,8 +6,8 @@ import (
|
||||
|
||||
// general: [0, 20)
|
||||
const (
|
||||
SUCCESS = 0
|
||||
FAIL = 1
|
||||
Success = 0
|
||||
GeneralFail = 1
|
||||
)
|
||||
|
||||
// loader: [20, 40)
|
||||
@@ -64,7 +64,7 @@ var errorsMap = map[error]int{
|
||||
|
||||
func GetErrorCode(err error) int {
|
||||
if err == nil {
|
||||
return SUCCESS
|
||||
return Success
|
||||
}
|
||||
|
||||
e := errors.Cause(err)
|
||||
@@ -72,5 +72,5 @@ func GetErrorCode(err error) int {
|
||||
return code
|
||||
}
|
||||
|
||||
return FAIL
|
||||
return GeneralFail
|
||||
}
|
||||
|
||||
69
hrp/loader.go
Normal file
69
hrp/loader.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package hrp
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
func LoadTestCases(iTestCases ...ITestCase) ([]*TestCase, error) {
|
||||
testCases := make([]*TestCase, 0)
|
||||
|
||||
for _, iTestCase := range iTestCases {
|
||||
if _, ok := iTestCase.(*TestCase); ok {
|
||||
testcase, err := iTestCase.ToTestCase()
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to convert ITestCase interface to TestCase struct")
|
||||
return nil, err
|
||||
}
|
||||
testCases = append(testCases, testcase)
|
||||
continue
|
||||
}
|
||||
|
||||
// iTestCase should be a TestCasePath, file path or folder path
|
||||
tcPath, ok := iTestCase.(*TestCasePath)
|
||||
if !ok {
|
||||
return nil, errors.New("invalid iTestCase type")
|
||||
}
|
||||
|
||||
casePath := tcPath.GetPath()
|
||||
err := fs.WalkDir(os.DirFS(casePath), ".", func(path string, dir fs.DirEntry, e error) error {
|
||||
if dir == nil {
|
||||
// casePath is a file other than a dir
|
||||
path = casePath
|
||||
} else if dir.IsDir() && path != "." && strings.HasPrefix(path, ".") {
|
||||
// skip hidden folders
|
||||
return fs.SkipDir
|
||||
} else {
|
||||
// casePath is a dir
|
||||
path = filepath.Join(casePath, path)
|
||||
}
|
||||
|
||||
// ignore non-testcase files
|
||||
ext := filepath.Ext(path)
|
||||
if ext != ".yml" && ext != ".yaml" && ext != ".json" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// filtered testcases
|
||||
testCasePath := TestCasePath(path)
|
||||
tc, err := testCasePath.ToTestCase()
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Str("path", path).Msg("load testcase failed")
|
||||
return nil
|
||||
}
|
||||
testCases = append(testCases, tc)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "read dir failed")
|
||||
}
|
||||
}
|
||||
|
||||
log.Info().Int("count", len(testCases)).Msg("load testcases successfully")
|
||||
return testCases, nil
|
||||
}
|
||||
@@ -190,7 +190,7 @@ func (p *Parser) ParseString(raw string, variablesMapping map[string]interface{}
|
||||
return raw, err
|
||||
}
|
||||
|
||||
result, err := p.CallFunc(funcName, parsedArgs.([]interface{})...)
|
||||
result, err := p.callFunc(funcName, parsedArgs.([]interface{})...)
|
||||
if err != nil {
|
||||
log.Error().Str("funcName", funcName).Interface("arguments", arguments).
|
||||
Err(err).Msg("call function failed")
|
||||
@@ -251,9 +251,9 @@ func (p *Parser) ParseString(raw string, variablesMapping map[string]interface{}
|
||||
return parsedString, nil
|
||||
}
|
||||
|
||||
// CallFunc calls function with arguments
|
||||
// callFunc calls function with arguments
|
||||
// only support return at most one result value
|
||||
func (p *Parser) CallFunc(funcName string, arguments ...interface{}) (interface{}, error) {
|
||||
func (p *Parser) callFunc(funcName string, arguments ...interface{}) (interface{}, error) {
|
||||
// call with plugin function
|
||||
if p.plugin != nil {
|
||||
if p.plugin.Has(funcName) {
|
||||
|
||||
@@ -478,14 +478,14 @@ func TestCallBuiltinFunction(t *testing.T) {
|
||||
parser := newParser()
|
||||
|
||||
// call function without arguments
|
||||
_, err := parser.CallFunc("get_timestamp")
|
||||
_, err := parser.callFunc("get_timestamp")
|
||||
if !assert.NoError(t, err) {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
// call function with one argument
|
||||
timeStart := time.Now()
|
||||
_, err = parser.CallFunc("sleep", 1)
|
||||
_, err = parser.callFunc("sleep", 1)
|
||||
if !assert.NoError(t, err) {
|
||||
t.Fatal()
|
||||
}
|
||||
@@ -494,7 +494,7 @@ func TestCallBuiltinFunction(t *testing.T) {
|
||||
}
|
||||
|
||||
// call function with one argument
|
||||
result, err := parser.CallFunc("gen_random_string", 10)
|
||||
result, err := parser.callFunc("gen_random_string", 10)
|
||||
if !assert.NoError(t, err) {
|
||||
t.Fatal()
|
||||
}
|
||||
@@ -503,7 +503,7 @@ func TestCallBuiltinFunction(t *testing.T) {
|
||||
}
|
||||
|
||||
// call function with two argument
|
||||
result, err = parser.CallFunc("max", float64(10), 9.99)
|
||||
result, err = parser.callFunc("max", float64(10), 9.99)
|
||||
if !assert.NoError(t, err) {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
@@ -317,9 +317,10 @@ func (r *HRPRunner) newCaseRunner(testcase *TestCase) (*testCaseRunner, error) {
|
||||
}
|
||||
|
||||
type testCaseRunner struct {
|
||||
testCase *TestCase
|
||||
hrpRunner *HRPRunner
|
||||
parser *Parser
|
||||
testCase *TestCase
|
||||
hrpRunner *HRPRunner
|
||||
parser *Parser
|
||||
|
||||
parsedConfig *TConfig
|
||||
parametersIterator *ParametersIterator
|
||||
rootDir string // project root dir
|
||||
|
||||
@@ -35,14 +35,6 @@ func (r *SessionRunner) resetSession() {
|
||||
r.closeResponseChan = make(chan *wsCloseRespObject, 1)
|
||||
}
|
||||
|
||||
func (r *SessionRunner) GetParser() *Parser {
|
||||
return r.parser
|
||||
}
|
||||
|
||||
func (r *SessionRunner) GetConfig() *TConfig {
|
||||
return r.parsedConfig
|
||||
}
|
||||
|
||||
func (r *SessionRunner) HTTPStatOn() bool {
|
||||
return r.hrpRunner.httpStatOn
|
||||
}
|
||||
@@ -74,31 +66,41 @@ func (r *SessionRunner) Start(givenVars map[string]interface{}) error {
|
||||
log.Info().Str("step", stepName).
|
||||
Str("type", string(step.Type())).Msg("run step start")
|
||||
|
||||
// run step
|
||||
stepResult, err := step.Run(r)
|
||||
stepResult.Name = stepName
|
||||
if err != nil {
|
||||
|
||||
// update summary
|
||||
r.summary.Records = append(r.summary.Records, stepResult)
|
||||
r.summary.Stat.Total += 1
|
||||
if stepResult.Success {
|
||||
r.summary.Stat.Successes += 1
|
||||
log.Info().
|
||||
Str("step", stepResult.Name).
|
||||
Str("type", string(stepResult.StepType)).
|
||||
Bool("success", true).
|
||||
Interface("exportVars", stepResult.ExportVars).
|
||||
Msg("run step end")
|
||||
} else {
|
||||
r.summary.Stat.Failures += 1
|
||||
// update summary result to failed
|
||||
r.summary.Success = false
|
||||
log.Error().
|
||||
Str("step", stepResult.Name).
|
||||
Str("type", string(stepResult.StepType)).
|
||||
Bool("success", false).
|
||||
Msg("run step end")
|
||||
}
|
||||
|
||||
if r.hrpRunner.failfast {
|
||||
return errors.Wrap(err, "abort running due to failfast setting")
|
||||
}
|
||||
// check if failfast
|
||||
if err != nil && r.hrpRunner.failfast {
|
||||
return errors.Wrap(err, "abort running due to failfast setting")
|
||||
}
|
||||
|
||||
// update extracted variables
|
||||
for k, v := range stepResult.ExportVars {
|
||||
r.sessionVariables[k] = v
|
||||
}
|
||||
|
||||
log.Info().
|
||||
Str("step", stepResult.Name).
|
||||
Str("type", string(stepResult.StepType)).
|
||||
Bool("success", stepResult.Success).
|
||||
Interface("exportVars", stepResult.ExportVars).
|
||||
Msg("run step end")
|
||||
}
|
||||
|
||||
// close websocket connection after all steps done
|
||||
|
||||
@@ -100,9 +100,6 @@ func (s *StepAPIWithOptionalArgs) Struct() *TStep {
|
||||
|
||||
func (s *StepAPIWithOptionalArgs) Run(r *SessionRunner) (stepResult *StepResult, err error) {
|
||||
defer func() {
|
||||
if err != nil {
|
||||
r.summary.Success = false
|
||||
}
|
||||
stepResult.StepType = stepTypeAPI
|
||||
}()
|
||||
// extend request with referenced API
|
||||
|
||||
@@ -4,9 +4,10 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/httprunner/httprunner/v4/hrp/pkg/uixt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"github.com/httprunner/httprunner/v4/hrp/pkg/uixt"
|
||||
)
|
||||
|
||||
// ios setting options
|
||||
@@ -559,7 +560,6 @@ func runStepMobileUI(s *SessionRunner, step *TStep) (stepResult *StepResult, err
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
parser := s.GetParser()
|
||||
|
||||
var osType string
|
||||
var mobileStep *MobileStep
|
||||
@@ -590,17 +590,6 @@ func runStepMobileUI(s *SessionRunner, step *TStep) (stepResult *StepResult, err
|
||||
screenshots = append(screenshots, uiDriver.ScreenShots...)
|
||||
attachments["screenshots"] = screenshots
|
||||
stepResult.Attachments = attachments
|
||||
|
||||
// update summary
|
||||
s.summary.Records = append(s.summary.Records, stepResult)
|
||||
s.summary.Stat.Total += 1
|
||||
if stepResult.Success {
|
||||
s.summary.Stat.Successes += 1
|
||||
} else {
|
||||
s.summary.Stat.Failures += 1
|
||||
// update summary result to failed
|
||||
s.summary.Success = false
|
||||
}
|
||||
}()
|
||||
|
||||
// prepare actions
|
||||
@@ -618,7 +607,7 @@ func runStepMobileUI(s *SessionRunner, step *TStep) (stepResult *StepResult, err
|
||||
|
||||
// run actions
|
||||
for _, action := range actions {
|
||||
if action.Params, err = parser.Parse(action.Params, stepVariables); err != nil {
|
||||
if action.Params, err = s.parser.Parse(action.Params, stepVariables); err != nil {
|
||||
return stepResult, errors.Wrap(err, "parse action params failed")
|
||||
}
|
||||
if err := uiDriver.DoAction(action); err != nil {
|
||||
|
||||
@@ -297,16 +297,6 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err
|
||||
if err != nil {
|
||||
stepResult.Attachments = err.Error()
|
||||
}
|
||||
// update summary
|
||||
r.summary.Records = append(r.summary.Records, stepResult)
|
||||
r.summary.Stat.Total += 1
|
||||
if stepResult.Success {
|
||||
r.summary.Stat.Successes += 1
|
||||
} else {
|
||||
r.summary.Stat.Failures += 1
|
||||
// update summary result to failed
|
||||
r.summary.Success = false
|
||||
}
|
||||
}()
|
||||
|
||||
// override step variables
|
||||
@@ -321,8 +311,8 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err
|
||||
}
|
||||
|
||||
sessionData := newSessionData()
|
||||
parser := r.GetParser()
|
||||
config := r.GetConfig()
|
||||
parser := r.parser
|
||||
config := r.parsedConfig
|
||||
|
||||
rb := newRequestBuilder(parser, config, step.Request)
|
||||
rb.req.Method = string(step.Request.Method)
|
||||
|
||||
@@ -109,12 +109,6 @@ func (s *StepTestCaseWithOptionalArgs) Run(r *SessionRunner) (stepResult *StepRe
|
||||
// export testcase export variables
|
||||
stepResult.ExportVars = summary.InOut.ExportVars
|
||||
|
||||
// merge testcase summary
|
||||
r.summary.Records = append(r.summary.Records, summary.Records...)
|
||||
r.summary.Stat.Total += summary.Stat.Total
|
||||
r.summary.Stat.Successes += summary.Stat.Successes
|
||||
r.summary.Stat.Failures += summary.Stat.Failures
|
||||
|
||||
if err == nil {
|
||||
stepResult.Success = true
|
||||
}
|
||||
|
||||
@@ -260,16 +260,6 @@ func runStepWebSocket(r *SessionRunner, step *TStep) (stepResult *StepResult, er
|
||||
if err != nil {
|
||||
stepResult.Attachments = err.Error()
|
||||
}
|
||||
// update summary
|
||||
r.summary.Records = append(r.summary.Records, stepResult)
|
||||
r.summary.Stat.Total += 1
|
||||
if stepResult.Success {
|
||||
r.summary.Stat.Successes += 1
|
||||
} else {
|
||||
r.summary.Stat.Failures += 1
|
||||
// update summary result to failed
|
||||
r.summary.Success = false
|
||||
}
|
||||
}()
|
||||
|
||||
// override step variables
|
||||
@@ -279,8 +269,8 @@ func runStepWebSocket(r *SessionRunner, step *TStep) (stepResult *StepResult, er
|
||||
}
|
||||
|
||||
sessionData := newSessionData()
|
||||
parser := r.GetParser()
|
||||
config := r.GetConfig()
|
||||
parser := r.parser
|
||||
config := r.parsedConfig
|
||||
|
||||
dummyReq := &Request{
|
||||
URL: step.WebSocket.URL,
|
||||
|
||||
@@ -2,8 +2,6 @@ package hrp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@@ -359,61 +357,3 @@ func convertJmespathExpr(checkExpr string) string {
|
||||
}
|
||||
return strings.Join(checkItems, ".")
|
||||
}
|
||||
|
||||
func LoadTestCases(iTestCases ...ITestCase) ([]*TestCase, error) {
|
||||
testCases := make([]*TestCase, 0)
|
||||
|
||||
for _, iTestCase := range iTestCases {
|
||||
if _, ok := iTestCase.(*TestCase); ok {
|
||||
testcase, err := iTestCase.ToTestCase()
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to convert ITestCase interface to TestCase struct")
|
||||
return nil, err
|
||||
}
|
||||
testCases = append(testCases, testcase)
|
||||
continue
|
||||
}
|
||||
|
||||
// iTestCase should be a TestCasePath, file path or folder path
|
||||
tcPath, ok := iTestCase.(*TestCasePath)
|
||||
if !ok {
|
||||
return nil, errors.New("invalid iTestCase type")
|
||||
}
|
||||
|
||||
casePath := tcPath.GetPath()
|
||||
err := fs.WalkDir(os.DirFS(casePath), ".", func(path string, dir fs.DirEntry, e error) error {
|
||||
if dir == nil {
|
||||
// casePath is a file other than a dir
|
||||
path = casePath
|
||||
} else if dir.IsDir() && path != "." && strings.HasPrefix(path, ".") {
|
||||
// skip hidden folders
|
||||
return fs.SkipDir
|
||||
} else {
|
||||
// casePath is a dir
|
||||
path = filepath.Join(casePath, path)
|
||||
}
|
||||
|
||||
// ignore non-testcase files
|
||||
ext := filepath.Ext(path)
|
||||
if ext != ".yml" && ext != ".yaml" && ext != ".json" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// filtered testcases
|
||||
testCasePath := TestCasePath(path)
|
||||
tc, err := testCasePath.ToTestCase()
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Str("path", path).Msg("load testcase failed")
|
||||
return nil
|
||||
}
|
||||
testCases = append(testCases, tc)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "read dir failed")
|
||||
}
|
||||
}
|
||||
|
||||
log.Info().Int("count", len(testCases)).Msg("load testcases successfully")
|
||||
return testCases, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user