运行银杏测试套件(在运行任何规范之前进行BeforeSuite设置)

huangapple go评论87阅读模式
英文:

Running Ginkgo test suite (BeforeSuite setup before any spec is ran

问题

我正在使用Ginkgo(和Gomega)包来对Go(lang)Rest API进行单元测试。

我需要使用全局设置,可以通过定义以下方式实现:

var _ = BeforeSuite(func() {...})

然后每个具体的规范(<file>_test.go)都应在此全局设置之后运行。不幸的是,我无法做到这一点...

我的套件文件名为handlers_suite_test.go,我的第一个测试规范名为cartContentsHandler_test.go。在我看来,Ginkgo按字母顺序运行测试文件,使得cartContentsHandler_test.gohandlers_suite_test.go之前运行。我在这两个文件中都放了一些log()调用,不幸的是它们只是确认了我的发现...

这真是一个令人不快的情况,因为我无法使我的测试运行起来...我需要确保在所有规范之前设置并运行httptest.Server和DB连接池。

你知道如何使suite_test作为第一个文件在测试规范之前运行吗?(我已经尝试将套件文件命名为_suite_test.go,但在这种情况下,套件似乎根本没有被执行)。

我的handlers_suite_test.go

package handlers_test

import (
	"<PROJ>/config"
	"<PROJ>/lib"
	"<PROJ>/router"
	"github.com/gorilla/mux"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"log"
	"net/http/httptest"
	"os"
	"testing"
)

var r *mux.Router
var s *httptest.Server
var serverURL string

func TestHandlers(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "Caracal Handlers Suite")
}

var _ = BeforeSuite(func() {
	r = router.NewRouter()
	s = httptest.NewServer(r)
	Expect(len(s.URL)).To(BeNumerically(">", 0))
	serverURL = s.URL
	log.Print("###" + serverURL + "###\n\n") // ==&gt; THIS PRINTS MUCH LATER AFTER log.Print() in cartContentsHandler_test.go

	cwd, _ := os.Getwd()
	cfg := config.ReadCfg(cwd + "/../config/config.json").DB
	lib.DB = lib.InitDB(cfg)
	err := lib.DB.Ping()
	Expect(err).NotTo(HaveOccurred())
})

var _ = AfterSuite(func() {
	// 	lib.DB.Close() // ==&gt; this was running into Panic...
	s.Close()
})

我的cartContensHandler_test.go

package handlers_test

import (
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

    "log"
	"net/http"
	"strings"
)

var _ = Describe("Handlers/CartContentsHandler", func() {
	Describe("Retrieves all available cart content types", func() {
		Context("No query string parameters", func() {
			var rdr *strings.Reader
			var req *http.Request
			var res *http.Response
			var err error
			var url = serverURL + "/cart-contents"

			log.Print(url)

			It("Makes a GET request", func() {
				rdr = strings.NewReader("")
				req, err = http.NewRequest("GET", url, rdr)
				Expect(err).NotTo(HaveOccurred())
			})

			It("retrieves a response", func() {
				res, err = http.DefaultClient.Do(req)
				Expect(err).NotTo(HaveOccurred())
			})

			It("Returns HTTP 200 OK", func() {
				Expect(res.StatusCode).To(BeNumerically("==", http.StatusOK)) // ==&gt; NOW THIS RETURNS 404 as request is to URL without server part
			})
		})
	})
})

当我在&lt;PROJ&gt;根目录中运行测试时,我使用以下命令:

ginkgo handlers -cover --v
英文:

I am experiencing with Ginkgo (and Gomega) packages for unit testing Go(lang) Rest API.

I need to use global setup which should be achievable by defining

var _ = BeforeSuite(func() {...})

Then each spec (concrete &lt;file&gt;_test.go) should run after this global setup. Unfortunately I cannot make this happen...

My suite file name is handlers_suite_test.go and my first test spec name is cartContentsHandler_test.go. It seems to me Ginkgo runs the test files in alphabetical order making the cartContentsHandler_test.go to run before handlers_suite_test.go. I have put some log() call into both files and unfortunately they just confirm my findings...

This is really unhappy situation as I cannot make my tests running at all... I need to make sure that an httptest.Server and DB pool connection are set up and running before all specs.

Do you know what to do in order to make the suite_test to run as the very first file before test specs? (I already tried to name the suite file as _suite_test.go but in this case it looks like suite is not even executed at all).

My handlers_suite_test.go:

package handlers_test

