mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-10 17:43:00 +08:00
change: convert StepResult Attachments to interface, for screenshots saving
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user