菜单

测试框架

相关源文件

此页面详细介绍了fzf用于确保代码质量和功能的测试框架。fzf采用全面的测试方法,结合了用于内部组件的Go单元测试和用于交互式功能集成测试的自定义Ruby框架。

测试架构概述

fzf采用双管齐下的测试策略,旨在验证单个组件的正确性以及应用程序的整体交互行为。

来源: .github/workflows/linux.yml .github/workflows/macos.yml src/options_test.go src/tokenizer_test.go test/test_core.rb6-13

Go 单元测试

fzf 中的 Go 单元测试遵循标准的 Go 测试模式。这些测试与生产代码一起存放,文件名以 _test.go 结尾。

使用 Go 单元测试的组件

以下组件有专门的单元测试

  1. 选项解析器:用于命令行参数解析和配置的测试

    • 测试选项标志、默认值和验证
    • 验证 --preview-window 等复杂选项的行为
  2. 分词器:用于模糊查找的文本分词测试

    • 使用不同分隔符验证分词解析
    • 测试范围解析以进行第 N 个分词选择
  3. 分隔符处理:用于各种分隔符模式的测试

    • 测试基于正则表达式的分隔符
    • 测试基于字符串的分隔符
    • 测试 AWK 风格的分词
  4. 按键绑定解析器:用于解析按键绑定定义的测试

    • 验证按键组合解析
    • 测试按键绑定到动作

单元测试示例

这是分隔符正则表达式功能的一个单元测试示例

以及分词器测试的一个示例

来源: src/options_test.go11-46 src/tokenizer_test.go7-55 src/options_test.go252-307

Ruby 集成测试框架

集成测试框架是 fzf 测试套件的核心。它旨在通过模拟真实的用户交互来测试 fzf 的交互式功能。

集成测试架构

来源: test/test_core.rb6-13 test/test_core.rb21-84 test/test_core.rb99-109 test/test_core.rb478-529 test/test_core.rb617-645

测试执行流程

集成测试使用 tmux 创建一个受控环境来测试 fzf 的交互行为。该框架允许精确模拟用户交互并验证 fzf 的响应。

该框架通过模拟真实用户交互并在每个步骤验证 fzf 的行为,为测试复杂的交互场景提供了强大的方法。

来源: test/test_core.rb21-84 test/test_core.rb99-109 test/test_core.rb111-175

核心框架组件

  1. TestInteractive: 基础类,提供与 tmux 会话交互的实用程序

    • 管理 tmux 会话生命周期
    • 提供交互和断言的辅助方法
  2. TestCore: 继承自 TestInteractive 并定义特定测试场景的测试用例

    • 包含不同 fzf 功能的独立测试方法
    • 按功能组织测试(按键绑定、多选等)
  3. Tmux 助手:用于管理 tmux 会话和模拟用户交互的方法

    • 发送击键并捕获输出
    • 提供同步机制

辅助方法

该框架提供了几个专门的辅助方法

方法描述使用示例
tmux.send_keys将击键发送到 tmux 会话tmux.send_keys "#{FZF} -q 'query'", :Enter
tmux.until等待直到 tmux 输出中满足指定条件tmux.until { |lines| assert_equal '> query', lines.last }
tmux.capture捕获 tmux 窗格的当前内容lines = tmux.capture
fzf_output返回 fzf 完成后的最终输出assert_equal 'selected item', fzf_output
fzf_output_lines将输出作为行数组返回assert_equal %w[item1 item2], fzf_output_lines
assert_equal验证预期值和实际值之间的相等性assert_equal ' 10/10 (6)', lines[-2]
assert_includes验证集合是否包含某个元素assert_includes lines, 'expected text'
tmux.prepare准备一个干净的 tmux 环境用于测试tmux.prepare

这些方法协同工作,为测试交互式 CLI 应用程序创建了一个强大的框架。

来源: test/test_core.rb7-138 test/test_core.rb99-109 test/test_core.rb478-529

集成测试示例

集成框架测试了以下功能

按键绑定测试

测试按键绑定是否正常工作的测试

来源: test/test_core.rb21-84

多选测试

多选功能测试

来源: test/test_core.rb99-109

测试类别

集成测试涵盖了 fzf 的广泛功能。以下是测试类别的详细分类

