Home >Backend Development >Golang >Ginkgo: a BDD Go language framework

Ginkgo: a BDD Go language framework

Go语言进阶学习
Go语言进阶学习forward
2023-07-25 14:32:48990browse

Unit testing focuses on the logical unit of code, usually an object or a specific function. We can write enough unit tests to ensure the quality of the code. When functions are modified or code is refactored, sufficient unit test cases can give us enough confidence.

Above unit testing are development specifications. In agile software development, there are two frequent visitors: Test-Driven Development (TDD) and Behavior-driven development (BDD). They are practices and techniques, but also design methodologies.

TDD

The basic idea of ​​TDD is to promote the entire development through testing. The principle is to write units before developing functional code. Test cases. Contains the following five steps:

  • Developers first write some test cases
  • Run These tests, but these tests will obviously fail because the business logic in the test cases has not been implemented
  • Implementation code details
  • If the developer successfully implements the code, running all tests will pass
  • Refactor the business code in time, if the new If the code function is incorrect, the corresponding test file will also fail

When new functions need to be developed, repeat the above steps. The process is as shown below

Ginkgo: a BDD Go language framework

##tdd-flowchart

There is a Github repository that is more interesting:learn-go-with-tests , this repository is designed to learn TDD with Go.

BDD

TDD focuses on development, and uses test cases to regulate and constrain developers to write higher quality and less buggy code . BDD focuses more on design. It requires the system to be defined when designing test cases, advocates the use of a common language to describe the behavior of the system, and combines system design and test cases to drive development. Development work.

BDD is derived from TDD,

The main difference lies in the description of the test. BDD uses a more understandable language to describe test cases, focusing more on the required functionality rather than the actual results.

The ability given by BDD to read tests like sentences brings about a change in the perception of tests and helps us think about how to write tests better.

Ginkgo

Ginkgo

is a BDD testing framework in Go language, designed to help developers write expressive comprehensive testing.

Ginkgo integrates Go’s native

testing<span style="font-size: 15px;"></span> library, which means you can pass go test<span style="font-size: 15px;"></span> to run the Ginkgo test suite. At the same time, it is also compatible with the assertion and mock suite testify and the rich test suite go-check. But Ginkgo recommends using it with the gomega library.

Next, we use Ginkgo to experience the test code of BDD mode.

Download

Use

go get<span style="font-size: 15px;"></span> Get

$ go get github.com/onsi/ginkgo/ginkgo
$ go get github.com/onsi/gomega/...

This command gets ginkgo and installs the <span style="font-size: 15px;">ginkgo</span> executable to <span style="font-size: 15px;">$GOPATH/bin</span>.

Create kit

Create gopher library

$ cd path-to-package/gopher

In<span style="font-size: 15px;">gopher.go</span> In the file, there are <span style="font-size: 15px;">Gopher</span> structure and verification method<span style="font-size: 15px;">Validate</span> As follows

package gopher

import (
 "errors"
 "unicode/utf8"
)

type Gopher struct {
 Name   string
 Gender string
 Age    int
}

func Validate(g Gopher) error {
 if utf8.RuneCountInString(g.Name) < 3 {
  return errors.New("名字太短,不能小于3")
 }

 if g.Gender != "男" {
  return errors.New("只要男的")
 }

 if g.Age < 18 {
  return errors.New("岁数太小,不能小于18")
 }
 return nil
}

We use the <span style="font-size: 15px;">ginkgo bootstrap</span> command to initialize a Ginkgo test suite .

$ ginkgo bootstrap
Generating ginkgo test suite bootstrap for gopher in:
        gopher_suite_test.go

At this time, is generated in the directory of the same level as <span style="font-size: 15px;"></span>gopher.go <span style="font-size: 15px;">gopher_suite_test.go</span> file, the content is as follows

package gopher_test

import (
 "testing"

 . "github.com/onsi/ginkgo"
 . "github.com/onsi/gomega"
)

func TestGopher(t *testing.T) {
 RegisterFailHandler(Fail)
 RunSpecs(t, "Gopher Suite")
}

此时,我们就可以运行测试套件了,通过命令 <span style="font-size: 15px;">go test</span><span style="font-size: 15px;">ginkgo</span> 均可。

 $ go test
Running Suite: Gopher Suite
===========================
Random Seed: 1629621653
Will run 0 of 0 specs


Ran 0 of 0 Specs in 0.000 seconds
SUCCESS! -- 0 Passed | 0 Failed | 0 Pending | 0 Skipped
PASS
ok      ginkgo/gopher   0.018s

当然,空测试套件没有什么价值,我们需要在此套件下编写测试(Spec)用例。

