A.4 命令行测试

我们在 1.8 节中说过,相比于一次性编写所有的代码,逐步编写并调试代码的做法更有效。编写实现算法的代码后,通过测试来确定不管输入如何它都能正确地工作很重要。

本书很多地方都演示了程序测试技巧。大多数测试都基于简单的想法:程序的所做所为符合预期吗?对于简单的程序,多次运行并查看结果并不难;但反复输入相同的测试用例终将让你感到厌烦。

通过使用命令行,可将提供输入、比较期望输出与实际输出的过程自动化。其中的基本理念是将测试用例存储在纯文本文件中,并让 Java 以为这些输入来自键盘。实现这种想法的基本步骤如下。

(1) 确保能够编译并运行代码仓库 ThinkJavaCode 的目录 ch03 下的示例 Convert.java

(2) 在 Convert.java 所在的目录中创建一个名为 test.in (in 表示输入)的纯文本文件,在其中输入如下内容并存盘:

  1. 193.04

(3) 再创建一个名为 test.exp(exp 表示预期)的纯文本文件,在其中输入如下内容并存盘:

  1. 193.04 cm = 6 ft, 4 in

(4) 打开一个终端窗口,并切换到这些文件所在的目录。执行下面的命令来测试这个程序:

  1. java Convert < test.in > test.out

在命令行中,<> 指的是重定向运算符(redirection operator)。前者将 test.in 的内容重定向到 System.in,使得就像通过键盘输入了它们一样。后者将 System.out 的内容重定向到新文件 test.out,这很像截屏。换而言之,文件 test.out 将包含程序的输出。

顺便说一句,完全可以在 DrJava(或其他开发环境)中对程序进行编译,再从命令行运行。熟悉这两种方法后,你就可根据工作需要选择合适的工具了。

现在可以对 test.out 和 test.exp 的内容进行比较了。如果这两个文件的内容相同,就说明程序的输出符合预期;如果不同,就说明程序存在 bug,而我们可根据实际输出对程序进行调试。所幸有一种通过命令行对文件进行比较的简单方式:

  1. diff test.exp test.out

实用工具 diff 概述两个文件的差别。如果没有任何差别,diff 将不会显示任何内容,就这里而言,这正是我们希望的。如果期望输出与实际输出不同,我们就需要继续调试。通常而言,有问题的是程序,而 diff 让我们能够了解问题出在什么地方。但也可能程序没问题,而是预期输出不对。

diff 的输出可能不那么容易解读,好在有很多显示文件差异的图形工具。例如,在 Windows 系统中可使用 WinMerge;在 Mac 系统中可使用 opendiff(这是 Xcode 自带的);在 Linux 系统中可使用 meld(如图 A-4 所示)。

{%}

图 A-4:用 meld 比较预期输出和实际输出

不管用哪种工具,目标都是相同的:不断调试程序,直到实际输出与预期输出相同。