dtoq41429
2015-07-03 08:14
浏览 304
已采纳

如何依次运行golang测试?

When I run go test, my output:

--- FAIL: TestGETSearchSuccess (0.00s)
        Location:       drivers_api_test.go:283
        Error:          Not equal: 200 (expected)
                                != 204 (actual)

--- FAIL: TestGETCOSearchSuccess (0.00s)
        Location:       drivers_api_test.go:391
        Error:          Not equal: 200 (expected)
                                != 204 (actual)

But after I run go test again, all my tests pass.

Tests fail only when I reset my mysql database, and then run go test for the first time.

For every GET request, I do a POST request before to ensure that there is data created in the DB.

Could anyone help me with how to make sure that tests are run sequentially? That is the POST requests are run before the GET requests?

图片转代码服务由CSDN问答提供 功能建议

当我运行 go test 时,我的输出:

  ---失败:TestGETSearchSuccess(0.00s)
位置:drivers_api_test.go:283 
错误:不等于:200(预期)
!= 204(实际)
 
--  -失败:TestGETCOSearchSuccess(0.00s)
位置:drivers_api_test.go:391 
错误:不等于:200(预期)
!= 204(实际)
   
 
  

但是,当我再次运行 go test 后,所有测试都通过了。

仅当我重置mysql数据库并运行时,测试失败 第一次测试

对于每个 GET 请求,我都会先执行 POST 请求,以确保在数据库中创建了数据。

有人可以帮助我确保测试按顺序运行吗? 那是 POST 请求在 GET 请求之前运行?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • dongpai2754 2015-07-03 10:03
    已采纳

    You can't / shouldn't rely on test execution order. The order in which tests are executed is not defined, and with the use of testing flags it is possible to exclude tests from running, so you have no guarantee that they will run at all.

    For example the following command will only run tests whose name contains a 'W' letter:

    go test -run W
    

    Also note that if some test functions mark themselves eligible for parallel execution using the T.Parallel() method, the go tool will reorder the tests to first run non-parallel tests, and then run parallel tests in parallel under certain circumstances (controlled by test flags like -p). You can see examples of this in this answer: Are tests executed in parallel in Go or one by one?

    Tests should be independent from each other. If a test function has prerequisites, that cannot be done/implemented in another test function.

    Options to do additional tasks before a test function is run:

    • You may put it in the test function itself
    • You may put it in a package init() function, in the _test.go file itself. This will run once before execution of test functions begins.
    • You may choose to implement a TestMain() function which will be called first and in which you may do additional setup before you call M.Run() to trigger the execution of test functions.
    • You may mix the above options.

    In your case in package init() or TestMain() you should check if your DB is initialized (there are test records inserted), and if not, insert the test records.

    Note that starting with Go 1.7, you may use subtests in which you define execution order of subtests. For details see blog post: Using Subtests and Sub-benchmarks, and the package doc of the testing package.

    点赞 评论
  • dtnat80842 2015-07-03 08:26

    The best way to achieve that is to create a TestMain, as presented here.

    import (
      "testing"
      "os"
    )
    
    func TestMain(m *testing.M) {
       // Do your stuff here
       os.Exit(m.Run())
    }
    
    点赞 评论
  • dongmi5177 2016-09-27 20:59

    Apart for 3rd party libraries like Convey and Ginkgo, with plain Golang 1.7 you can run tests sequentially. You can read more here

    func TestFoo(t *testing.T) {
        // <setup code>
        t.Run("A=1", func(t *testing.T) { ... })
        t.Run("A=2", func(t *testing.T) { ... })
        t.Run("B=1", func(t *testing.T) { ... })
        // <tear-down code>
    }
    

    And you can run them conditionally with:

    go test -run ''      # Run all tests.
    go test -run Foo     # Run top-level tests matching "Foo", such as "TestFooBar".
    go test -run Foo/A=  # For top-level tests matching "Foo", run subtests matching "A=".
    go test -run /A=1    # For all top-level tests, run subtests matching "A=1".
    

    So lets say you got an user package from a REST api that you want to test. You need to test the create handler in order to be able to test the login handler. Usually I would have this on the user_test.go

    type UserTests struct { Test *testing.T}
    func TestRunner(t *testing.T) {
    
        t.Run("A=create", func(t *testing.T) {
            test:= UserTests{Test: t}
            test.TestCreateRegularUser()
            test.TestCreateConfirmedUser()
            test.TestCreateMasterUser()
            test.TestCreateUserTwice()
        })
        t.Run("A=login", func(t *testing.T) {
            test:= UserTests{Test: t}
            test.TestLoginRegularUser()
            test.TestLoginConfirmedUser()
            test.TestLoginMasterUser()
        })
    
    }
    

    Then I can append methods to the UserTest type that wont be executed by the go test command in any _test.go file

    func (t *UserTests) TestCreateRegularUser() {
        registerRegularUser := util.TableTest{
            Method:      "POST",
            Path:        "/iot/users",
            Status:      http.StatusOK,
            Name:        "registerRegularUser",
            Description: "register Regular User has to return 200",
            Body: SerializeUser(RegularUser),
        }
        response := util.SpinSingleTableTests(t.Test, registerRegularUser)
        util.LogIfVerbose(color.BgCyan, "IOT/USERS/TEST", response)
    }
    
    点赞 评论

相关推荐 更多相似问题