低代码到底是不是行业毒瘤?一线大厂怎么做的?戳此了解>>> 了解详情
写点什么

DocTest 1.0 的 Ruby 版本发布了

2008 年 7 月 13 日

一年前

Tom Locke

Roger Pack 分别实现了各自的 Ruby DocTest(doctest 来自于 Python 标准库)。如今

Nic 博士也在从事这项工作。DocTest 可以方便地根据标准命令解释器(IRB for Ruby)的输出生成测试,并剪贴到文档串(docstring)中。

在 IRB 中进行测试,复制 / 粘贴你的输出,把它作为函数的注释:

<pre id="brcv19"># doctest: Add 5 and 5 to get 10<p># >> five_and_five</p><p># => 10</p><p>def five_and_five</p><p>5 + 5</p><p>end</p>然后你可以这样来运行测试:

$ rubydoctest five.rb

<pre id="brcv26"><p>=== Testing 'five.rb'...</p><p>OK | Add 5 and 5 to get 10</p><p>1 comparisons, 1 doctests, 0 failures, 0 errors</p>以上实验采用的是

git 存储库中最新的源程序。不久后还会有一个升级包可用。

这样的文档串驱动测试有几个优点:

  • 熟悉 IRB 现场测试的人会觉得它很用起来很自然。
  • 测试时只需要观察一个地方。
  • 简单。

……还有几个缺陷:

  • 应避免很长的文档串,如果有的话,要把它放在单独的测试文件中。
  • 不支持某些复杂的断言测试。
  • 测试大量的输出可能会觉得冗长乏味。

可以看一看使用 DocTest 的演示录像

InfoQ 采访了 Duane Johnson,谈一谈 DocTest 和文档串驱动测试。

InfoQ:首先,是什么促使你写 DocTest 的?我听说你研究了前两个实现。

Duane Johnson:我目前正致力于改进一个大型 Ruby 项目(

memorypress.com ), 它只有很少的测试和文档。为了让它更完善,我们肯定需要在适当的地方做一些测试,避免不小心造成破坏。问题是,我的大部分“测试”时间都花在 irb 控制台 上了,因为我们不是总清楚测试进行到哪了以及如何应对。换句话说,测试对于我来说是种探索性工作——我需要看到程序是不是按照我明确规定的那样运行。 Ruby DocTest 是个完美的结合,因为我可以把成功的实验输出复制到代码库中,并进行完整的核对测试。

最新的代码都在 github上吗?它是不是融合了上一版的 DocTest?你都增加了些什么?

是的,那儿有最新的代码。在本周早些时候,在得到 Tom Locke 的许可后,我从他的项目弄出了一个分支,放在

github.com/tablatom/rubydoctest , 在里面加入了我的更新。我发现 Tom 写的代码读起来很顺,而且他通过 eval(动态执行代码,而不是像 Python 的 doctests 那样直接测试字符 串)比较结果的方法非常棒。例如能成功地比较 Ruby 的无序哈希。我也参考了 Roger Pack 的主意,把 doctest 放到 ruby 源代码的注释中。我并没有借用 Roger 的程序(在

code.google.com 上),但借用了他的主意。现在,Ruby DocTest 有两个选项,一是 Roger 的“内嵌 doctest”风格,一是 Tom 的“标记文件的分立文档”风格。

既满意又不满意。我还是有点喜欢 rspec 的。但在我的工作流程中,我发现自己总是在追赶代码,因为懒得切换到其他的 文件(或者创建一个文件)去写测试。我经常有一种为琐事操心的感觉,就是当我应该对方法测试一些边界情况时,却放弃了,因为那时候我脑子里还有许多其他东 西。要是我能在那放一个 irb 会话,我想,就能符合我 90% 的需求了。所以我就这么干了。

DocTest 不在 BDD 周期中吗?

不在。它不是一个测试先行的方法。刚才已经提到了,我目前的需求,是给那些没有经过严格测试的已有项目建立文档。

DocTest 要代替其他的单元测试框架吗?或者仅是一个额外的工具?

