当前位置:首页 > 文章列表 > Golang > Go问答 > Go testing.Short 怎样在集成测试中跳过慢用例

Go testing.Short 怎样在集成测试中跳过慢用例

来源:17golang原创 2026-11-02 02:34:36 0浏览 收藏

在 Go 集成测试的开头判断 testing.Short(),为 true 时调用 t.Skip("跳过原因"),再用 go test -short 执行,就能主动跳过这条慢用例。判断必须放在连接数据库、启动服务、创建容器或加载大数据之前;只传 -short,不在测试中响应它,Go 不会自动识别和过滤慢测试。

官方文档:https://pkg.go.dev/testing

先把慢用例变成显式的短模式分支

一个包里同时有字符串处理的快速断言和依赖服务的集成用例,开发时通常希望先拿到快速反馈。这里的“短”是项目作者定义的运行策略,而不是执行器根据耗时排名计算出来的分类。文件叫 integration_test.go、函数名带 Integration,都不会自动获得跳过行为。

短模式也可以让某些穷举测试缩小数据规模,但本文只处理整条慢用例跳过:快速用例照常执行,明确标记的集成用例给出可见的 SKIP 原因。完整流水线仍要安排不启用短模式的任务,避免集成覆盖长期消失。

最小写法只需要 Short 和 Skip

在已有测试文件中引入 testing 后,把下面的判断放在测试函数最前面即可。这个最小片段只展示入口;它末尾的注释需要替换为真正的集成准备和断言,不能将空测试当作完成了业务验证。

func TestSnapshotIntegration(t *testing.T) {
    // 在创建测试服务、连接数据库或加载大数据之前判断。
    if testing.Short() {
        t.Skip("短模式跳过快照集成测试")
    }
    // 此处继续编写集成测试的准备与断言。
}

testing.Short 读取测试短模式标志,t.Skip 则记录原因并终止当前测试的执行。直接 return 只会正常返回,不产生跳过标记,读者在日志中容易把它误认为已完成断言。相关 API 和行为见官方 testing 文档。

图中“运行设置”包含-short 标志、testing.Short,“测试入口”包含集成测试、t.Skip,“测试资源”包含昂贵初始化、资源清理。标志与 Short 是配置关联;集成测试依赖判断、跳过入口及资源准备,资源清理与昂贵初始化对应。线条只描述代码职责关系。

短模式标志、集成测试入口与测试资源职责关系
图1:短模式测试结构图。分组说明配置、测试入口和资源职责,不表示执行流程或运行结果。

关键是把判断放在昂贵初始化之前

如果先启动数据库容器再调用 t.Skip,虽然用例显示 SKIP,准备成本已经发生。应该让测试入口持有这条规则:通过短模式判断后,才调用昂贵初始化;每次成功获取资源后立即安排资源清理。完整示例中的 t.Cleanup 用于释放临时 HTTP 服务,响应体则用 defer 关闭。

包级变量初始化和 init 早于普通测试函数,不能靠函数体里的 t.Skip 撤销已经发生的工作。把有副作用的资源准备移进测试或显式的准备函数。如果必须在 TestMain 中依据 testing.Short 决策,应先调用 flag.Parse;普通测试函数进入时,测试参数已经解析。不要在包级初始化时直接调用 testing.Short。

若 TestMain 管理了全包资源,短模式下不准备它们时,仍应运行 m.Run,让包内快速测试正常执行。不要因为 short 为 true 就直接退出整个包,也不要因此让快速测试继续访问尚未初始化的共享资源。参数解析与入口边界可查看 https://go.dev/src/testing/testing.go。

用辅助函数或子测试复用这条规则

同类集成用例多时,可以复用下面的辅助函数;每个集成测试在开头调用 requireIntegration(t),随后才准备自身资源。t.Helper 使错误或跳过位置更接近调用点,便于定位。

func requireIntegration(t *testing.T) {
    t.Helper()
    // 由测试自身所在的 goroutine 调用,让跳过原因出现在调用处。
    if testing.Short() {
        t.Skip("短模式不运行集成测试")
    }
}

如果只有部分子测试昂贵,就在对应 t.Run 回调里判断,保留同一父测试中的快速子测试。注意父测试为定位子测试仍可能被执行,因此昂贵准备也要放进慢子测试,不能放在所有 t.Run 之前。整组都依赖同一昂贵资源时,才适合在该组父测试入口跳过。

t.Skip 应由当前测试运行的 goroutine 调用。不要启动工作 goroutine 后让它自行 t.Skip;跳过并不会自动停止这些 goroutine。判断最好也位于 t.Parallel 和工作任务创建之前,避免无谓的调度和资源占用。

这些情况不会被短模式自动解决

目标对应手段容易混淆的边界
作者定义的轻量运行-short 与 testing.Short不是自动耗时检测
按测试名称选择范围-run选中后仍执行函数里的短模式判断
避免复用成功测试结果-count=1不改变哪些测试主动跳过
约束外部请求等待请求超时短模式不能中断已经阻塞的操作

