golang实现Cucumber BDD测试框架的插件库godog的使用
Golang实现Cucumber BDD测试框架的插件库godog的使用
godog是Golang官方支持的Cucumber BDD框架,它将规范和测试文档合并为一个整体,使用Given/When/Then格式的Gherkin场景描述。
为什么选择Godog/Cucumber
单一真实来源
Godog将规范和测试文档合并为一个整体。
活文档
因为规范会被Godog自动测试,所以它们总是保持最新。
关注客户
业务和IT并不总是相互理解。Godog的可执行规范鼓励更紧密的协作,帮助团队始终牢记业务目标。
减少返工
当自动化测试如此有趣时,团队可以轻松保护自己免受昂贵的回归影响。
完整示例Demo
步骤1 - 创建Go模块
mkdir godogs
cd godogs
go mod init godogs
步骤2 - 创建Gherkin特性文件
创建features/godogs.feature
文件:
Feature: eat godogs
In order to be happy
As a hungry gopher
I need to be able to eat godogs
Scenario: Eat 5 out of 12
Given there are 12 godogs
When I eat 5
Then there should be 7 remaining
步骤3 - 创建godog步骤定义
创建godogs_test.go
文件:
package main
import (
"context"
"errors"
"fmt"
"testing"
"github.com/cucumber/godog"
)
// godogsCtxKey是用于在context.Context中存储可用godogs的键
type godogsCtxKey struct{}
func thereAreGodogs(ctx context.Context, available int) (context.Context, error) {
return context.WithValue(ctx, godogsCtxKey{}, available), nil
}
func iEat(ctx context.Context, num int) (context.Context, error) {
available, ok := ctx.Value(godogsCtxKey{}).(int)
if !ok {
return ctx, errors.New("there are no godogs available")
}
if available < num {
return ctx, fmt.Errorf("you cannot eat %d godogs, there are %d available", num, available)
}
available -= num
return context.WithValue(ctx, godogsCtxKey{}, available), nil
}
func thereShouldBeRemaining(ctx context.Context, remaining int) error {
available, ok := ctx.Value(godogsCtxKey{}).(int)
if !ok {
return errors.New("there are no godogs available")
}
if available != remaining {
return fmt.Errorf("expected %d godogs to be remaining, but there is %d", remaining, available)
}
return nil
}
func TestFeatures(t *testing.T) {
suite := godog.TestSuite{
ScenarioInitializer: InitializeScenario,
Options: &godog.Options{
Format: "pretty",
Paths: []string{"features"},
TestingT: t, // 将运行子测试的测试实例
},
}
if suite.Run() != 0 {
t.Fatal("non-zero status returned, failed to run feature tests")
}
}
func InitializeScenario(sc *godog.ScenarioContext) {
sc.Step(`^there are (\d+) godogs$`, thereAreGodogs)
sc.Step(`^I eat (\d+)$`, iEat)
sc.Step(`^there should be (\d+) remaining$`, thereShouldBeRemaining)
}
步骤4 - 创建主程序
创建godogs.go
文件:
package main
// Godogs available to eat
var Godogs int
func main() { /* usual main func */ }
步骤5 - 运行测试
运行测试命令:
go test -v godogs_test.go
你应该看到类似以下的输出:
=== RUN TestFeatures
Feature: eat godogs
In order to be happy
As a hungry gopher
I need to be able to eat godogs
=== RUN TestFeatures/Eat_5_out_of_12
Scenario: Eat 5 out of 12 # features/godogs.feature:6
Given there are 12 godogs # godog_test.go:15 -> command-line-arguments.thereAreGodogs
When I eat 5 # godog_test.go:19 -> command-line-arguments.iEat
Then there should be 7 remaining # godog_test.go:34 -> command-line-arguments.thereShouldBeRemaining
1 scenarios (1 passed)
3 steps (3 passed)
279.917µs
--- PASS: TestFeatures (0.00s)
--- PASS: TestFeatures/Eat_5_out_of_12 (0.00s)
PASS
ok command-line-arguments 0.164s
高级用法
使用TestMain运行测试套件
func TestMain(m *testing.M) {
opts := godog.Options{
Format: "progress",
Paths: []string{"features"},
Randomize: time.Now().UTC().UnixNano(), // 随机化场景执行顺序
}
status := godog.TestSuite{
Name: "godogs",
TestSuiteInitializer: InitializeTestSuite,
ScenarioInitializer: InitializeScenario,
Options: &opts,
}.Run()
// 可选:除了godog外运行testing包的逻辑
if st := m.Run(); st > status {
status = st
}
os.Exit(status)
}
使用标签过滤场景
你可以使用-t=<expression>
或--tags=<expression>
来过滤场景:
@wip
- 运行所有带有wip标签的场景~@wip
- 排除所有带有wip标签的场景@wip && ~@new
- 运行wip场景,但排除new场景@wip,@undone
- 运行wip或undone场景
使用断言库
func thereShouldBeRemaining(ctx context.Context, remaining int) error {
assert.Equal(
godog.T(ctx), Godogs, remaining,
"Expected %d godogs to be remaining, but there is %d", remaining, Godogs,
)
return nil
}
总结
Godog提供了一个强大的BDD测试框架,可以帮助团队更好地协作开发。通过Gherkin语法编写的测试用例既可作为文档,又可作为自动化测试,确保系统行为符合预期。
更多关于golang实现Cucumber BDD测试框架的插件库godog的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang实现Cucumber BDD测试框架的插件库godog的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用Godog实现Golang中的BDD测试
Godog是Golang的一个BDD(行为驱动开发)测试框架,它是Cucumber的Golang实现版本。下面我将详细介绍如何使用Godog来编写BDD测试。
1. 安装Godog
首先需要安装Godog包:
go get github.com/cucumber/godog/cmd/godog@latest
2. 基本使用
2.1 创建feature文件
在features
目录下创建.feature
文件,例如calculator.feature
:
Feature: Calculator
In order to avoid silly mistakes
As a math idiot
I want to be told the sum of two numbers
Scenario: Add two numbers
Given I have entered 50 into the calculator
And I have entered 70 into the calculator
When I press add
Then the result should be 120 on the screen
2.2 实现步骤定义
创建测试文件calculator_test.go
:
package main
import (
"github.com/cucumber/godog"
)
type calculator struct {
result int
}
func (c *calculator) iHaveEnteredIntoTheCalculator(arg1 int) error {
c.result = arg1
return nil
}
func (c *calculator) iPressAdd() error {
// 这里实现加法逻辑
// 示例中简化处理
c.result += c.result
return nil
}
func (c *calculator) theResultShouldBeOnTheScreen(arg1 int) error {
if c.result != arg1 {
return fmt.Errorf("expected %d, but got %d", arg1, c.result)
}
return nil
}
func InitializeScenario(ctx *godog.ScenarioContext) {
calc := &calculator{}
ctx.Step(`^I have entered (\d+) into the calculator$`, calc.iHaveEnteredIntoTheCalculator)
ctx.Step(`^I press add$`, calc.iPressAdd)
ctx.Step(`^the result should be (\d+) on the screen$`, calc.theResultShouldBeOnTheScreen)
}
2.3 创建测试入口
创建godog_test.go
文件:
package main
import (
"testing"
"github.com/cucumber/godog"
)
func TestFeatures(t *testing.T) {
suite := godog.TestSuite{
ScenarioInitializer: InitializeScenario,
Options: &godog.Options{
Format: "pretty",
Paths: []string{"features"},
TestingT: t,
},
}
if suite.Run() != 0 {
t.Fatal("non-zero status returned, failed to run feature tests")
}
}
3. 高级功能
3.1 使用表格数据
可以在feature文件中使用表格:
Scenario Outline: Add two numbers
Given I have entered <a> into the calculator
And I have entered <b> into the calculator
When I press add
Then the result should be <result> on the screen
Examples:
| a | b | result |
| 1 | 2 | 3 |
| 5 | 5 | 10 |
| 10 | 20 | 30 |
3.2 钩子函数
Godog支持多种钩子函数:
func InitializeScenario(ctx *godog.ScenarioContext) {
// 在场景开始前执行
ctx.BeforeScenario(func(sc *godog.Scenario) {
fmt.Println("Before scenario:", sc.Name)
})
// 在场景结束后执行
ctx.AfterScenario(func(sc *godog.Scenario, err error) {
fmt.Println("After scenario:", sc.Name, "with error:", err)
})
// 在步骤前执行
ctx.BeforeStep(func(st *godog.Step) {
fmt.Println("Before step:", st.Text)
})
// 在步骤后执行
ctx.AfterStep(func(st *godog.Step, err error) {
fmt.Println("After step:", st.Text, "with error:", err)
})
}
3.3 自定义输出格式
Godog支持多种输出格式:
suite := godog.TestSuite{
Options: &godog.Options{
Format: "junit", // 可以是pretty, progress, junit等
Output: colors.Colored(os.Stdout),
Paths: []string{"features"},
},
}
4. 运行测试
运行测试有两种方式:
- 使用go test:
go test -v
- 直接使用godog命令:
godog
5. 实际项目结构示例
project/
├── features/
│ ├── calculator.feature
│ └── other.feature
├── go.mod
├── go.sum
├── godog_test.go
└── internal/
└── calculator/
├── calculator.go
└── calculator_test.go
Godog是一个强大的BDD测试框架,可以帮助团队更好地协作,通过自然语言描述测试场景,同时保持测试代码的可维护性。它特别适合需要业务人员参与测试用例设计的项目。