refactor: update summary in controller

This commit is contained in:
debugtalk
2022-10-18 15:51:56 +08:00
parent c5f81f2593
commit 23abc56a82
12 changed files with 112 additions and 140 deletions

View File

@@ -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
View 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
}

View File

@@ -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) {

View File

@@ -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()
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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,

View File

@@ -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
}