图中“执行选择”包含短模式、名称筛选,“用例记录”包含快速用例、慢用例,“结果语义”包含跳过标记、失败标记。名称筛选关联两类用例,短模式关联主动响应它的慢用例,慢用例可以关联跳过或失败记录。两种标记语义不同:已报告失败后再跳过,不能把失败改成成功。

短模式、名称筛选与跳过和失败标记之间的静态关系
图2:测试选择与结果语义结构图。连线表示选择或记录关系,不声称某次测试已经运行。

-short 默认关闭。集成任务建议明确使用 -short=false,尤其要排除共享任务模板或 GOFLAGS 意外开启短模式。go test 的参数与缓存规则详见 https://pkg.go.dev/cmd/go#hdr-Testing_flags。缓存可能复用已有成功测试结果,观察真实执行行为时可以用 -count=1;这不是性能优化开关。

一个可独立保存的 HTTP 集成测试示例

以下完整文件使用本机替身 HTTP 服务,演示快速用例与集成入口的分工。替身服务本身很小,不人为添加 Sleep,也不声称它具有真实慢服务的耗时;实际项目可在相同判断位置接入其集成准备。代码和命令未在本文执行,预期情况列在后面。

package snapshot

import (
    "io"
    "net/http"
    "net/http/httptest"
    "strings"
    "testing"
    "time"
)

func TestSnapshotName(t *testing.T) {
    // 不依赖外部资源的快速断言,在短模式下仍保留。
    got := strings.TrimSpace(" report-07 ")
    if got != "report-07" {
        t.Fatalf("快照名不符:got %q", got)
    }
}

func TestSnapshotIntegration(t *testing.T) {
    // 真实项目的慢准备必须位于这个判断后面。
    if testing.Short() {
        t.Skip("短模式跳过快照 HTTP 集成测试")
    }

    // 自包含的小型替身服务,用于演示集成入口,不冒充真实慢服务。
    srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        if r.Method != http.MethodGet || r.URL.Path != "/snapshot" {
            http.NotFound(w, r)
            return
        }
        w.Header().Set("Content-Type", "text/plain; charset=utf-8")
        io.WriteString(w, "record-07\nrecord-08\n")
    }))
    t.Cleanup(srv.Close)

    // 超时负责约束请求等待,和是否启用短模式是两项独立设置。
    client := &http.Client{Timeout: 3 * time.Second}
    resp, err := client.Get(srv.URL + "/snapshot")
    if err != nil {
        t.Fatalf("获取快照失败:%v", err)
    }
    defer resp.Body.Close()
    if resp.StatusCode != http.StatusOK {
        t.Fatalf("响应状态不符:%d", resp.StatusCode)
    }
    body, err := io.ReadAll(resp.Body)
    if err != nil {
        t.Fatalf("读取响应失败:%v", err)
    }
    if string(body) != "record-07\nrecord-08\n" {
        t.Fatalf("快照内容不符:%q", body)
    }
}

在全新的独立目录保存文件后,可使用以下命令。第一条仅供没有 go.mod 的示例目录;已有项目直接使用自己的模块,不覆盖原配置。

# 将完整示例保存为独立目录中的 snapshot_test.go,已有模块则无需重复初始化。
go mod init example.com/snapshot-short-demo

# 快速反馈:跳过主动响应短模式的慢用例,并显示跳过原因。
go test -short -count=1 -v ./...

# 完整反馈:明确关闭短模式,重新执行而不复用测试结果缓存。
go test -short=false -count=1 -v ./...

# 仅选择集成用例;-run 负责名称筛选,不会覆盖代码中的短模式判断。
go test -short=false -count=1 -v -run '^TestSnapshotIntegration$' .
调用条件预期行为
-shortTestSnapshotName 正常执行;集成用例在创建测试服务之前跳过
-short=false两条用例均执行;HTTP 服务创建失败、请求失败或断言不符会报告失败
-run 仅选集成函数,同时开启 -short集成函数仍会主动跳过,不因名称选中而强行运行

短任务适合频繁反馈,完整任务负责集成覆盖。CI 应分别查看两种任务的实际执行与跳过明细,不能只因为包退出码为零就推断慢用例全部通过。

慢用例没写 testing.Short 会怎样?

仍会运行。短模式只是一个供代码读取的标志,不是全自动过滤器。

测试依赖没准备好,是否都应该 Skip?

应先看任务约定。允许缺少可选环境的本地任务可以明确跳过;要求必须具备依赖的集成任务,应把缺失环境作为失败,避免错误配置被掩盖。

Skip 后还需要 return 吗?

不需要用 return 来终止当前测试,但已经安排的清理工作仍须正确设计,其他已启动 goroutine 也需要自己的停止机制。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Go fuzz 测试怎样定位导致崩溃的最小输入Go fuzz 测试怎样定位导致崩溃的最小输入
上一篇
Go fuzz 测试怎样定位导致崩溃的最小输入
Go pprof HTTP 端点暴露后怎样限制访问范围
下一篇
Go pprof HTTP 端点暴露后怎样限制访问范围
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    837次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    834次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    919次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    894次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    717次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码