import (
	&quot;&lt;PROJ&gt;/config&quot;
	&quot;&lt;PROJ&gt;/lib&quot;
	&quot;&lt;PROJ&gt;/router&quot;
	&quot;github.com/gorilla/mux&quot;
	. &quot;github.com/onsi/ginkgo&quot;
	. &quot;github.com/onsi/gomega&quot;

	&quot;log&quot;
	&quot;net/http/httptest&quot;
	&quot;os&quot;
	&quot;testing&quot;
)

var r *mux.Router
var s *httptest.Server
var serverURL string

func TestHandlers(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, &quot;Caracal Handlers Suite&quot;)
}

var _ = BeforeSuite(func() {
	r = router.NewRouter()
	s = httptest.NewServer(r)
	Expect(len(s.URL)).To(BeNumerically(&quot;&gt;&quot;, 0))
	serverURL = s.URL
	log.Print(&quot;###&quot; + serverURL + &quot;###\n\n&quot;) // ==&gt; THIS PRINTS MUCH LATER AFTER log.Print() in cartContentsHandler_test.go

	cwd, _ := os.Getwd()
	cfg := config.ReadCfg(cwd + &quot;/../config/config.json&quot;).DB
	lib.DB = lib.InitDB(cfg)
	err := lib.DB.Ping()
	Expect(err).NotTo(HaveOccurred())
})

var _ = AfterSuite(func() {
	// 	lib.DB.Close() // ==&gt; this was running into Panic...
	s.Close()
})

My cartContensHandler_test.go:

package handlers_test

import (
	. &quot;github.com/onsi/ginkgo&quot;
	. &quot;github.com/onsi/gomega&quot;

    &quot;log&quot;
	&quot;net/http&quot;
	&quot;strings&quot;
)

var _ = Describe(&quot;Handlers/CartContentsHandler&quot;, func() {
	Describe(&quot;Retrieves all available cart content types&quot;, func() {
		Context(&quot;No query string parameters&quot;, func() {
			var rdr *strings.Reader
			var req *http.Request
			var res *http.Response
			var err error
			var url = serverURL + &quot;/cart-contents&quot;

			log.Print(url)

			It(&quot;Makes a GET request&quot;, func() {
				rdr = strings.NewReader(&quot;&quot;)
				req, err = http.NewRequest(&quot;GET&quot;, url, rdr)
				Expect(err).NotTo(HaveOccurred())
			})

			It(&quot;retrieves a response&quot;, func() {
				res, err = http.DefaultClient.Do(req)
				Expect(err).NotTo(HaveOccurred())
			})

			It(&quot;Returns HTTP 200 OK&quot;, func() {
				Expect(res.StatusCode).To(BeNumerically(&quot;==&quot;, http.StatusOK)) // ==&gt; NOW THIS RETURNS 404 as request is to URL without server part
			})
		})
	})
})

When in &lt;PROJ> root, I run the tests this way:

ginkgo handlers -cover --v

答案1

得分: 13

发生的情况是 BeforeSuite 注册一个在测试套件之前执行的函数,而 It 注册一个作为测试套件一部分的测试函数。对于 DescribeContext 的回调会立即执行。因此,你必须将所有依赖于 BeforeSuite 的内容放入 It 中。

英文:

What happens is that BeforeSuite registers a function that will be executed before the test suite, and It registers a test function that will be part of the test suite. The callbacks to Describe and Context are executed immediately. So you must put everything that depends on BeforeSuite into It.

答案2

得分: 3

为了确保BeforeSuiteDescribe块的本地设置之前运行必要的全局设置,您应该使用BeforeEach

在您的套件中:

var serverURL string

var _ = BeforeSuite(func() {
    r = router.NewRouter()
    s = httptest.NewServer(r)
    serverURL = s.URL
})

以及在测试中:

var _ = Describe("Handlers/CartContentsHandler", func() {
  var url url.URL

  BeforeEach(func() {
    url = serverURL + "/cart-contents"
  })

  It("Makes a GET request", func() {
    # ....
  })
})
英文:

To guarantee that the BeforeSuite will run the necessary global setup before the local setup for a Describe block, you should use BeforeEach:

In your suite:

var serverURL string

var _ = BeforeSuite(func() {
    r = router.NewRouter()
    s = httptest.NewServer(r)
    serverURL = s.URL
})

and in the test:

var _ = Describe(&quot;Handlers/CartContentsHandler&quot;, func() {
  var url url.URL

  BeforeEach(func() {
    url = serverURL + &quot;/cart-contents&quot;
  })

  It(&quot;Makes a GET request&quot;, func() {
    # ....
  })
})

huangapple
  • 本文由 发表于 2016年3月24日 22:42:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/36202934.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定