mirror of
https://github.com/httprunner/httprunner.git
synced 2026-07-08 22:13:13 +08:00
feat: integrage ios performance monitor
This commit is contained in:
@@ -6,6 +6,10 @@
|
|||||||
},
|
},
|
||||||
"ios": [
|
"ios": [
|
||||||
{
|
{
|
||||||
|
"perf_options": {
|
||||||
|
"sys_cpu": true,
|
||||||
|
"sys_mem": true
|
||||||
|
},
|
||||||
"port": 8700,
|
"port": 8700,
|
||||||
"mjpeg_port": 8800,
|
"mjpeg_port": 8800,
|
||||||
"log_on": true
|
"log_on": true
|
||||||
|
|||||||
@@ -3,7 +3,10 @@ config:
|
|||||||
variables:
|
variables:
|
||||||
app_name: 抖音
|
app_name: 抖音
|
||||||
ios:
|
ios:
|
||||||
- port: 8700
|
- perf_options:
|
||||||
|
sys_cpu: true
|
||||||
|
sys_mem: true
|
||||||
|
port: 8700
|
||||||
mjpeg_port: 8800
|
mjpeg_port: 8800
|
||||||
log_on: true
|
log_on: true
|
||||||
teststeps:
|
teststeps:
|
||||||
|
|||||||
@@ -14,7 +14,15 @@ func TestIOSDouyinLive(t *testing.T) {
|
|||||||
WithVariables(map[string]interface{}{
|
WithVariables(map[string]interface{}{
|
||||||
"app_name": "抖音",
|
"app_name": "抖音",
|
||||||
}).
|
}).
|
||||||
SetIOS(hrp.WithLogOn(true), hrp.WithWDAPort(8700), hrp.WithWDAMjpegPort(8800)),
|
SetIOS(
|
||||||
|
hrp.WithLogOn(true),
|
||||||
|
hrp.WithWDAPort(8700),
|
||||||
|
hrp.WithWDAMjpegPort(8800),
|
||||||
|
hrp.WithPerfOptions(
|
||||||
|
hrp.WithPerfSystemCPU(true),
|
||||||
|
hrp.WithPerfSystemMem(true),
|
||||||
|
),
|
||||||
|
),
|
||||||
TestSteps: []hrp.IStep{
|
TestSteps: []hrp.IStep{
|
||||||
hrp.NewStep("启动抖音").
|
hrp.NewStep("启动抖音").
|
||||||
IOS().
|
IOS().
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -88,4 +88,4 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// replace github.com/httprunner/funplugin => ../funplugin
|
// replace github.com/httprunner/funplugin => ../funplugin
|
||||||
replace github.com/electricbubble/gidevice => github.com/debugtalk/gidevice v0.6.3-0.20221008035433-d79086a752a7
|
replace github.com/electricbubble/gidevice => github.com/debugtalk/gidevice v0.6.3-0.20221009112329-b36169c16739
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -96,8 +96,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
|
|||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/debugtalk/gidevice v0.6.3-0.20221008035433-d79086a752a7 h1:rxaa937c9aj3Yu4M2UZb5CLAgmPu5XXpXQEfKKSWkEw=
|
github.com/debugtalk/gidevice v0.6.3-0.20221009112329-b36169c16739 h1:rMcmtiJJh28z0ILZxdq0C6A2kbobdr4zu9CtxiS6GVY=
|
||||||
github.com/debugtalk/gidevice v0.6.3-0.20221008035433-d79086a752a7/go.mod h1:bRHL2M9qgeEKju8KRvKMZUVEg7t5zMnTiG3SJ3QDH5o=
|
github.com/debugtalk/gidevice v0.6.3-0.20221009112329-b36169c16739/go.mod h1:bRHL2M9qgeEKju8KRvKMZUVEg7t5zMnTiG3SJ3QDH5o=
|
||||||
github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ=
|
github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ=
|
||||||
github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI=
|
github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI=
|
||||||
github.com/electricbubble/gadb v0.0.7 h1:fxvVLVNs3IFKuYAEXDF2tDZUjT9jNCltoTSirjM5dgo=
|
github.com/electricbubble/gadb v0.0.7 h1:fxvVLVNs3IFKuYAEXDF2tDZUjT9jNCltoTSirjM5dgo=
|
||||||
|
|||||||
@@ -131,8 +131,10 @@ type DriverExt struct {
|
|||||||
frame *bytes.Buffer
|
frame *bytes.Buffer
|
||||||
doneMjpegStream chan bool
|
doneMjpegStream chan bool
|
||||||
scale float64
|
scale float64
|
||||||
StartTime time.Time // used to associate screenshots name
|
StartTime time.Time // used to associate screenshots name
|
||||||
ScreenShots []string // save screenshots path
|
ScreenShots []string // save screenshots path
|
||||||
|
perfStop chan struct{} // stop performance monitor
|
||||||
|
perfData []string // save perf data
|
||||||
|
|
||||||
CVArgs
|
CVArgs
|
||||||
}
|
}
|
||||||
@@ -154,6 +156,14 @@ func extend(driver WebDriver) (dExt *DriverExt, err error) {
|
|||||||
return dExt, nil
|
return dExt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (dExt *DriverExt) GetPerfData() []string {
|
||||||
|
if dExt.perfStop == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
close(dExt.perfStop)
|
||||||
|
return dExt.perfData
|
||||||
|
}
|
||||||
|
|
||||||
func (dExt *DriverExt) takeScreenShot() (raw *bytes.Buffer, err error) {
|
func (dExt *DriverExt) takeScreenShot() (raw *bytes.Buffer, err error) {
|
||||||
// wait for action done
|
// wait for action done
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
|
|||||||
@@ -92,6 +92,28 @@ func InitWDAClient(device *IOSDevice) (*DriverExt, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if device.PerfOptions != nil {
|
||||||
|
data, err := iosDevice.d.PerfStart(device.perfOpitons()...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
driverExt.perfStop = make(chan struct{})
|
||||||
|
// start performance monitor
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-driverExt.perfStop:
|
||||||
|
iosDevice.d.PerfStop()
|
||||||
|
return
|
||||||
|
case d := <-data:
|
||||||
|
fmt.Println(string(d))
|
||||||
|
driverExt.perfData = append(driverExt.perfData, string(d))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
driverExt.UUID = iosDevice.UUID()
|
driverExt.UUID = iosDevice.UUID()
|
||||||
return driverExt, nil
|
return driverExt, nil
|
||||||
}
|
}
|
||||||
@@ -122,6 +144,15 @@ func WithLogOn(logOn bool) IOSDeviceOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithPerfOptions(options ...giDevice.PerfOption) IOSDeviceOption {
|
||||||
|
return func(device *IOSDevice) {
|
||||||
|
device.PerfOptions = &giDevice.PerfOptions{}
|
||||||
|
for _, option := range options {
|
||||||
|
option(device.PerfOptions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func IOSDevices(udid ...string) (devices []giDevice.Device, err error) {
|
func IOSDevices(udid ...string) (devices []giDevice.Device, err error) {
|
||||||
var usbmux giDevice.Usbmux
|
var usbmux giDevice.Usbmux
|
||||||
if usbmux, err = giDevice.NewUsbmux(); err != nil {
|
if usbmux, err = giDevice.NewUsbmux(); err != nil {
|
||||||
@@ -171,11 +202,12 @@ func NewIOSDevice(options ...IOSDeviceOption) (device *IOSDevice, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type IOSDevice struct {
|
type IOSDevice struct {
|
||||||
d giDevice.Device
|
d giDevice.Device
|
||||||
UDID string `json:"udid,omitempty" yaml:"udid,omitempty"`
|
PerfOptions *giDevice.PerfOptions `json:"perf_options,omitempty" yaml:"perf_options,omitempty"`
|
||||||
Port int `json:"port,omitempty" yaml:"port,omitempty"` // WDA remote port
|
UDID string `json:"udid,omitempty" yaml:"udid,omitempty"`
|
||||||
MjpegPort int `json:"mjpeg_port,omitempty" yaml:"mjpeg_port,omitempty"` // WDA remote MJPEG port
|
Port int `json:"port,omitempty" yaml:"port,omitempty"` // WDA remote port
|
||||||
LogOn bool `json:"log_on,omitempty" yaml:"log_on,omitempty"`
|
MjpegPort int `json:"mjpeg_port,omitempty" yaml:"mjpeg_port,omitempty"` // WDA remote MJPEG port
|
||||||
|
LogOn bool `json:"log_on,omitempty" yaml:"log_on,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dev *IOSDevice) UUID() string {
|
func (dev *IOSDevice) UUID() string {
|
||||||
@@ -240,6 +272,57 @@ func (dev *IOSDevice) opitons() (deviceOptions []IOSDeviceOption) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (dev *IOSDevice) perfOpitons() (perfOptions []giDevice.PerfOption) {
|
||||||
|
if dev.PerfOptions == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// system
|
||||||
|
if dev.PerfOptions.SysCPU {
|
||||||
|
perfOptions = append(perfOptions, giDevice.WithPerfSystemCPU(true))
|
||||||
|
}
|
||||||
|
if dev.PerfOptions.SysMem {
|
||||||
|
perfOptions = append(perfOptions, giDevice.WithPerfSystemMem(true))
|
||||||
|
}
|
||||||
|
if dev.PerfOptions.SysDisk {
|
||||||
|
perfOptions = append(perfOptions, giDevice.WithPerfSystemDisk(true))
|
||||||
|
}
|
||||||
|
if dev.PerfOptions.SysNetwork {
|
||||||
|
perfOptions = append(perfOptions, giDevice.WithPerfSystemNetwork(true))
|
||||||
|
}
|
||||||
|
if dev.PerfOptions.FPS {
|
||||||
|
perfOptions = append(perfOptions, giDevice.WithPerfFPS(true))
|
||||||
|
}
|
||||||
|
if dev.PerfOptions.Network {
|
||||||
|
perfOptions = append(perfOptions, giDevice.WithPerfNetwork(true))
|
||||||
|
}
|
||||||
|
|
||||||
|
// process
|
||||||
|
if dev.PerfOptions.BundleID != "" {
|
||||||
|
perfOptions = append(perfOptions,
|
||||||
|
giDevice.WithPerfBundleID(dev.PerfOptions.BundleID))
|
||||||
|
}
|
||||||
|
if dev.PerfOptions.Pid != 0 {
|
||||||
|
perfOptions = append(perfOptions,
|
||||||
|
giDevice.WithPerfPID(dev.PerfOptions.Pid))
|
||||||
|
}
|
||||||
|
|
||||||
|
// config
|
||||||
|
if dev.PerfOptions.OutputInterval != 0 {
|
||||||
|
perfOptions = append(perfOptions,
|
||||||
|
giDevice.WithPerfOutputInterval(dev.PerfOptions.OutputInterval))
|
||||||
|
}
|
||||||
|
if dev.PerfOptions.SystemAttributes != nil {
|
||||||
|
perfOptions = append(perfOptions,
|
||||||
|
giDevice.WithPerfSystemAttributes(dev.PerfOptions.SystemAttributes...))
|
||||||
|
}
|
||||||
|
if dev.PerfOptions.ProcessAttributes != nil {
|
||||||
|
perfOptions = append(perfOptions,
|
||||||
|
giDevice.WithPerfProcessAttributes(dev.PerfOptions.ProcessAttributes...))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// NewHTTPDriver creates new remote HTTP client, this will also start a new session.
|
// NewHTTPDriver creates new remote HTTP client, this will also start a new session.
|
||||||
func (dev *IOSDevice) NewHTTPDriver(capabilities Capabilities) (driver WebDriver, err error) {
|
func (dev *IOSDevice) NewHTTPDriver(capabilities Capabilities) (driver WebDriver, err error) {
|
||||||
localPort, err := getFreePort()
|
localPort, err := getFreePort()
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ func (s *veDEMOCRService) getOCRResult(imageBuf []byte) ([]OCRResult, error) {
|
|||||||
return nil, fmt.Errorf("close body writer error: %v", err)
|
return nil, fmt.Errorf("close body writer error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
url, _ := base64.StdEncoding.DecodeString("aHR0cHM6Ly9odWJibGUuYnl0ZWRhbmNlLm5ldC92aWRlby9hcGkvdjEvYWxnb3JpdGhtL29jcg==")
|
url, _ := base64.StdEncoding.DecodeString("aHR0cHM6Ly9ndGZ0YXNrLmJ5dGVkYW5jZS5jb20vYXBpL3YxL2FsZ29yaXRobS9vY3I=")
|
||||||
req, err := http.NewRequest("POST", string(url), bodyBuf)
|
req, err := http.NewRequest("POST", string(url), bodyBuf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("construct request error: %v", err)
|
return nil, fmt.Errorf("construct request error: %v", err)
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
v4.3.0-beta-10081235
|
v4.3.0-beta-10101409
|
||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
@@ -162,8 +161,8 @@ func (r *SessionRunner) GetSummary() (*TestCaseSummary, error) {
|
|||||||
caseSummary.InOut.ExportVars = exportVars
|
caseSummary.InOut.ExportVars = exportVars
|
||||||
caseSummary.InOut.ConfigVars = r.parsedConfig.Variables
|
caseSummary.InOut.ConfigVars = r.parsedConfig.Variables
|
||||||
|
|
||||||
// add WDA/UIA logs to summary
|
|
||||||
for uuid, client := range r.hrpRunner.uiClients {
|
for uuid, client := range r.hrpRunner.uiClients {
|
||||||
|
// add WDA/UIA logs to summary
|
||||||
log, err := client.Driver.StopCaptureLog()
|
log, err := client.Driver.StopCaptureLog()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return caseSummary, err
|
return caseSummary, err
|
||||||
@@ -172,6 +171,10 @@ func (r *SessionRunner) GetSummary() (*TestCaseSummary, error) {
|
|||||||
"uuid": uuid,
|
"uuid": uuid,
|
||||||
"content": log,
|
"content": log,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// stop performance monitor
|
||||||
|
logs["performance"] = client.GetPerfData()
|
||||||
|
|
||||||
caseSummary.Logs = append(caseSummary.Logs, logs)
|
caseSummary.Logs = append(caseSummary.Logs, logs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
21
hrp/step.go
21
hrp/step.go
@@ -1,6 +1,10 @@
|
|||||||
package hrp
|
package hrp
|
||||||
|
|
||||||
import "github.com/httprunner/httprunner/v4/hrp/internal/uixt"
|
import (
|
||||||
|
giDevice "github.com/electricbubble/gidevice"
|
||||||
|
|
||||||
|
"github.com/httprunner/httprunner/v4/hrp/internal/uixt"
|
||||||
|
)
|
||||||
|
|
||||||
type StepType string
|
type StepType string
|
||||||
|
|
||||||
@@ -24,6 +28,21 @@ var (
|
|||||||
WithIgnoreNotFoundError = uixt.WithIgnoreNotFoundError
|
WithIgnoreNotFoundError = uixt.WithIgnoreNotFoundError
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
WithPerfSystemCPU = giDevice.WithPerfSystemCPU
|
||||||
|
WithPerfSystemMem = giDevice.WithPerfSystemMem
|
||||||
|
WithPerfSystemDisk = giDevice.WithPerfSystemDisk
|
||||||
|
WithPerfSystemNetwork = giDevice.WithPerfSystemNetwork
|
||||||
|
WithPerfGPU = giDevice.WithPerfGPU
|
||||||
|
WithPerfFPS = giDevice.WithPerfFPS
|
||||||
|
WithPerfNetwork = giDevice.WithPerfNetwork
|
||||||
|
WithPerfBundleID = giDevice.WithPerfBundleID
|
||||||
|
WithPerfPID = giDevice.WithPerfPID
|
||||||
|
WithPerfOutputInterval = giDevice.WithPerfOutputInterval
|
||||||
|
WithPerfProcessAttributes = giDevice.WithPerfProcessAttributes
|
||||||
|
WithPerfSystemAttributes = giDevice.WithPerfSystemAttributes
|
||||||
|
)
|
||||||
|
|
||||||
type StepResult struct {
|
type StepResult struct {
|
||||||
Name string `json:"name" yaml:"name"` // step name
|
Name string `json:"name" yaml:"name"` // step name
|
||||||
StepType StepType `json:"step_type" yaml:"step_type"` // step type, testcase/request/transaction/rendezvous
|
StepType StepType `json:"step_type" yaml:"step_type"` // step type, testcase/request/transaction/rendezvous
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ var (
|
|||||||
WithWDAPort = uixt.WithWDAPort
|
WithWDAPort = uixt.WithWDAPort
|
||||||
WithWDAMjpegPort = uixt.WithWDAMjpegPort
|
WithWDAMjpegPort = uixt.WithWDAMjpegPort
|
||||||
WithLogOn = uixt.WithLogOn
|
WithLogOn = uixt.WithLogOn
|
||||||
|
WithPerfOptions = uixt.WithPerfOptions
|
||||||
)
|
)
|
||||||
|
|
||||||
type IOSStep struct {
|
type IOSStep struct {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
__version__ = "v4.3.0-beta-10081235"
|
__version__ = "v4.3.0-beta-10101409"
|
||||||
__description__ = "One-stop solution for HTTP(S) testing."
|
__description__ = "One-stop solution for HTTP(S) testing."
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "httprunner"
|
name = "httprunner"
|
||||||
version = "v4.3.0-beta-10081235"
|
version = "v4.3.0-beta-10101409"
|
||||||
description = "One-stop solution for HTTP(S) testing."
|
description = "One-stop solution for HTTP(S) testing."
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|||||||
Reference in New Issue
Block a user