Maison > développement back-end > Golang > le corps du texte

Ginkgo : un framework de langage BDD Go

Libérer: 2023-07-25 14:32:48
avant
955 Les gens l'ont consulté

Les tests unitaires se concentrent sur l'unité logique du code, qui est généralement un objet ou une fonction spécifique. Nous pouvons écrire suffisamment de tests unitaires pour garantir la qualité du code. Lorsque les fonctions sont modifiées ou que le code est refactorisé, suffisamment de cas de tests unitaires peuvent nous donner suffisamment de confiance.

Les tests unitaires ci-dessus se trouvent les spécifications de développement. Dans le développement logiciel agile, il y a deux visiteurs fréquents : le développement piloté par les tests (TDD) et le développement piloté par le comportement (BDD). Ce sont des pratiques et des techniques, mais aussi des méthodologies de conception.

TDD

L'idée de base de TDD est de promouvoir l'ensemble du développement par le biais de tests. Le principe est d'écrire des cas de tests unitaires avant de développer du code fonctionnel. Contient les cinq étapes suivantes :

  • Les développeurs écrivent d'abord quelques cas de test
  • Exécutez ces tests, mais ces tests échoueront évidemment car la logique métier dans les cas de test n'a pas été implémentée
  • Détails du code d'implémentation
  • Si le développeur implémente avec succès le code, tous les tests réussiront
  • Refactorisez le code métier en temps opportun Si la nouvelle fonction du code est incorrecte, le fichier de test correspondant. Il échouera également

Lorsque de nouvelles fonctionnalités doivent être développées, répétez les étapes ci-dessus. Le processus est illustré dans la figure ci-dessous

Ginkgo : un framework de langage BDD Go

tdd-flowchart

Il existe un référentiel Github qui est plus intéressant : learn-go-with-tests , qui est conçu pour apprendre le TDD via Go.

BDD

TDD se concentre sur le développement et utilise des cas de test pour réglementer et contraindre les développeurs à écrire du code de meilleure qualité et moins bogué. BDD se concentre davantage sur la conception, qui nécessite que le système soit défini lors de la conception des cas de test, préconise l'utilisation d'un langage commun pour décrire le comportement du système et la combinaison de la conception du système et des cas de test pour piloter le travail de développement.

BDD est dérivé de TDD, La principale différence réside dans la description du test. BDD utilise un langage plus compréhensible pour décrire les cas de test, en se concentrant davantage sur les fonctionnalités requises plutôt que sur les résultats réels.

La capacité donnée par BDD de lire les tests comme des phrases entraîne un changement dans la perception des tests et nous aide à réfléchir à la façon de mieux rédiger les tests.

Ginkgo

Ginkgo est un framework de test BDD en langage Go, conçu pour aider les développeurs à écrire des tests complets et expressifs.

Ginkgo intègre le natif de Go <code style='font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;background: rgba(14, 210, 247, 0.15);'><span style="font-size: 15px;">testing</span> 库,这意味着你可以通过 <span style="font-size: 15px;">go test</span> 来运行 Ginkgo 测试套件。同时,它与断言和 mock 套件 testify 、富测试集 go-check 同样兼容。但 Ginkgo 建议的是搭配 gomega 库一起使用。

下面,我们使用 Ginkgo 来感受一下 BDD 模式的测试代码。

下载

使用 <span style="font-size: 15px;">go get</span>testing bibliothèque , ce qui signifie que vous pouvez transmettre

🎜go test🎜 🎜 à exécuter la suite de tests Ginkgo. En même temps, il est également compatible avec la suite d'assertions et de simulations 🎜🎜testify🎜🎜 et la suite de tests riches 🎜🎜go-check🎜🎜. Mais ce que Ginkgo recommande, c'est de l'utiliser avec la bibliothèque 🎜🎜gomega🎜🎜. 🎜🎜🎜🎜 Ensuite, nous utilisons Ginkgo pour expérimenter le code de test du mode BDD. 🎜🎜
Télécharger
🎜🎜Utiliser🎜🎜go get🎜🎜 get🎜🎜
$ go get github.com/onsi/ginkgo/ginkgo
$ go get github.com/onsi/gomega/...
Copier après la connexion

该命令获取 ginkgo 并安装 <code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;background: rgba(14, 210, 247, 0.15);"><span style="font-size: 15px;">ginkgo</span> 可执行文件到 <span style="font-size: 15px;">$GOPATH/bin</span>

