Go 项目测试报告利器:Allure Go 入门指南
本文你将学到:
- 🤔 什么是 Allure 和
allure-go
? - 🛠️ 如何配置你的开发环境。
- ✍️ 编写你的第一个使用
allure-go
的测试。 - 🚀 运行测试并生成精美的 Allure 报告。
- 📊 解读 Allure 报告的关键部分。
- ⚡ 如何利用 Go 的特性并行运行测试,提升效率。
准备好了吗?让我们开始 Go 测试报告的魅力之旅吧!🚀💖
🤔 什么是 Allure?
Allure Framework 是一个灵活的、支持多种语言的测试报告神器 🏆。它不仅仅是展示测试通过 ✅ 或失败 ❌,更能提供一个包含测试步骤 🚶♀️、日志 📝、附件 📎、历史趋势 📈、环境信息 🖥️ 等丰富内容的交互式 Web 报告。这对于理解测试细节、快速定位问题 🔍、团队协作 🤝 都非常有帮助!
🤔 什么是 allure-go
?
allure-go
是由 Ozon Tech 团队 👨💻👩💻 开发和维护的项目,它为 Go 语言提供了完整的 Allure 功能集成。它旨在不增加开发者过多心智负担的前提下,将 Allure 的强大报告能力带入 Go 的测试生态。你可以用它来:
- 🗂️ 组织测试套件 (Test Suites)。
- 📝 定义详细的测试步骤 (Steps)。
- 🏷️ 添加丰富的元数据(如标题、描述、负责人、严重性、标签、链接等)。
- 📄 在报告中附加各种类型的文件(文本、JSON、图片等)。
- 💨 利用 Go 的并发特性并行执行测试。
🛠️ 准备工作:环境配置
在开始编写代码之前,确保你的开发环境满足以下条件:
- Go 语言环境: 安装 Go 1.18 或更高版本 🟢。
- 检查方法:在终端输入
go version
。go version go1.24.3 windows/amd64
- 安装指南:Go 官网下载 🔗
- 检查方法:在终端输入
- Allure 命令行工具 (Allure Commandline): 这个工具用于将
allure-go
生成的 JSON 结果文件转换成 HTML 报告 📊。- 检查方法:在终端输入
allure --version
。 - 安装指南:
- macOS (Homebrew):
brew install allure
🍎 - Windows (Scoop):
scoop install allure
🪟 - Linux / 手动: 参考 Allure 官方文档 🐧 / 手动 💪
- 检查是否成功:终端输入
allure --version
,看到版本号就 OK 👌!
- macOS (Homebrew):
- 检查方法:在终端输入
环境就绪!让我们开始写代码吧 ⌨️。
✍️ 你的第一个 Allure Go 测试:Hello World! 👋🌍
我们将使用 allure-go
提供的 suite
(测试套件)结构来组织我们的第一个测试。这是一种常见的、结构化的方式。
1. 创建项目目录和文件 📂
在你的工作区创建一个项目目录,例如 my-allure-app
,然后在里面创建一个用于存放测试代码的子目录,例如 tests
。在 tests
目录中,创建一个测试文件 simple_suite_test.go
。
my-allure-app/
├── go.mod (稍后生成)
└── tests/
└── simple_suite_test.go
2. 编写测试代码 (simple_suite_test.go
) 📝
// 文件名: simple_suite_test.go
package simple_test // 使用一个简单的包名
import (
"testing" // Go 标准测试库
// Allure Go 框架的核心包
"github.com/ozontech/allure-go/pkg/framework/provider"
"github.com/ozontech/allure-go/pkg/framework/suite"
)
// --- 定义一个简单的测试套件 ---
type SimpleSuite struct {
suite.Suite // 嵌入 allure-go 基础套件
}
// --- 一个简单的测试方法 ---
func (s *SimpleSuite) TestHelloWorld(t provider.T) {
// 添加 Allure 元数据
t.Epic("入门示例")
t.Feature("基本功能")
t.Title("简单问候测试")
t.Description("这是一个演示 allure-go 基本用法的最简单测试。")
t.Tags("smoke", "simple") // 添加标签
// 添加一个测试步骤
t.WithNewStep("执行问候并验证", func(sCtx provider.StepCtx) {
sCtx.Log("准备生成问候语...") // 在步骤中打印日志
greeting := "Hello, Allure!"
expected := "Hello, Allure!"
sCtx.Logf("生成的问候语: %s", greeting) // 带格式的日志
// 执行断言 (会自动记录为子步骤)
// t.Require() 中的断言如果失败,会停止当前测试
sCtx.Require().Equal(expected, greeting, "问候语应该匹配预期值")
sCtx.Log("验证成功!")
})
// 测试方法级别的日志
t.Log("TestHelloWorld 测试完成。")
}
// --- 套件运行器 ---
// 这是 Go testing 包识别并执行测试套件的入口函数
func TestRunSimpleSuite(t *testing.T) {
// 使用 suite.RunSuite 运行我们定义的 SimpleSuite
suite.RunSuite(t, new(SimpleSuite))
}
代码详解 (带 Emoji 版 😉):
package simple_test
: 定义包名,测试文件通常使用_test
后缀 🏷️。import (...)
:testing
: Go 标准库,测试的基础 🧱。github.com/ozontech/allure-go/pkg/framework/provider
: 提供了provider.T
类型,它是 allure-go 增强的测试上下文,包含了添加元数据、步骤等方法 ✨。github.com/ozontech/allure-go/pkg/framework/suite
: 提供了suite.Suite
结构,用于组织测试套件 🗂️。github.com/ozontech/allure-go/pkg/allure
: 包含了 Allure 的数据模型和常量,如Severity
、LinkType
等 🌟。
type SimpleSuite struct { suite.Suite }
: 定义了一个名为SimpleSuite
的结构体,通过嵌入suite.Suite
来继承 allure-go 套件的功能 💪。func (s *SimpleSuite) TestHelloWorld(t provider.T)
: 定义了一个测试方法 🧪。- 方法必须是套件(
*SimpleSuite
)的成员。 - 方法名必须以
Test
开头 ✍️。 - 接收一个
provider.T
类型的参数t
,我们通过t
来与 Allure 交互 🤝。
- 方法必须是套件(
t.Epic()
,t.Feature()
,t.Title()
,t.Description()
,t.Tags()
,t.SetSeverity()
,t.Owner()
: 这些方法用于给测试用例添加各种元数据,让报告更具可读性 👀。t.WithNewStep("步骤名", func(sCtx provider.StepCtx) { ... })
: 创建一个命名的测试步骤 🚶。步骤内的代码会在一个闭包函数中执行。sCtx
是步骤的上下文 📜。sCtx.Log()
,sCtx.Logf()
,sCtx.WithNewParameters()
: 在步骤内部记录信息和参数 📝。sCtx.Require().Equal(...)
: 这是testify
库提供的断言方法,allure-go
对其进行了包装 🎁。每次断言都会在 Allure 报告中自动生成一个子步骤,显示断言的操作和结果 ✅/❌。Require
在失败时会中断测试 🛑。func TestRunSimpleSuite(t *testing.T)
: 这是 Go testing 能识别的入口函数 ▶️。suite.RunSuite(t, new(SimpleSuite))
:allure-go
提供的函数,用于执行指定套件 (SimpleSuite
) 中的所有Test
开头的方法 🏃♀️。
🚀 运行测试并生成报告 📊
现在代码写好了,让我们来运行它!
- 打开终端/命令行 💻,进入你的项目根目录 (
my-allure-app
)。 - 初始化 Go 模块 (如果还没有
go.mod
文件):go mod init my-allure-app # 将 my-allure-app 替换为你的模块名
- 下载依赖:
go mod tidy
会自动分析代码并下载所有需要的库 (allure-go
,testify
等) 📦。go mod tidy
- 运行 Go 测试: 执行
go test
命令,并指向包含测试文件的包 🎯。go test
./tests/...
表示运行tests
目录及其所有子目录下的测试 🔄。- 成功运行后,你应该会看到类似
PASS
或ok testg/tests ...
的输出 ✅。 - 关键: 在项目根目录 (
my-allure-app
) 下,你会发现一个新生成的allure-results
文件夹 📁。这里面存放着测试过程中产生的 JSON 格式的原始结果文件 📄。
- 生成 Allure 报告: 使用
allure
命令行工具处理allure-results
✨。allure generate allure-results --clean
allure generate
是生成报告的命令。allure-results
是输入目录。--clean
(可选) 会先清除之前生成的报告 🧹。- 此命令会在当前目录下生成一个
allure-report
文件夹,里面是 HTML 报告 🌐。
- 打开 Allure 报告:
allure open
- 此命令会启动一个本地 Web 服务器,并在你的默认浏览器中打开报告!🎉
现在,你应该能看到一个漂亮的 Allure 报告页面了!🤩
🧐 解读 Allure 报告
打开报告后,你会看到很多有用的信息:
- Overview 📊: 报告的概览,显示测试总数、通过率、失败率、以及各种元数据(如 Epic, Feature)的分布饼图 पाई।
- Suites 🗂️: 按测试套件(我们例子中的
SimpleSuite
)和测试方法(TestHelloWorld
)组织的树状结构。点击测试方法可以查看其详细信息。 - Behaviors 🎭: 按 Epic -> Feature -> Story 组织的视图,适合从功能角度查看测试覆盖。
- Graphs 📈: 提供各种维度的统计图表,如按状态、严重性、执行时间分布等。
- Timeline ⏳: 显示测试用例的执行时间线,对于识别性能瓶颈和观察并行执行效果很有用。
点击我们运行的 TestHelloWorld
,你会看到:
- 左侧是测试的元数据(描述、严重性、负责人、标签等)🏷️。
- 右侧是测试的执行细节:
- 清晰的测试步骤("执行问候并验证")🚶♀️。
- 步骤内的日志 (
sCtx.Log
输出) 📝。 - 步骤参数 📊。
- 断言自动生成的子步骤 (
Require.Equal
) 及其状态 ✅。
花点时间探索一下报告的各个部分,感受它的强大之处吧!💪
⚡ 更进一步:并行测试 💨
当测试用例数量增多时 📈,顺序执行会变得很慢 🐌。Go 语言天生擅长并发 🚀,allure-go
也很好地支持了利用 Go 的 t.Parallel()
来并行执行测试用例,从而大大缩短总测试时间 ⏱️!
如何实现?
非常简单!只需要在你想并行执行的测试方法内部,调用 t.Parallel()
即可。就这么 Easy!😎
示例代码 (parallel_suite_test.go
)
在 tests
目录下创建新文件 parallel_suite_test.go
:
// 文件名: parallel_suite_test.go
package parallel_test
import (
"testing"
"time" // 引入 time 包来模拟耗时操作
"github.com/ozontech/allure-go/pkg/framework/provider"
"github.com/ozontech/allure-go/pkg/framework/suite"
)
// --- 定义并行测试套件 ---
type ParallelSuite struct {
suite.Suite // 嵌入基础套件
}
// --- 测试方法 1 ---
func (s *ParallelSuite) TestOne(t provider.T) {
// !!! 标记此测试可以与其他 Parallel 测试并发运行 !!!
t.Parallel()
// 添加 Allure 元数据
t.Epic("并发执行示例")
t.Feature("并行测试")
t.Title("并行测试用例 1")
t.Description("这个测试会模拟一些耗时操作,并与其他测试并行执行。")
t.Tags("parallel", "test1")
t.WithNewStep("步骤 A - 测试 1", func(sCtx provider.StepCtx) {
sCtx.Log("开始执行测试 1 的步骤 A...")
// 模拟耗时 1 秒
time.Sleep(1 * time.Second)
sCtx.Log("步骤 A 完成。")
sCtx.Require().True(true, "简单断言") // 添加一个简单断言
})
t.WithNewStep("步骤 B - 测试 1", func(sCtx provider.StepCtx) {
sCtx.Log("开始执行测试 1 的步骤 B...")
// 模拟耗时 1.5 秒
time.Sleep(1500 * time.Millisecond)
sCtx.Log("步骤 B 完成。")
})
t.Logf("并行测试用例 1 (TestOne) 完成 @ %s", time.Now().Format(time.RFC3339Nano))
}
// --- 测试方法 2 ---
func (s *ParallelSuite) TestTwo(t provider.T) {
// !!! 标记此测试可以与其他 Parallel 测试并发运行 !!!
t.Parallel()
// 添加 Allure 元数据
t.Epic("并发执行示例")
t.Feature("并行测试")
t.Title("并行测试用例 2")
t.Description("这是另一个并行执行的测试用例。")
t.Tags("parallel", "test2")
t.WithNewStep("步骤 X - 测试 2", func(sCtx provider.StepCtx) {
sCtx.Log("开始执行测试 2 的步骤 X...")
// 模拟耗时 2 秒
time.Sleep(2 * time.Second)
sCtx.Log("步骤 X 完成。")
})
t.Logf("并行测试用例 2 (TestTwo) 完成 @ %s", time.Now().Format(time.RFC3339Nano))
}
// --- 测试方法 3 (不使用 Parallel) ---
func (s *ParallelSuite) TestThreeSequential(t provider.T) {
// !!! 这个测试没有调用 t.Parallel(),它会等待前面的并行测试完成后再顺序执行 !!!
// 或者,如果它在所有 Parallel 测试之前被调度,其他 Parallel 测试会等它完成。
// Go 的测试调度器会管理这些。
t.Epic("并发执行示例")
t.Feature("顺序测试")
t.Title("顺序执行的测试用例 3")
t.Description("这个测试没有标记为并行,会按顺序执行。")
t.Tags("sequential", "test3")
t.WithNewStep("步骤 Z - 测试 3", func(sCtx provider.StepCtx) {
sCtx.Log("开始执行顺序测试 3 的步骤 Z...")
// 模拟耗时 0.5 秒
time.Sleep(500 * time.Millisecond)
sCtx.Log("步骤 Z 完成。")
})
t.Logf("顺序测试用例 3 (TestThreeSequential) 完成 @ %s", time.Now().Format(time.RFC3339Nano))
}
// --- 套件运行器 ---
func TestRunParallelSuite(t *testing.T) {
// 运行 ParallelSuite 套件
// Go 的 testing 包会自动处理 t.Parallel() 的调度
suite.RunSuite(t, new(ParallelSuite))
}
代码解释 (带 Emoji 版 😉):
- 我们在
TestParallelOne
和TestParallelTwo
的开头调用了t.Parallel()
✨。 TestSequentialThree
没有调用t.Parallel()
,它会顺序执行 🚶♂️。- 我们使用
time.Sleep()
模拟耗时操作 ⏳,以便观察并行效果。
运行并行测试:
- 保存文件
parallel_suite_test.go
💾。 - 同步依赖 (如果需要):
go mod tidy
📦。 - 运行测试 (建议加
-v
查看详细日志):go test -v
- 观察控制台输出 👀,你可能会看到
TestParallelOne
和TestParallelTwo
的日志交错出现 🔀,它们的完成时间戳可能非常接近 🤏。 - 注意观察
go test
命令执行的总时间 ⏱️。如果测试是顺序执行的,总时间大约是 1s + 1.5s + 0.5s = 3s。但并行执行后,总时间应该会明显缩短(接近于最长并行测试的时间 1.5s 加上顺序测试的时间 0.5s,大约 2s 左右)⚡️! - === RUN TestRunParallelSuite
=== RUN TestRunParallelSuite/ParallelSuite
=== RUN TestRunParallelSuite/ParallelSuite/Tests
=== RUN TestRunParallelSuite/ParallelSuite/Tests/TestOne
=== PAUSE TestRunParallelSuite/ParallelSuite/Tests/TestOne
=== RUN TestRunParallelSuite/ParallelSuite/Tests/TestThreeSequential
main_test.go:82: 开始执行顺序测试 3 的步骤 Z...
main_test.go:85: 步骤 Z 完成。
main_test.go:88: 顺序测试用例 3 (TestThreeSequential) 完成 @ 2025-05-12T21:06:27.6568988+08:00
=== RUN TestRunParallelSuite/ParallelSuite/Tests/TestTwo
=== PAUSE TestRunParallelSuite/ParallelSuite/Tests/TestTwo
=== CONT TestRunParallelSuite/ParallelSuite/Tests/TestOne
=== CONT TestRunParallelSuite/ParallelSuite/Tests/TestTwo
=== NAME TestRunParallelSuite/ParallelSuite/Tests/TestOne
main_test.go:30: 开始执行测试 1 的步骤 A...
=== NAME TestRunParallelSuite/ParallelSuite/Tests/TestTwo
main_test.go:60: 开始执行测试 2 的步骤 X...
=== NAME TestRunParallelSuite/ParallelSuite/Tests/TestOne
main_test.go:33: 步骤 A 完成。
main_test.go:38: 开始执行测试 1 的步骤 B...
=== NAME TestRunParallelSuite/ParallelSuite/Tests/TestTwo
main_test.go:63: 步骤 X 完成。
main_test.go:66: 并行测试用例 2 (TestTwo) 完成 @ 2025-05-12T21:06:29.6716268+08:00
=== NAME TestRunParallelSuite/ParallelSuite/Tests/TestOne
main_test.go:41: 步骤 B 完成。
main_test.go:44: 并行测试用例 1 (TestOne) 完成 @ 2025-05-12T21:06:30.1722998+08:00
--- PASS: TestRunParallelSuite (3.02s)
--- PASS: TestRunParallelSuite/ParallelSuite (3.02s)
--- PASS: TestRunParallelSuite/ParallelSuite/Tests (0.52s)
--- PASS: TestRunParallelSuite/ParallelSuite/Tests/TestThreeSequential (0.51s)
--- PASS: TestRunParallelSuite/ParallelSuite/Tests/TestTwo (2.00s)
--- PASS: TestRunParallelSuite/ParallelSuite/Tests/TestOne (2.50s)
PASS
ok testg 3.649s
- 观察控制台输出 👀,你可能会看到
- 生成并查看报告:
allure generate allure-results --clean allure open
- 在 Allure 报告的 Timeline ⏳ 视图中,你可以清晰地看到
TestParallelOne
和TestParallelTwo
的执行时间条有重叠 ⏸️⏸️,而TestSequentialThree
则在它们之后(或之前)执行,没有重叠 ➖。
- 在 Allure 报告的 Timeline ⏳ 视图中,你可以清晰地看到
通过 t.Parallel()
,你可以轻松地让你的 Go 测试跑得更快!💨💨💨
● Allure
🏠 Overview
🚩 Categories
💼 Suites
📊 Graphs
⏱️ Timeline
🏷️ Behaviors
📦 Packages
|
ALLURE REPORT 5/12/202520:28:18 - 20:30:18 (1m 59s) 4
test cases
100%
|
总结与展望 🎓🔭
恭喜你!🥳 你已经成功入门了 allure-go
,掌握了:
- 🛠️ 配置环境和依赖。
- ✍️ 使用
suite
结构编写测试。 - 🏷️ 添加 Allure 元数据和测试步骤。
- 🚀 运行测试并生成、查看 Allure 报告。
- ⚡ 利用
t.Parallel()
实现测试并行化。
allure-go
的功能远不止这些,你还可以探索:
- 更丰富的元数据:
t.SetIssue()
(关联 JIRA 等 🐞),t.SetTestCase()
(关联 TestRail 等 ✅),t.SetLink()
(添加文档链接 🔗) 等。 - 附件: 使用
t.Attachment()
或sCtx.Attachment()
添加截图 🖼️、日志文件 📄、API 请求/响应体 <-> 等。 - 参数化测试:
allure-go
提供了强大的参数化测试功能 🔢,可以轻松实现数据驱动测试。 - Setup/Teardown 钩子:
BeforeAll
☀️,AfterAll
🌙,BeforeEach
✨,AfterEach
🧹 用于在测试套件或测试方法执行前后进行准备和清理工作。
希望这篇入门指南能帮助你开启使用 allure-go
提升 Go 项目测试质量和效率的大门🚪。建议查阅 allure-go 的官方 GitHub 仓库 获取更详细的文档和示例 📚。
本文作者: 永生
本文链接: https://yys.zone/detail/?id=419
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
评论列表 (0 条评论)