每个类别包含多个测试方法,用于验证 fzf 功能的具体方面

  1. 基本功能

    • 默认命令执行 (test_fzf_default_command)
    • 错误处理 (test_fzf_default_command_failure)
    • 退出代码 (test_exitstatus_empty)
  2. 用户交互

    • 按键绑定 (test_key_bindings)
    • 导航 (test_scroll)
    • 文本编辑 (test_file_word)
    • 跳转功能 (test_jump, test_jump_accept)
  3. 选择管理

    • 单选 (test_select_1)
    • 多选 (test_multi_order, test_multi_max)
    • 选择切换 (test_toggle_all)
    • 全选/全不选 (test_select_all_deselect_all_toggle_all)
  4. 显示功能

    • 布局选项 (test_no_clear)
    • 预览窗口 (test_preview_opts)
    • 标题显示 (test_header, test_header_lines)
    • 边距和填充 (test_margin)
  5. 查询处理

    • 过滤 (test_invalid_cache)
    • 搜索模式 (test_toggle_search)
    • 历史管理 (test_history)
    • 查询转换 (test_transform_query)

来源: test/test_core.rb7-992 test/test_core.rb21-84 test/test_core.rb99-109 test/test_core.rb111-175 test/test_core.rb478-529 test/test_core.rb617-645 test/test_core.rb786-844

运行测试

本地测试

fzf 项目提供了多种方式在本地开发期间运行测试。

Go 单元测试

运行 Go 单元测试

这些命令执行标准的 Go 单元测试,以验证各个组件的正确性。

Ruby 集成测试

运行 Ruby 集成测试

集成测试要求安装 tmux 并将其添加到你的 PATH 中。

CI 测试

通过 GitHub Actions 工作流,测试会自动在 CI 中运行,支持 Linux 和 macOS 环境。

CI 管道确保在合并更改之前,所有测试在不同平台上都能通过。

测试依赖项

要运行完整的测试套件,您需要:

  1. Go 开发环境
  2. Ruby 解释器
  3. tmux(用于集成测试)
  4. 标准的 Unix 工具

来源: .github/workflows/linux.yml44-48 .github/workflows/macos.yml41-45 test/runner.rb

编写新测试

添加单元测试

fzf 项目遵循标准的 Go 测试实践。要添加新的单元测试:

  1. src/ 目录中创建新测试文件或添加到现有文件中。

    • 测试文件应命名为 *_test.go
    • 将测试放在它们所测试的代码旁边。
  2. 使用名为 TestXxx 的函数遵循 Go 测试约定。

    • 函数名称必须以 Test 开头,后跟一个大写名称。
    • 必须接受 t *testing.T 作为唯一参数。
  3. 使用标准的 Go 测试包进行断言。

    • 使用 t.Error() / t.Errorf() 报告失败。
    • 使用 t.Fatal() / t.Fatalf() 处理关键故障,这些故障会停止测试。

示例

添加集成测试

Ruby 集成测试框架提供了一种强大的方式来测试交互式功能。

  1. 向现有测试类添加新的测试方法,或创建一个新类。

    • 测试方法名称必须以 test_ 开头。
    • 将相关测试分组在同一个类中。
  2. 继承自 TestInteractive 以访问测试框架。

    • 这提供了对 tmux 会话和辅助方法的访问。
  3. 遵循已建立的模式。

    • 使用 tmux.send_keys 在 tmux 中启动 fzf。
    • 使用 tmux.until 等待初始化。
    • 发送按键以模拟用户交互。
    • 使用 tmux.until 等待条件满足。
    • 对输出或状态进行断言。
    • 使用 fzf_outputfzf_output_lines 验证最终输出。

示例

这种模式允许通过模拟真实用户交互和在每个步骤验证 fzf 的响应来对交互式功能进行全面测试。

来源: src/options_test.go252-307 test/test_core.rb111-175 test/test_core.rb478-529

最佳实践

  1. 隔离性:每个测试都应该是独立的,不依赖于其他测试的状态。
  2. 清理:在测试后妥善清理资源,以免影响后续测试。
  3. 清晰的断言:断言应尽可能具体。
  4. 描述性名称:使用清晰表明被测试功能的名称。
  5. 注释:为复杂的测试步骤添加注释以解释正在测试的内容。

结论

fzf 测试框架结合了传统的 Go 单元测试和强大的基于 Ruby 的集成测试系统,以确保代码的正确性和交互式行为的恰当性。这种双重方法允许对内部组件和最终用户体验进行全面测试。

来源: test/test_core.rb src/options_test.go src/tokenizer_test.go .github/workflows/linux.yml .github/workflows/macos.yml