我们可以在 <span style="font-size: 15px;">gopher_suite_test.go</span> 中编写测试,但是推荐分离到独立的文件中,特别是包中有多个需要被测试的源文件的情况下。

创建 Spec

执行 <span style="font-size: 15px;">ginkgo generate gopher</span>  可以生成一个 <span style="font-size: 15px;">gopher_test.go</span> 测试文件。

 $ ginkgo generate gopher
Generating ginkgo test for Gopher in:
  gopher_test.go

此时测试文件中的内容如下

package gopher_test

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

var _ = Describe("Gopher", func() {

})
编写 Spec

我们基于此测试文件撰写实际的测试用例

package gopher_test

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

func mockInputData() ([]gopher.Gopher, error) {
 inputData := []gopher.Gopher{
  {
   Name:   "菜刀",
   Gender: "男",
   Age:    18,
  },
  {
   Name:   "小西瓜",
   Gender: "女",
   Age:    19,
  },
  {
   Name:   "机器铃砍菜刀",
   Gender: "男",
   Age:    17,
  },
  {
   Name:   "小菜刀",
   Gender: "男",
   Age:    20,
  },
 }
 return inputData, nil
}

var _ = Describe("Gopher", func() {

 BeforeEach(func() {
  By("当测试不通过时,我会在这里打印一个消息 【BeforeEach】")
 })

 inputData, err := mockInputData()

 Describe("校验输入数据", func() {

  Context("当获取数据没有错误发生时", func() {
   It("它应该是接收数据成功了的", func() {
    gomega.Expect(err).Should(gomega.BeNil())
   })
  })

  Context("当获取的数据校验失败时", func() {
   It("当数据校验返回错误为:名字太短,不能小于3 时", func() {
    gomega.Expect(gopher.Validate(inputData[0])).Should(gomega.MatchError("名字太短,不能小于3"))
   })

   It("当数据校验返回错误为:只要男的 时", func() {
    gomega.Expect(gopher.Validate(inputData[1])).Should(gomega.MatchError("只要男的"))
   })

   It("当数据校验返回错误为:岁数太小,不能小于18 时", func() {
    gomega.Expect(gopher.Validate(inputData[2])).Should(gomega.MatchError("岁数太小,不能小于18"))
   })
  })

  Context("当获取的数据校验成功时", func() {
   It("通过了数据校验", func() {
    gomega.Expect(gopher.Validate(inputData[3])).Should(gomega.BeNil())
   })
  })
 })

 AfterEach(func() {
  By("当测试不通过时,我会在这里打印一个消息 【AfterEach】")
 })
})

可以看到,BDD 风格的测试案例在代码中就被描述地非常清晰。由于我们的测试用例与预期相符,执行 <span style="font-size: 15px;">go test</span> 执行测试套件会校验通过。

 $ go test
Running Suite: Gopher Suite
===========================
Random Seed: 1629625854
Will run 5 of 5 specs

•••••
Ran 5 of 5 Specs in 0.000 seconds
SUCCESS! -- 5 Passed | 0 Failed | 0 Pending | 0 Skipped
PASS
ok      ginkgo/gopher   0.013s

读者可自行更改数据致测试不通过,你会看到 Ginkgo 将打印出堆栈与错误描述性信息。

Summary

TDD and BDD are methodologies often mentioned in agile development. Compared with TDD, BDD drives software development by writing behaviors and specifications. These behaviors and specifications are reflected in more "tedious" description information in the code.

There is another way to express the essence of BDD: BDD helps developers design software, and TDD helps developers test software.

Ginkgo is an excellent BDD framework in the Go language. It effectively helps developers organize and orchestrate test cases through DSL syntax (Describe/Context/It). This article only shows a very simple use case of Ginkgo, and should be used as a starting point.

Readers need to understand its execution life cycle when using Ginkgo. The key points include <span style="font-size: 15px;">It, Context, Describe, BeforeEach, AfterEach, JustBeforeEach, BeforeSuite, AfterSuite, By, Fail</span> The execution sequence and semantic logic of these modules.

Ginkgo has many features that are not covered in this article, such as asynchronous testing, benchmark testing, continuous integration and other powerful support. Its warehouse is located at https://github.com/onsi/ginkgo. It also provides English and Chinese versions of usage documentation. Readers can learn more about Ginkgo.

Finally, the Ginkgo framework is also used in the K8s project to write its end-to-end (E2E) tests Use cases are worth learning from.

The above is the detailed content of Ginkgo: a BDD Go language framework. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:Go语言进阶学习. If there is any infringement, please contact admin@php.cn delete