httprunner / httprunner

HttpRunner 是一个开源的 API/UI 测试工具,简单易用,功能强大,具有丰富的插件化机制和高度的可扩展能力。

Home Page:https://httprunner.com/httprunner/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

validate 失败后report无法正常生成

jonzha9527 opened this issue · comments

desc

hrp 4.3.6
validate 如果失败后台会报错,report 也没有生成,当validate 成功的情况下,一切正常

testcase

    validate:
      - check: body.Code
        assert: len_gt
        expect: 10
        msg: check code length

cmd

hrp run test/tmp.yml -s -g -c --log-plugin

error

2023-11-08T15:44:45.182+0800 [ERROR] hc-grpc-py: plugin process exited: path=/root/.hrp/venv/bin/python3 pid=130273 error="signal: killed"                                
panic: runtime error: invalid memory address or nil pointer dereference [recovered]                                                                                       
        panic: runtime error: invalid memory address or nil pointer dereference

+1

commented

+1

请问能通过降版本解决吗?

+1,这要怎么解决

问题描述:我是通过从数据库读取配置、用例参数然后传入执行,代码如下:

testcase := &hrp.TestCase{
		Config: tConfig,
		TestSteps: []hrp.IStep{
			testSteps,
		},
	}

	caseRunner, _ := hrp.NewRunner(nil).SetHTTPStatOn().NewCaseRunner(testcase)
	sessionRunner := caseRunner.NewSession()
	if err = sessionRunner.Start(nil); err != nil {
		return nil, err
	}
	summary, err := sessionRunner.GetSummary()
	if err != nil {
		return summary, err
	}

	return summary, nil

详细描述:但是执行时也发现了这个问题,如果断言成功报告可以生成,只要断言失败就会报:runtime error: invalid memory address or nil pointer dereference,调试发现代码执行到github.com/stretchr/testify库下面代码return output处报错

func labeledOutput(content ...labeledContent) string {
	longestLabel := 0
	for _, v := range content {
		if len(v.label) > longestLabel {
			longestLabel = len(v.label)
		}
	}
	var output string
	for _, v := range content {
		output += "\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n"
	}
	return output
}

进一步描述:但是通过单独执行如下测试函数,即使断言失败也不会报错

var (
	stepGET = NewStep("get with params").
		GET("/get").
		WithParams(map[string]interface{}{"foo1": "bar1", "foo2": "bar2"}).
		WithHeaders(map[string]string{"User-Agent": "HttpRunnerPlus"}).
		WithCookies(map[string]string{"user": "debugtalk"}).
		Validate().
		AssertEqual("status_code", 400, "check status code").
		AssertEqual("headers.\"Content-Type\"", "application/json; charset=utf-8", "check header Content-Type").
		AssertEqual("body.args.foo1", "bar1", "check param foo1").
		AssertEqual("body.args.foo2", "bar2", "check param foo2")
	stepPOSTData = NewStep("post form data").
			POST("/post").
			WithParams(map[string]interface{}{"foo1": "bar1", "foo2": "bar2"}).
			WithHeaders(map[string]string{"User-Agent": "HttpRunnerPlus", "Content-Type": "application/x-www-form-urlencoded"}).
			WithBody("a=1&b=2").
			WithCookies(map[string]string{"user": "debugtalk"}).
			Validate().
			AssertEqual("status_code", 400, "check status code")
)

func TestRunRequestStatOn(t *testing.T) {
	testcase := &TestCase{
		Config:    NewConfig("test").SetBaseURL("https://postman-echo.com"),
		TestSteps: []IStep{stepGET, stepPOSTData},
	}
	caseRunner, _ := NewRunner(t).SetHTTPStatOn().NewCaseRunner(testcase)
	sessionRunner := caseRunner.NewSession()
	if err := sessionRunner.Start(nil); err != nil {
		t.Fatal()
	}
	summary, _ := sessionRunner.GetSummary()

	stat := summary.Records[0].HttpStat
	if !assert.GreaterOrEqual(t, stat["DNSLookup"], int64(0)) {
		t.Fatal()
	}
	if !assert.Greater(t, stat["TCPConnection"], int64(0)) {
		t.Fatal()
	}
	if !assert.Greater(t, stat["TLSHandshake"], int64(0)) {
		t.Fatal()
	}
	if !assert.Greater(t, stat["ServerProcessing"], int64(0)) {
		t.Fatal()
	}
	if !assert.GreaterOrEqual(t, stat["ContentTransfer"], int64(0)) {
		t.Fatal()

在main.go中加入 testing.Init() 来初始化参数就可以正常work了,本地重新make build生成hrp。

func main() {
	defer func() {
		if err := recover(); err != nil {
			// report panic to sentry
			sentry.CurrentHub().Recover(err)
			sentry.Flush(time.Second * 5)

			// print panic trace
			panic(err)
		}
	}()
	testing.Init()

	exitCode := cmd.Execute()
	os.Exit(exitCode)
}

在main.go中加入 testing.Init() 来初始化参数就可以正常work了,本地重新make build生成hrp。

func main() {
	defer func() {
		if err := recover(); err != nil {
			// report panic to sentry
			sentry.CurrentHub().Recover(err)
			sentry.Flush(time.Second * 5)

			// print panic trace
			panic(err)
		}
	}()
	testing.Init()

	exitCode := cmd.Execute()
	os.Exit(exitCode)
}

感谢解答,有效

在main.go中加入 testing.Init() 来初始化参数就可以正常work了,本地重新make build生成hrp。

func main() {
	defer func() {
		if err := recover(); err != nil {
			// report panic to sentry
			sentry.CurrentHub().Recover(err)
			sentry.Flush(time.Second * 5)

			// print panic trace
			panic(err)
		}
	}()
	testing.Init()

	exitCode := cmd.Execute()
	os.Exit(exitCode)
}

感谢解答,有效

后面验证又发现go 1.19不会报invalid memory address or nil pointer dereference,但是go 1.21的版本会报invalid memory address or nil pointer dereference