mirror of
https://github.com/httprunner/httprunner.git
synced 2026-09-05 23:51:25 +08:00
feat: NewSummary, NewCaseSummary
This commit is contained in:
+6
-36
@@ -201,7 +201,7 @@ func (r *HRPRunner) Run(testcases ...ITestCase) (err error) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
// record execution data to summary
|
// record execution data to summary
|
||||||
s := newOutSummary()
|
s := NewSummary()
|
||||||
|
|
||||||
// load all testcases
|
// load all testcases
|
||||||
testCases, err := LoadTestCases(testcases...)
|
testCases, err := LoadTestCases(testcases...)
|
||||||
@@ -242,7 +242,7 @@ func (r *HRPRunner) Run(testcases ...ITestCase) (err error) {
|
|||||||
// each run has its own session runner
|
// each run has its own session runner
|
||||||
sessionRunner := caseRunner.NewSession()
|
sessionRunner := caseRunner.NewSession()
|
||||||
caseSummary, err := sessionRunner.Start(it.Next())
|
caseSummary, err := sessionRunner.Start(it.Next())
|
||||||
s.appendCaseSummary(caseSummary)
|
s.AddCaseSummary(caseSummary)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("[Run] run testcase failed")
|
log.Error().Err(err).Msg("[Run] run testcase failed")
|
||||||
runErr = err
|
runErr = err
|
||||||
@@ -257,14 +257,14 @@ func (r *HRPRunner) Run(testcases ...ITestCase) (err error) {
|
|||||||
|
|
||||||
// save summary
|
// save summary
|
||||||
if r.saveTests {
|
if r.saveTests {
|
||||||
if err := s.genSummary(); err != nil {
|
if err := s.GenSummary(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate HTML report
|
// generate HTML report
|
||||||
if r.genHTMLReport {
|
if r.genHTMLReport {
|
||||||
if err := s.genHTMLReport(); err != nil {
|
if err := s.GenHTMLReport(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -414,7 +414,7 @@ func (r *CaseRunner) NewSession() *SessionRunner {
|
|||||||
sessionRunner := &SessionRunner{
|
sessionRunner := &SessionRunner{
|
||||||
caseRunner: r,
|
caseRunner: r,
|
||||||
sessionVariables: make(map[string]interface{}),
|
sessionVariables: make(map[string]interface{}),
|
||||||
summary: newSummary(),
|
summary: NewCaseSummary(),
|
||||||
|
|
||||||
transactions: make(map[string]map[transactionType]time.Time),
|
transactions: make(map[string]map[transactionType]time.Time),
|
||||||
ws: newWSSession(),
|
ws: newWSSession(),
|
||||||
@@ -538,7 +538,7 @@ func (r *SessionRunner) Start(givenVars map[string]interface{}) (summary *TestCa
|
|||||||
stepResult.Name = stepName + loopIndex
|
stepResult.Name = stepName + loopIndex
|
||||||
stepResult.StartTime = startTime
|
stepResult.StartTime = startTime
|
||||||
|
|
||||||
r.updateSummary(stepResult)
|
r.summary.AddStepResult(stepResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
// update extracted variables
|
// update extracted variables
|
||||||
@@ -657,33 +657,3 @@ func (r *SessionRunner) IgnorePopup() bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateSummary updates summary of StepResult.
|
|
||||||
func (r *SessionRunner) updateSummary(stepResult *StepResult) {
|
|
||||||
switch stepResult.StepType {
|
|
||||||
case stepTypeTestCase:
|
|
||||||
// record requests of testcase step
|
|
||||||
if records, ok := stepResult.Data.([]*StepResult); ok {
|
|
||||||
for _, result := range records {
|
|
||||||
r.addSingleStepResult(result)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
r.addSingleStepResult(stepResult)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
r.addSingleStepResult(stepResult)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *SessionRunner) addSingleStepResult(stepResult *StepResult) {
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@ type StepResult struct {
|
|||||||
Success bool `json:"success" yaml:"success"` // step execution result
|
Success bool `json:"success" yaml:"success"` // step execution result
|
||||||
Elapsed int64 `json:"elapsed_ms" yaml:"elapsed_ms"` // step execution time in millisecond(ms)
|
Elapsed int64 `json:"elapsed_ms" yaml:"elapsed_ms"` // step execution time in millisecond(ms)
|
||||||
HttpStat map[string]int64 `json:"httpstat,omitempty" yaml:"httpstat,omitempty"` // httpstat in millisecond(ms)
|
HttpStat map[string]int64 `json:"httpstat,omitempty" yaml:"httpstat,omitempty"` // httpstat in millisecond(ms)
|
||||||
Data interface{} `json:"data,omitempty" yaml:"data,omitempty"` // session data or slice of step data
|
Data interface{} `json:"data,omitempty" yaml:"data,omitempty"` // step data, *StepResult or []*StepResult
|
||||||
ContentSize int64 `json:"content_size" yaml:"content_size"` // response body length
|
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
|
ExportVars map[string]interface{} `json:"export_vars,omitempty" yaml:"export_vars,omitempty"` // extract variables
|
||||||
Attachments interface{} `json:"attachments,omitempty" yaml:"attachments,omitempty"` // store extra step information, such as error message or screenshots
|
Attachments interface{} `json:"attachments,omitempty" yaml:"attachments,omitempty"` // store extra step information, such as error message or screenshots
|
||||||
|
|||||||
+49
-17
@@ -17,7 +17,7 @@ import (
|
|||||||
"github.com/httprunner/httprunner/v4/hrp/internal/version"
|
"github.com/httprunner/httprunner/v4/hrp/internal/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newOutSummary() *Summary {
|
func NewSummary() *Summary {
|
||||||
platForm := &Platform{
|
platForm := &Platform{
|
||||||
HttprunnerVersion: version.VERSION,
|
HttprunnerVersion: version.VERSION,
|
||||||
GoVersion: runtime.Version(),
|
GoVersion: runtime.Version(),
|
||||||
@@ -43,7 +43,8 @@ type Summary struct {
|
|||||||
rootDir string
|
rootDir string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Summary) appendCaseSummary(caseSummary *TestCaseSummary) {
|
func (s *Summary) AddCaseSummary(caseSummary *TestCaseSummary) {
|
||||||
|
log.Info().Interface("caseSummary", caseSummary).Msg("add case summary")
|
||||||
s.Success = s.Success && caseSummary.Success
|
s.Success = s.Success && caseSummary.Success
|
||||||
s.Stat.TestCases.Total += 1
|
s.Stat.TestCases.Total += 1
|
||||||
s.Stat.TestSteps.Total += caseSummary.Stat.Total
|
s.Stat.TestSteps.Total += caseSummary.Stat.Total
|
||||||
@@ -55,7 +56,6 @@ func (s *Summary) appendCaseSummary(caseSummary *TestCaseSummary) {
|
|||||||
s.Stat.TestSteps.Successes += caseSummary.Stat.Successes
|
s.Stat.TestSteps.Successes += caseSummary.Stat.Successes
|
||||||
s.Stat.TestSteps.Failures += caseSummary.Stat.Failures
|
s.Stat.TestSteps.Failures += caseSummary.Stat.Failures
|
||||||
s.Details = append(s.Details, caseSummary)
|
s.Details = append(s.Details, caseSummary)
|
||||||
s.Success = s.Success && caseSummary.Success
|
|
||||||
|
|
||||||
// specify output reports dir
|
// specify output reports dir
|
||||||
if len(s.Details) == 1 {
|
if len(s.Details) == 1 {
|
||||||
@@ -66,7 +66,7 @@ func (s *Summary) appendCaseSummary(caseSummary *TestCaseSummary) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Summary) genHTMLReport() error {
|
func (s *Summary) GenHTMLReport() error {
|
||||||
reportsDir := filepath.Join(s.rootDir, env.ResultsDir)
|
reportsDir := filepath.Join(s.rootDir, env.ResultsDir)
|
||||||
err := builtin.EnsureFolderExists(reportsDir)
|
err := builtin.EnsureFolderExists(reportsDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -96,7 +96,7 @@ func (s *Summary) genHTMLReport() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Summary) genSummary() error {
|
func (s *Summary) GenSummary() error {
|
||||||
reportsDir := filepath.Join(s.rootDir, env.ResultsDir)
|
reportsDir := filepath.Join(s.rootDir, env.ResultsDir)
|
||||||
err := builtin.EnsureFolderExists(reportsDir)
|
err := builtin.EnsureFolderExists(reportsDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -142,6 +142,18 @@ type Platform struct {
|
|||||||
Platform string `json:"platform" yaml:"platform"`
|
Platform string `json:"platform" yaml:"platform"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewCaseSummary() *TestCaseSummary {
|
||||||
|
return &TestCaseSummary{
|
||||||
|
Success: true,
|
||||||
|
Stat: &TestStepStat{},
|
||||||
|
Time: &TestCaseTime{
|
||||||
|
StartAt: time.Now(),
|
||||||
|
},
|
||||||
|
InOut: &TestCaseInOut{},
|
||||||
|
Records: []*StepResult{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestCaseSummary stores tests summary for one testcase
|
// TestCaseSummary stores tests summary for one testcase
|
||||||
type TestCaseSummary struct {
|
type TestCaseSummary struct {
|
||||||
Name string `json:"name" yaml:"name"`
|
Name string `json:"name" yaml:"name"`
|
||||||
@@ -155,6 +167,38 @@ type TestCaseSummary struct {
|
|||||||
RootDir string `json:"root_dir" yaml:"root_dir"`
|
RootDir string `json:"root_dir" yaml:"root_dir"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddStepResult updates summary of StepResult.
|
||||||
|
func (s *TestCaseSummary) AddStepResult(stepResult *StepResult) {
|
||||||
|
switch stepResult.StepType {
|
||||||
|
case stepTypeTestCase:
|
||||||
|
// record requests of testcase step
|
||||||
|
records, ok := stepResult.Data.([]*StepResult)
|
||||||
|
if !ok {
|
||||||
|
log.Warn().
|
||||||
|
Interface("data", stepResult.Data).
|
||||||
|
Msg("get unexpected testcase step data")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.Success = s.Success && stepResult.Success
|
||||||
|
for _, result := range records {
|
||||||
|
s.addSingleStepResult(result)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
s.addSingleStepResult(stepResult)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *TestCaseSummary) addSingleStepResult(stepResult *StepResult) {
|
||||||
|
s.Success = s.Success && stepResult.Success
|
||||||
|
s.Stat.Total += 1
|
||||||
|
if stepResult.Success {
|
||||||
|
s.Stat.Successes += 1
|
||||||
|
} else {
|
||||||
|
s.Stat.Failures += 1
|
||||||
|
}
|
||||||
|
s.Records = append(s.Records, stepResult)
|
||||||
|
}
|
||||||
|
|
||||||
type TestCaseInOut struct {
|
type TestCaseInOut struct {
|
||||||
ConfigVars map[string]interface{} `json:"config_vars" yaml:"config_vars"`
|
ConfigVars map[string]interface{} `json:"config_vars" yaml:"config_vars"`
|
||||||
ExportVars map[string]interface{} `json:"export_vars" yaml:"export_vars"`
|
ExportVars map[string]interface{} `json:"export_vars" yaml:"export_vars"`
|
||||||
@@ -191,15 +235,3 @@ type ValidationResult struct {
|
|||||||
CheckValue interface{} `json:"check_value" yaml:"check_value"`
|
CheckValue interface{} `json:"check_value" yaml:"check_value"`
|
||||||
CheckResult string `json:"check_result" yaml:"check_result"`
|
CheckResult string `json:"check_result" yaml:"check_result"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSummary() *TestCaseSummary {
|
|
||||||
return &TestCaseSummary{
|
|
||||||
Success: true,
|
|
||||||
Stat: &TestStepStat{},
|
|
||||||
Time: &TestCaseTime{
|
|
||||||
StartAt: time.Now(),
|
|
||||||
},
|
|
||||||
InOut: &TestCaseInOut{},
|
|
||||||
Records: []*StepResult{},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+44
-8
@@ -1,12 +1,20 @@
|
|||||||
package hrp
|
package hrp
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
func TestGenHTMLReport(t *testing.T) {
|
func TestGenHTMLReport(t *testing.T) {
|
||||||
summary := newOutSummary()
|
summary := NewSummary()
|
||||||
caseSummary1 := newSummary()
|
|
||||||
caseSummary2 := newSummary()
|
caseSummary1 := NewCaseSummary()
|
||||||
stepResult1 := &StepResult{}
|
stepResult1 := &StepResult{}
|
||||||
|
caseSummary1.AddStepResult(stepResult1)
|
||||||
|
summary.AddCaseSummary(caseSummary1)
|
||||||
|
|
||||||
|
caseSummary2 := NewCaseSummary()
|
||||||
stepResult2 := &StepResult{
|
stepResult2 := &StepResult{
|
||||||
Name: "Test",
|
Name: "Test",
|
||||||
StepType: stepTypeRequest,
|
StepType: stepTypeRequest,
|
||||||
@@ -14,11 +22,39 @@ func TestGenHTMLReport(t *testing.T) {
|
|||||||
ContentSize: 0,
|
ContentSize: 0,
|
||||||
Attachments: "err",
|
Attachments: "err",
|
||||||
}
|
}
|
||||||
caseSummary1.Records = []*StepResult{stepResult1, stepResult2, nil}
|
caseSummary2.AddStepResult(stepResult2)
|
||||||
summary.appendCaseSummary(caseSummary1)
|
summary.AddCaseSummary(caseSummary2)
|
||||||
summary.appendCaseSummary(caseSummary2)
|
|
||||||
err := summary.genHTMLReport()
|
err := summary.GenHTMLReport()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTestCaseSummary_AddStepResult(t *testing.T) {
|
||||||
|
caseSummary := NewCaseSummary()
|
||||||
|
stepResult1 := &StepResult{
|
||||||
|
Name: "Test1",
|
||||||
|
StepType: stepTypeRequest,
|
||||||
|
Success: true,
|
||||||
|
ContentSize: 0,
|
||||||
|
Attachments: "err",
|
||||||
|
}
|
||||||
|
caseSummary.AddStepResult(stepResult1)
|
||||||
|
stepResult2 := &StepResult{
|
||||||
|
Name: "Test2",
|
||||||
|
StepType: stepTypeTestCase,
|
||||||
|
Success: false,
|
||||||
|
ContentSize: 0,
|
||||||
|
Attachments: "err",
|
||||||
|
Data: []*StepResult{stepResult1},
|
||||||
|
}
|
||||||
|
caseSummary.AddStepResult(stepResult2)
|
||||||
|
|
||||||
|
if !assert.Equal(t, 2, len(caseSummary.Records)) {
|
||||||
|
t.Fatal()
|
||||||
|
}
|
||||||
|
if !assert.False(t, caseSummary.Success) {
|
||||||
|
t.Fatal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user