老实说,我还不知道。对我来说,这是个写测试的新方法。所以我还会继续完善它,相信很快就会有答案的。我觉得前面所说的目标已经实现 90% 了……可能还有一些地方,更适合使用传统的 rspec 或者 Test::Unit 用例。

DocTest 对代码的注解是否会妨碍阅读呢?

我想,doctest 的迁移步骤应该是这样的:

  1. 你写了一些代码,然后增加一两行内嵌 doctest 注释;
  2. 你修改了另一些代码,然后回到原始代码;
  3. 你添加了更多的测试用例,但是测试的数量(或长度)变得太大,因此你把它们移到单独的 *.doctest 文件里;
  4. 最后,你有了一个较完整的标记文件集合,还有有代码例子作为文档,其中包括指令和注释。

边写代码边写测试的一个有趣的副作用之一,是鼓励你让 ruby 源文件更加独立——换句话说,最好能够“动态执行 (eval)”文件而不出现任何依赖错误,而这正是 doctests 所要求的。我发现只要让一个文件摆脱掉一系列复杂的隐藏条件(就像 Rails 文件那 样),测试起来就容易得多。而且我对每个文件的依赖也更清楚了。

2008 年 7 月 13 日 21:11303
用户头像

发布了 33 篇内容, 共 34541 次阅读, 收获喜欢 0 次。

关注

评论

发布
暂无评论
发现更多内容

目标检测综述

Dreamer

架构师训练营第 1 期 第 3 周作业

李循律

极客大学架构师训练营

EDA最强攻略,如何为EDA选择存储?

焱融科技

分布式 高性能 存储 半导体 EDA

Docker底层技术

混沌畅想

Docker 容器 DevOps 底层技术

架构师训练营第 1 期 第 5 周作业

李循律

极客大学架构师训练营

C++primer-函数探幽

Dreamer

c++

C++ primer -- 第16章 string类和标准模版库

Dreamer

c++

C++ primer --第十一章 使用类

Dreamer

c++

C++ primer -- 第17章 输入,输出和文件

Dreamer

c++

独立显卡市场又一巨头跻入,英特尔锐炬® Xe MAX 独立显卡来了!

intel001

永续合约系统开发源码,合约跟单软件搭建app

WX13823153201

Here I come

Dreamer

C++ 第九章 内存模型和名称空间

Dreamer

c++

架构师训练营第一期 - week6

习习

c++ primer -- 第14章 C++中代码重用

Dreamer

c++

架构师训练营第 6 周:技术选型 (二)

子青

一个研发团队是如何坚持7年技术分享的?

PingCode

团队管理 敏捷开发 研发管理 技术分享 程序员节

极客大学 - 架构师训练营第一期 - 第六周作业

Black Eyed Peter

极客大学架构师训练营

架构师训练营第六周学习笔记

一马行千里

学习 极客大学架构师训练营

写文档太麻烦,试试这款 IDEA 插件吧!

程序员小航

Java markdown IDEA idea插件 文档

MySQL中事务的持久性实现原理

X先生

MySQL 数据库 sql 数据库事务 事务

C++ primer -- 第十二章 类和动态内存分配

Dreamer

c++

Caffe 安装踩坑记录

Dreamer

caffe

TensorFlow 篇 | TensorFlow 数据输入的最佳实践

Alex

tensorflow keras input pipeline dataset

学习笔记--week06

张荣召

C++ primer -- 第十五章 友元,异常和其他

Dreamer

c++

C++ primer -- 第18章 探讨C++新标准

Dreamer

c++

当下工作流管理系统的发展趋势

Marilyn

敏捷开发 快速开发 软件架构 企业开发

Forsage矩阵系统开发,智能合约搭建

薇電13242772558

C++ primer -- 第十章 对象和类

Dreamer

c++

C++ primer -- 第十三章 类继承

Dreamer

c++

2021 ThoughtWorks 技术雷达峰会

2021 ThoughtWorks 技术雷达峰会

DocTest 1.0的Ruby版本发布了-InfoQ