Ruby TRICK 2018:用 68 个字符写出一个支持分组的迷你测试框架(04-colin 获奖作品)
2026/9/13 19:14:56 网站建设 项目流程

Ruby TRICK 2018:用 68 个字符写出一个支持分组的迷你测试框架(04-colin 获奖作品)

【免费下载链接】rubyThe Ruby Programming Language项目地址: https://gitcode.com/GitHub_Trending/ru/ruby

本文以 Ruby 官方仓库sample/trick2018/04-colin/下 TRICK 2018(The 3rd Transcendental Ruby Imbroglio Contest for rubyKaigi)"Best one-liner" 获奖作品为蓝本,完整讲解这个 68 字符测试库的使用方法:如何用同一个方法🤔编写单条断言与嵌套测试分组、如何运行测试文件,以及它的源码仅由一行方法实现时各语句的字符预算、Ruby 版本兼容性与终端 Unicode 限制。读完后,你可以独立使用这套极简测试风格,并理解它"一切靠一个方法"的设计手法。

一、这是什么:一行代码的测试框架

sample/trick2018/目录收录的是 rubyKaigi 第三届 TRICK 比赛的获奖作品。比赛总览 中对本作品的定位是:

04-colin/entry.rb: "Best one-liner" — 4th prize

作者信息 显示作者为 Colin Fulton。整个测试库的实现文件 entry.rb 去掉版权头注释后只有一行,共 68 个字符(98 字节):

$🚀=0;def 🤔 🏷,🤔=0,&b;puts ' '*$🚀+(🤔 ?"":"🚫 ")+🏷;$🚀+=4;b&.[];$🚀-=4;end

使用说明文档 中的原始设计目标(Description 一节原文)是:

The goal was to create a testing library where the test files looked good and the output looked good in as few characters as possible. The result is 68 characters and has one method to handle everything.

即:用尽可能少的字符,同时让"测试文件本身读起来好看"和"测试输出好看"。最终结果是 68 个字符、只用一个方法处理所有事情。

这里有一个 Ruby 语言层面的关键点:🤔🏷🚀都是完全合法的 Ruby 标识符(Ruby 的方法名/变量名支持任意 Unicode 字母字符),因此 emoji 既是被测试方法的"方法名",也是测试用例的"断言值",还兼任输出缩进计数器——这是作品能压到一行的语言基础。

二、编写测试:🤔的两种子调用形态

依据 remarks.markdown 的 "Remarks" 一节,使用方法如下:创建一段require了 entry.rb 的 Ruby 测试文件,然后直接运行:

ruby name_of_test_file.rb

2.1 单条测试:字符串 + 断言值

调用🤔并传入两个参数:第一个是描述该测试的字符串,第二个是测试断言。断言为 truthy 则测试通过,为 falsy 则失败。原文档示例:

string_1 = "Hello world!" string_2 = "This is not the same!" 🤔 "The two strings are equal", string_1 == string_2

因为断言string_1 == string_2的返回值是false,这条测试会失败。

2.2 测试分组:字符串 + 代码块

调用🤔并传入一个描述字符串 + 一个块(block),即可在某个标签下创建一组测试。原文档示例:

🤔 "This is a group of tests" do # Add other groups and/or tests here. end

2.3 完整示例:嵌套分组的测试文件

原文档给出的完整例子(含一个刻意设计为失败的断言,用于演示失败输出):

require './entry' 🤔 "Math" do 🤔 "Addition" do 🤔 "One plus one equals two.", 1+1 == 2 🤔 "One plus one equals eleven. (This should fail.)", 1+1 == 11 end 🤔 "Subtraction" do 🤔 "One minus one equals zero.", 1-1 == 0 🤔 "Ten minus one equal nine.", 10-1 == 9 end end

结构上:顶层是 "Math" 组,其下嵌套 "Addition" 与 "Subtraction" 两个子组,每个子组内是具体断言测试。其中1+1 == 11这条是作者刻意写失败的,用来展示失败时的输出样式。

三、源码剖析:68 个字符是怎么花出去的

把 entry.rb 中那一行按 Ruby 语句拆开(用;分隔),可以逐段对照它如何实现上面两种子调用形态:

$🚀=0; # 全局变量 $🚀 初始化为 0,充当当前缩进深度计数器 def 🤔 🏷,🤔=0,&b; # 定义方法 🤔:参数 🏷 是描述字符串, # 参数 🤔 带默认值 0(断言值,缺省为 falsy), # &b 收集传入的块 puts ' '*$🚀+(🤔 ?"":"🚫 ")+🏷; # 输出:缩进空格 + 失败前缀 + 描述 $🚀+=4; # 缩进深度 +4 b&.[]; # 若给了块(分组形态)则执行该块 $🚀-=4; # 缩进深度 -4 end

