onsi/ginkgo
GitHub: onsi/ginkgo
Ginkgo 是一个构建于 Go 标准 testing 包之上的 BDD 风格测试框架,通过富有表现力的 DSL 帮助开发者编写可读性强、可并行运行的测试用例。
Stars: 9033 | Forks: 704

[](https://github.com/onsi/ginkgo/actions?query=workflow%3Atest+branch%3Amaster) | [Ginkgo 文档](https://onsi.github.io/ginkgo/)
# Ginkgo
Ginkgo 是一个成熟的 Go 测试框架,旨在帮助你编写富有表现力的测试用例(specs)。Ginkgo 构建于 Go 的 `testing` 基础之上,并由 [Gomega](https://github.com/onsi/gomega) 匹配器库作为补充。结合使用 Ginkgo 和 Gomega,可以让你清晰地表达测试用例背后的意图:
```
import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
...
)
var _ = Describe("Checking books out of the library", Label("library"), func() {
var library *libraries.Library
var book *books.Book
var valjean *users.User
BeforeEach(func() {
library = libraries.NewClient()
book = &books.Book{
Title: "Les Miserables",
Author: "Victor Hugo",
}
valjean = users.NewUser("Jean Valjean")
})
When("the library has the book in question", func() {
BeforeEach(func(ctx SpecContext) {
Expect(library.Store(ctx, book)).To(Succeed())
})
Context("and the book is available", func() {
It("lends it to the reader", func(ctx SpecContext) {
Expect(valjean.Checkout(ctx, library, "Les Miserables")).To(Succeed())
Expect(valjean.Books()).To(ContainElement(book))
Expect(library.UserWithBook(ctx, book)).To(Equal(valjean))
}, SpecTimeout(time.Second * 5))
})
Context("but the book has already been checked out", func() {
var javert *users.User
BeforeEach(func(ctx SpecContext) {
javert = users.NewUser("Javert")
Expect(javert.Checkout(ctx, library, "Les Miserables")).To(Succeed())
})
It("tells the user", func(ctx SpecContext) {
err := valjean.Checkout(ctx, library, "Les Miserables")
Expect(err).To(MatchError("Les Miserables is currently checked out"))
}, SpecTimeout(time.Second * 5))
It("lets the user place a hold and get notified later", func(ctx SpecContext) {
Expect(valjean.Hold(ctx, library, "Les Miserables")).To(Succeed())
Expect(valjean.Holds(ctx)).To(ContainElement(book))
By("when Javert returns the book")
Expect(javert.Return(ctx, library, book)).To(Succeed())
By("it eventually informs Valjean")
notification := "Les Miserables is ready for pick up"
Eventually(ctx, valjean.Notifications).Should(ContainElement(notification))
Expect(valjean.Checkout(ctx, library, "Les Miserables")).To(Succeed())
Expect(valjean.Books(ctx)).To(ContainElement(book))
Expect(valjean.Holds(ctx)).To(BeEmpty())
}, SpecTimeout(time.Second * 10))
})
})
When("the library does not have the book in question", func() {
It("tells the reader the book is unavailable", func(ctx SpecContext) {
err := valjean.Checkout(ctx, library, "Les Miserables")
Expect(err).To(MatchError("Les Miserables is not in the library catalog"))
}, SpecTimeout(time.Second * 5))
})
})
```
跳转到[文档](https://onsi.github.io/ginkgo/)了解更多。你可以轻松地[初始化](https://onsi.github.io/ginkgo/#bootstrapping-a-suite)并开始编写你的[第一个测试用例](https://onsi.github.io/ginkgo/#adding-specs-to-a-suite)。
如果你有任何问题、建议、Bug 报告或功能需求等,请提交一个 [GitHub issue](https://github.com/onsi/ginkgo/issues/new),或访问 [Ginkgo Slack 频道](https://app.slack.com/client/T029RQSE6/CQQ50BBNW)。
## 功能特性
无论是编写基础单元测试、复杂的集成测试,还是性能测试,Ginkgo 都为你提供了一套富有表现力的领域特定语言(DSL)。对于熟悉 [Quick](https://github.com/Quick/Quick)、[RSpec](https://rspec.info)、[Jasmine](https://jasmine.github.io) 和 [Busted](https://lunarmodules.github.io/busted/) 等框架的用户来说,这套 DSL 会显得非常亲切。这种测试风格有时被称为“行为驱动开发”(BDD),尽管 Ginkgo 的实用性早已超越了验收级别的测试。
使用 Ginkgo 的 DSL,你可以通过嵌套的 [`Describe`、`Context` 和 `When` 容器节点](https://onsi.github.io/ginkgo/#organizing-specs-with-container-nodes)来组织你的测试用例。使用 [`BeforeEach` 和 `AfterEach` setup 节点](https://onsi.github.io/ginkgo/#extracting-common-setup-beforeeach)进行前置准备和清理。使用承载断言的 [`It` 和 `Specify` 主题节点](https://onsi.github.io/ginkgo/#spec-subjects-it)。使用 [`BeforeSuite` 和 `AfterSuite` 节点](https://onsi.github.io/ginkgo/#suite-setup-and-cleanup-beforesuite-and-aftersuite)在整个测试套件(suite)运行前后进行准备和清理……还有[更多功能!](https://onsi.github.io/ginkgo/#writing-specs)。
```
ginkgo -p
```
通过遵循[编写并行测试用例的既有模式](https://onsi.github.io/ginkgo/#patterns-for-parallel-integration-specs),你甚至可以构建庞大且复杂的集成测试套件,这些套件能够被完美并行化并高效运行。而且你不必担心测试套件会卡住或遗留资源泄漏问题——Ginkgo 为每个节点提供了 `context.Context`,并具备在设定时间后中断测试用例并随后进行清理的能力。
随着测试套件的增长,Ginkgo 借助[标签](https://onsi.github.io/ginkgo/#spec-labels)帮助你保持测试用例的井然有序,并允许你轻松运行[测试用例子集](https://onsi.github.io/ginkgo/#filtering-specs),无论是通过[编程方式](https://onsi.github.io/ginkgo/#focused-specs)还是在[命令行](https://onsi.github.io/ginkgo/#combining-filters)中执行。此外,Ginkgo 的报告基础架构可以生成[多种格式](https://onsi.github.io/ginkgo/#generating-machine-readable-reports)的机器可读输出,_并且_允许你构建自己的[自定义报告系统](https://onsi.github.io/ginkgo/#generating-reports-programmatically)。
这仅仅是 Ginkgo 为你的测试套件带来了一系列丰富且成熟的[断言和匹配器](https://onsi.github.io/gomega/#provided-matchers)。借助 Gomega,你可以轻松地在测试用例中混合使用[同步和异步断言](https://onsi.github.io/ginkgo/#patterns-for-asynchronous-testing)。你甚至可以通过组合 Gomega 的[现有基础组件](https://onsi.github.io/ginkgo/#building-custom-matchers),快速且轻松地构建出一套适合你领域的、富有表现力的自定义匹配器。
祝测试愉快!
## 结合 Claude Code 使用 Ginkgo
Ginkgo 内置了一组 [Claude Code](https://claude.com/claude-code) 技能作为插件提供,并将此仓库作为插件市场。因此,在你的项目中编写测试用例的代理(agent)可以直接调用 Ginkgo 的惯用法、装饰器和注意事项。在 Claude Code 中执行以下命令:
```
/plugin marketplace add onsi/ginkgo
/plugin install ginkgo@ginkgo
```
(或者以非交互式方式执行:`claude plugin marketplace add onsi/ginkgo`,然后执行 `claude plugin install ginkgo@ginkgo`)
此操作将安装一系列 `ginkgo:*` 技能,这些技能会在你编写和运行测试用例时自动激活。建议从 `ginkgo:overview` 开始;完整列表请查看[插件 README](plugins/ginkgo/README.md)。
## 开源协议
Ginkgo 采用 MIT 许可证
标签:EVTX分析, 日志审计