创建套件

创建 gopher 库

$ cd path-to-package/gopher
Copier après la connexion

<span style="font-size: 15px;">gopher.go</span> 文件中,有 <span style="font-size: 15px;">Gopher</span> 结构体与校验方法 <span style="font-size: 15px;">Validate</span> 如下

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
}
Copier après la connexion

我们通过 <span style="font-size: 15px;">ginkgo bootstrap</span> 命令,来初始化一个 Ginkgo 测试套件。

$ ginkgo bootstrap
Generating ginkgo test suite bootstrap for gopher in:
        gopher_suite_test.go
Copier après la connexion

此时在 <span style="font-size: 15px;">gopher.go</span> 同级目录中,生成了 <span style="font-size: 15px;">gopher_suite_test.go</span>ginkgo可执行文件到

🎜$GOPATH/bin🎜🎜 。🎜 🎜
创建套件
🎜🎜创建 gopher 库🎜🎜
package gopher_test

import (
 "testing"

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

func TestGopher(t *testing.T) {
 RegisterFailHandler(Fail)
 RunSpecs(t, "Gopher Suite")
}
Copier après la connexion
Copier après la connexion
🎜 🎜在 🎜🎜gopher.go🎜🎜 文件中,有 🎜 🎜Gopher🎜🎜 结构体与校验方法 🎜 🎜ginkgo bootstrap🎜 🎜 命令 , 来 初 始化 一 个 个 个 个 测试 套件 。🎜🎜
 $ 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
Copier après la connexion
Copier après la connexion
🎜 🎜此时在 🎜🎜gopher.go🎜🎜 同级目录中,生成了 🎜🎜gopher_suite_test.go🎜🎜 文件,内容如下🎜🎜
package gopher_test

import (
 "testing"

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

func TestGopher(t *testing.T) {
 RegisterFailHandler(Fail)
 RunSpecs(t, "Gopher Suite")
}
Copier après la connexion
Copier après la connexion

此时,我们就可以运行测试套件了,通过命令 <span style="font-size: 15px;">go test</span><code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;background: rgba(14, 210, 247, 0.15);"><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
Copier après la connexion
Copier après la connexion

当然,空测试套件没有什么价值,我们需要在此套件下编写测试(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
Copier après la connexion

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

package gopher_test

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

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

})
Copier après la connexion
编写 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】")
 })
})
Copier après la connexion

可以看到,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
Copier après la connexion

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

Résumé

TDD et BDD sont des méthodologies couramment mentionnées dans le développement agile. Comparé à TDD, BDD pilote le développement de logiciels en écrivant des comportements et spécifications. Ces comportements et spécifications sont reflétés dans des informations de description plus "verbeuses" dans le code.

Il existe une autre façon d'exprimer l'essence de BDD : BDD aide les développeurs à concevoir des logiciels, et TDD aide les développeurs à tester des logiciels.

Ginkgo est un excellent framework BDD dans le langage Go. Il aide efficacement les développeurs à organiser et orchestrer des cas de test via la syntaxe DSL (Describe/Context/It). Cet article ne présente qu'un cas d'utilisation très simple de Ginkgo et doit être utilisé comme point de départ.

Les lecteurs doivent comprendre son cycle de vie d'exécution lorsqu'ils utilisent Ginkgo. Les points clés incluent <code style='font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;background: rgba(14, 210, 247, 0.15);'><span style="font-size: 15px;">It、Context、Describe、BeforeEach、AfterEach、JustBeforeEach、BeforeSuite、AfterSuite、By、Fail</span>It, Context, Describe, BeforeEach, AfterEach, JustBeforeEach, BeforeSuite, AfterSuite, By, Fail La séquence d'exécution et la logique sémantique de ces modules.

Ginkgo possède de nombreuses fonctionnalités qui ne sont pas couvertes dans cet article, telles que les tests asynchrones, les tests de référence, l'intégration continue et d'autres supports puissants. Son entrepôt est situé sur https://github.com/onsi/ginkgo. Il fournit également des versions anglaise et chinoise de la documentation d'utilisation. Les lecteurs peuvent l'utiliser pour en savoir plus sur le Ginkgo.

Enfin, le framework Ginkgo est également utilisé dans le projet K8s pour écrire ses cas de test de bout en bout (E2E), ce qui mérite d'être appris.

🎜

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:Go语言进阶学习
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!