各部分与设计目标对应关系:

  • 🤔既是方法名又是断言参数def 🤔 🏷,🤔=0,&b中同名复用让"分组调用"(🤔 "标签" do ... end)与"断言调用"(🤔 "描述", 断言值)共享同一个入口——分组时第二个参数缺省为0(falsy),断言时第二个参数取断言的布尔结果。
  • 🤔 ?"":"🚫 ":三元表达式实现通过/失败前缀。断言 truthy 输出空串,falsy 时输出🚫。这正是 2.1、2.2 节中"断言真假决定测试成败"的底层实现。
  • $🚀+=4/$🚀-=4包裹b&.[]:进入分组块之前把缩进 +4,块执行完(内部的所有测试输出都基于加深后的$🚀)再 -4,从而用全局变量模拟出嵌套分组的四级缩进树形输出。
  • b&.[]:安全导航调用块;块为nil(单条断言形态)时整句短路,恰好只执行一次puts

从源码结构看,整个框架没有引入任何类、状态机或钩子:一次puts、一次块调用、一个计数器变量,即完成"分组 + 断言 + 缩进 + 失败标记"的全部行为。

说明:当前环境未安装 Ruby 解释器,以上为逐字符核对源码得出的静态分析(该行实测为 68 个字符、98 个 UTF-8 字节),输出样式结论来自源码语句逻辑与原文档描述。

四、Ruby 版本兼容性与字符数权衡

remarks.markdown 明确列出了作品验证过的解释器版本:

  • ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]
  • ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin15]
  • 如果把b&.[]换成b&&b[],在 ruby 2.0.0 上也能工作,但字符数会多 1 个。

这透露出一个典型的 code golf 权衡点:&.[]是"一个方法名的安全导航调用",而b&&b[]是"先判空再显式调用",两者语义等价(块为 nil 时都不执行),后者少了 1 个字符的写法在这里反而更长(b&.[]5 字符 vsb&&b[]7 字符),作者为了 68 字符的极限选了&.[],代价是放弃 2.0.0 兼容。适用前提因此是:Ruby ≥ 2.1(&.[]所依赖的 safe navigation 语法自 2.3 起可用);若需兼容 Ruby 2.0,可按文档说明做单字符级的替换。

五、限制:终端必须支持 Unicode

原文档 "Limitation" 一节指出:

Your terminal program must support Unicode characters for the test output to look correct. If your terminal does not support Unicode, simply replace the 🚫 in the code with whatever character you want to prefix failing tests.

即:测试输出中的失败前缀🚫与缩进、描述都依赖终端正确渲染 Unicode;在纯 ASCII 终端上,直接把源码里的🚫替换成任意想要的 ASCII 字符即可保持功能不变(如!F)。同理,🤔/🏷/🚀作为标识符在 ASCII 终端下会原样回显到输出中,但语法功能不受影响。

六、如何阅读与复现这套作品

  • 实现文件:entry.rb(第 2 行即全部 68 字符实现)
  • 原始使用说明(本文主体来源):remarks.markdown
  • 作者信息:authors.markdown
  • 比赛背景与其他获奖作品:sample/trick2018/README.md

复现步骤(只读仓库中文件,不改仓库):

  1. 将 entry.rb 的内容保存为自己的工作目录中的entry.rb
  2. 新建name_of_test_file.rb,写入require './entry'后按第二节的两种🤔形态编写测试;
  3. 在具备 Ruby ≥ 2.3 且终端支持 Unicode 的环境中执行:
ruby name_of_test_file.rb

预期输出为按分组深度每级缩进 4 空格的树形列表,失败的断言行以🚫前缀标记。

注意:比赛 README 同时警告 "THESE ARE BAD EXAMPLES! You must NOT use them as a sample code."——这些作品是 Ruby 语言技巧的极限实验(emoji 命名、单行压缩、全局变量计数),学习其语言机制有价值,但不应作为日常测试库的生产模板。

七、小结

维度内容
作品TRICK 2018 "Best one-liner"(4th prize),04-colin/entry.rb
规模1 行,68 字符 / 98 字节,仅 1 个方法
单条测试🤔 "描述", 断言值,truthy 通过、falsy 失败并以🚫前缀输出
测试分组🤔 "分组名" do ... end,每级缩进 4 空格($🚀+=4/$🚀-=4
运行方式ruby name_of_test_file.rb
已验证版本ruby 2.5.1p57、2.3.0p0;将b&.[]改为b&&b[]可兼容 2.0.0(+1 字符)
限制终端需支持 Unicode,否则替换🚫为任意前缀字符

这套作品的可迁移经验是:Ruby 的 Unicode 标识符、def ... ,默认值,&block的签名设计、&.安全导航与全局计数器组合,可以在不定义任何类的前提下,用一个方法同时表达"断言"与"分组"两种递归结构——这正是它 68 字符也能"测试文件好看、输出好看"的原因。

【免费下载链接】rubyThe Ruby Programming Language项目地址: https://gitcode.com/GitHub_Trending/ru/ruby

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询