From 5fba76e6e302e5b590b3f0f8ace044edf318aee7 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Wed, 31 Aug 2022 23:16:46 +0800 Subject: [PATCH] change: convert StepResult Attachments to interface, for screenshots saving --- examples/uitest/demo_weixin_test.go | 11 +++++--- hrp/boomer.go | 11 ++++---- hrp/step.go | 2 +- hrp/step_ios_ui.go | 43 +++++++++++++++++++++++------ hrp/step_request.go | 2 +- hrp/step_testcase.go | 2 +- hrp/step_websocket.go | 2 +- hrp/summary_test.go | 2 +- 8 files changed, 53 insertions(+), 22 deletions(-) diff --git a/examples/uitest/demo_weixin_test.go b/examples/uitest/demo_weixin_test.go index 26611ae7..70d2180a 100644 --- a/examples/uitest/demo_weixin_test.go +++ b/examples/uitest/demo_weixin_test.go @@ -31,13 +31,16 @@ func TestIOSWeixinLive(t *testing.T) { hrp.NewStep("向上滑动,等待 10s"). IOS(). SwipeUp().Sleep(10).ScreenShot(). // 上划 1 次,等待 10s,截图保存 - SwipeUp().Times(10).ScreenShot(), // 再上划 1 次,等待 10s,截图保存 + SwipeUp().Sleep(10).ScreenShot(), // 再上划 1 次,等待 10s,截图保存 }, } fmt.Println(testCase) - err := hrp.NewRunner(t).Run(testCase) - if err != nil { - t.Fatal(err) + runner := hrp.NewRunner(t) + sessionRunner, _ := runner.NewSessionRunner(testCase) + if err := sessionRunner.Start(nil); err != nil { + t.Fatal() } + summary := sessionRunner.GetSummary() + fmt.Println(summary) } diff --git a/hrp/boomer.go b/hrp/boomer.go index e8ea55fc..c7d56bb6 100644 --- a/hrp/boomer.go +++ b/hrp/boomer.go @@ -10,12 +10,13 @@ import ( "time" "github.com/httprunner/funplugin" + "github.com/rs/zerolog/log" + "golang.org/x/net/context" + "github.com/httprunner/httprunner/v4/hrp/internal/boomer" "github.com/httprunner/httprunner/v4/hrp/internal/builtin" "github.com/httprunner/httprunner/v4/hrp/internal/json" "github.com/httprunner/httprunner/v4/hrp/internal/sdk" - "github.com/rs/zerolog/log" - "golang.org/x/net/context" ) func NewStandaloneBoomer(spawnCount int64, spawnRate float64) *HRPBoomer { @@ -252,7 +253,6 @@ func (b *HRPBoomer) rebalanceRunner(profile *boomer.Profile) { log.Info().Interface("profile", profile).Msg("rebalance tasks successfully") } - func (b *HRPBoomer) PollTasks(ctx context.Context) { for { select { @@ -261,7 +261,7 @@ func (b *HRPBoomer) PollTasks(ctx context.Context) { if len(b.Boomer.GetTasksChan()) > 0 { continue } - //Todo: 过滤掉已经传输过的task + // Todo: 过滤掉已经传输过的task if task.TestCasesBytes != nil { // init boomer with profile b.initWorker(task.Profile) @@ -382,7 +382,8 @@ func (b *HRPBoomer) convertBoomerTask(testcase *TestCase, rendezvousList []*Rend if result.Success { b.RecordSuccess(string(result.StepType), result.Name, result.Elapsed, result.ContentSize) } else { - b.RecordFailure(string(result.StepType), result.Name, result.Elapsed, result.Attachment) + exception, _ := result.Attachments.(string) + b.RecordFailure(string(result.StepType), result.Name, result.Elapsed, exception) } } } diff --git a/hrp/step.go b/hrp/step.go index 34cdb879..8636d0c3 100644 --- a/hrp/step.go +++ b/hrp/step.go @@ -93,7 +93,7 @@ type StepResult struct { Data interface{} `json:"data,omitempty" yaml:"data,omitempty"` // session data or slice of step data ContentSize int64 `json:"content_size" yaml:"content_size"` // response body length ExportVars map[string]interface{} `json:"export_vars,omitempty" yaml:"export_vars,omitempty"` // extract variables - Attachment string `json:"attachment,omitempty" yaml:"attachment,omitempty"` // step error information + Attachments interface{} `json:"attachments,omitempty" yaml:"attachments,omitempty"` // store extra step information, such as error message or screenshots } // TStep represents teststep data structure. diff --git a/hrp/step_ios_ui.go b/hrp/step_ios_ui.go index 5f1126ed..ea6a0092 100644 --- a/hrp/step_ios_ui.go +++ b/hrp/step_ios_ui.go @@ -495,6 +495,7 @@ func runStepIOS(s *SessionRunner, step *TStep) (stepResult *StepResult, err erro Success: false, ContentSize: 0, } + screenshots := make([]string, 0) // init wdaClient driver wdaClient, err := s.hrpRunner.InitWDAClient(step.IOS.WDADevice) @@ -502,6 +503,29 @@ func runStepIOS(s *SessionRunner, step *TStep) (stepResult *StepResult, err erro return } + defer func() { + attachments := make(map[string]interface{}) + if err != nil { + attachments["error"] = err.Error() + } + + // save attachments + screenshots = append(screenshots, wdaClient.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 var actions []MobileAction if step.IOS.Actions == nil { @@ -523,11 +547,14 @@ func runStepIOS(s *SessionRunner, step *TStep) (stepResult *StepResult, err erro } // take snapshot - screenshotPath, err := wdaClient.DriverExt.ScreenShot(fmt.Sprintf("validate_%s", step.Name)) + screenshotPath, err := wdaClient.DriverExt.ScreenShot( + fmt.Sprintf("validate_%d", time.Now().Unix())) if err != nil { log.Warn().Err(err).Str("step", step.Name).Msg("take screenshot failed") + } else { + log.Info().Str("path", screenshotPath).Msg("take screenshot before validation") + screenshots = append(screenshots, screenshotPath) } - log.Info().Str("path", screenshotPath).Msg("take screenshot before validation") // validate validateResults, err := wdaClient.doValidation(step.Validators) @@ -545,6 +572,8 @@ var errActionNotImplemented = errors.New("UI action not implemented") type uiDriver struct { uixt.DriverExt + + screenShots []string // save screenshots path } func (ud *uiDriver) doAction(action MobileAction) error { @@ -684,14 +713,12 @@ func (ud *uiDriver) doAction(action MobileAction) error { case ctlScreenShot: // take snapshot log.Info().Msg("take snapshot for current screen") - var screenshotPath string - var err error - if param, ok := action.Params.(string); ok { - screenshotPath, err = ud.ScreenShot(fmt.Sprintf("screenshot_%s", param)) - } else { - screenshotPath, err = ud.ScreenShot(fmt.Sprintf("screenshot_%d", time.Now().Unix())) + screenshotPath, err := ud.ScreenShot(fmt.Sprintf("screenshot_%d", time.Now().Unix())) + if err != nil { + return errors.Wrap(err, "take screenshot failed") } log.Info().Str("path", screenshotPath).Msg("take screenshot") + ud.screenShots = append(ud.screenShots, screenshotPath) return err case ctlStartCamera: // start camera, alias for app_launch com.apple.camera diff --git a/hrp/step_request.go b/hrp/step_request.go index 48a70e4d..47a9a242 100644 --- a/hrp/step_request.go +++ b/hrp/step_request.go @@ -295,7 +295,7 @@ func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err defer func() { // update testcase summary if err != nil { - stepResult.Attachment = err.Error() + stepResult.Attachments = err.Error() } // update summary r.summary.Records = append(r.summary.Records, stepResult) diff --git a/hrp/step_testcase.go b/hrp/step_testcase.go index 09440e5a..0bcc1ae3 100644 --- a/hrp/step_testcase.go +++ b/hrp/step_testcase.go @@ -54,7 +54,7 @@ func (s *StepTestCaseWithOptionalArgs) Run(r *SessionRunner) (stepResult *StepRe defer func() { // update testcase summary if err != nil { - stepResult.Attachment = err.Error() + stepResult.Attachments = err.Error() } }() diff --git a/hrp/step_websocket.go b/hrp/step_websocket.go index 90feec2d..5da949f6 100644 --- a/hrp/step_websocket.go +++ b/hrp/step_websocket.go @@ -258,7 +258,7 @@ func runStepWebSocket(r *SessionRunner, step *TStep) (stepResult *StepResult, er defer func() { // update testcase summary if err != nil { - stepResult.Attachment = err.Error() + stepResult.Attachments = err.Error() } // update summary r.summary.Records = append(r.summary.Records, stepResult) diff --git a/hrp/summary_test.go b/hrp/summary_test.go index 32343e0e..034ded16 100644 --- a/hrp/summary_test.go +++ b/hrp/summary_test.go @@ -12,7 +12,7 @@ func TestGenHTMLReport(t *testing.T) { StepType: stepTypeRequest, Success: false, ContentSize: 0, - Attachment: "err", + Attachments: "err", } caseSummary1.Records = []*StepResult{stepResult1, stepResult2, nil} summary.appendCaseSummary(caseSummary1)