摘要

  • Grace Hopper 1967 年回到 U.S. Navy 后,帮助建立了编译器测试与验证工作。她在 1980 年的口述史中把一种重要的跨机器测试方法归给 George Baird,而不是说测试系统由自己独立完成。
  • 这套测试让特定 COBOL 功能及其输出可以被观察和比较,但不能证明编译器完全正确、所有功能组合都已覆盖,或任何应用都能原样迁移。
  • 语言标准规定目标,合规测试只检验一组明确的样例,应用迁移测试则要面对真实程序及其运行环境。把三者都简称为“可移植”,会遮住尚未验证的部分。

标准不是验收结果

对同时从多家厂商采购计算机的政府机构来说,COBOL 曾带来一个很实际的希望:程序不必永远绑定同一家供应商。但语言名称相同,不代表不同编译器都会以同样方式实现每个必需功能。标准写明应有的行为,却不能替买方测量已经交付的软件。

这正是 Grace Hopper 职业生涯中较少被讲述的一段。公众熟悉她早期的编译器工作,以及 FLOW-MATIC 对 COBOL 的影响;这里追踪的是另一个问题:当机构要采购多厂商系统时,怎样把兼容性的承诺变成可以复核的证据?答案不是再写一条合同措辞,而是让编译器运行明确的测试程序,把预期结果与实际结果并列,并能在另一台机器上复现检查。

这项工作并非从零开始,也并非由一人完成。George N. Baird 在 1972 年发表的 Department of Defense COBOL 编译器验证系统论文,回溯到 1963 年开始的一项标准小组工作。该小组编写程序,检查编译器是否提供规范要求的功能。目标不是调试所有编译器,也不是穷举全部可能组合,而是选取若干功能,单独或组合运行,再报告结果。

让失败可以定位

Baird 描述的 U.S. Navy 早期测试程序继承了此前工作,也改进了报告方式:系统可以把机器实际生成的结果与预期结果对照,并指出失败出现在哪个过程。初版包含 12 个程序,源代码约 5,000 行。

这些数字说明了“验证”落到地面后的样子。“我们的编译器支持 COBOL”是宽泛承诺;“该编译器在这套配置下接受了这些必需语法,并产生了这些输出”则是一项别人可以重新运行和检查的陈述。测试不能取代技术判断,却能让判断中的一部分留下可追溯记录。

Grace Hopper 在 1980 年接受 Computer History Museum 采访时回忆,Norman Ream 于 1967 年请她回到现役,任务是建立测试与验证程序,以支持标准并改善软件迁移。她把这件事比作产品检验:有标准,就应有能检查实现是否符合标准的测试。

她还说自己要求配备程序员。她提到民职人员 Ed Ford、一名少尉和两名水兵;George Baird 是最早加入的人之一,Arnold Johnson 后来加入。1971 年 1 月的 Datamation 报道提供了同期旁证:当时 U.S. Navy 要求 COBOL 编译器通过验证,Department of Defense 与 National Bureau of Standards 则已原则同意合作制定针对 ANSI 标准的测试程序。“原则同意”并不等于联邦服务已经建成;它只记录了报道当时的项目状态。

Hopper 把一项关键设计归给 George Baird

口述史中最值得注意的,不是 Hopper 抢先认领发明,而是她明确指出 George Baird 的贡献。她说,Baird 找到一种做法,把各台计算机不同的专用名称和控制卡细节放入独立配置数据里。通用测试逻辑仍以标准 COBOL 编写,机器专属的小文件再补上运行所需的差异。

因此,可移植的不只是业务程序,也包括测试工具。若每换一种编译器就重写整套测试,比较结果会更难维护,也更容易偏向某个实现。把共同测试与本机配置分开,团队便能重复使用同一套检查,同时保留每台机器的具体差异。

Hopper 的说法是多年后的回忆,应作为她对团队分工的证言来读。Baird 的 1972 年论文则提供了较接近当时的技术说明。两类资料合起来支持一个谨慎的归属:Hopper 帮助落实任务并组织团队,Baird 提出重要的跨机器机制,标准组织及其他成员也提供了先行工作。现有资料不支持把 COBOL 或整个验证系统说成某一个人的作品。

测试通过,能说明什么

测试通过,意味着某个编译器在指定条件下处理了被选中的功能,并输出预期结果;它不说明所有有效组合都跑过,不说明所有缺陷都已发现,也不说明某个具体应用能不改动就换到另一台机器。

这不是 COBOL 特有的局限。NIST 对另一条并行路线的回顾,讲述了 Betty Holberton 与 Elizabeth Parker 主导的 FORTRAN 测试项目,并指出有限测试集无法证明编译器绝对正确。那是 National Bureau of Standards 的独立项目,不是 Hopper 的海军 COBOL 验证系统。保留这个区别,才能看见验证实践是由不同团队、不同语言共同发展出来的。

编译器符合标准与应用可移植性仍是两个层次。编译器可能通过选定测试,但某个应用仍依赖厂商扩展、操作系统服务、文件布局、运行库行为或数据表示方式。这是根据测试范围作出的推论,并不代表 U.S. Navy 的测试程序逐一检查了所有依赖。要迁移应用,还要针对真实程序运行回归测试,并记录它原先所处的环境。

因此,教训不是怀疑标准或测试,而是准确描述它们证明了什么:标准规定预期行为;一致的测试集检查实现的一部分;迁移测试验证机构真正要搬动的系统。若把这三件事都压成“可移植”,剩余风险就会变得不可见。

留下可追溯的边界

不把 Hopper 的贡献夸大,反而能看清它的形状。她帮助机构把兼容性愿景变成有团队、有流程的验证能力。她的回忆也展现了一种少见于“天才独自发明”叙事的领导方式:为技术工作争取合作者,并把关键机制的功劳交给实际设计者。

Baird 的做法解释了这种归属为何重要。可移植性不只写在委员会标准里,还取决于测试设计、机器适配、结果比较和重复运行。没有可观察测试的标准,只给买方留下说法;抹掉作者的测试系统,则会丢掉怎样复现它的知识;没有范围说明的通过标签,又会把有限证据包装成过宽的承诺。

对长期运行的软件,验证记录应与结论一同保存:采用哪个标准版本、哪一版编译器、哪些测试、机器专属配置是什么、观察到什么结果。Hopper 参与的 U.S. Navy 工作没有消除供应商差异,却让机构能够揭示其中一部分、比较实现并据此采购。这比“COBOL 让软件天然可移植”更窄,却更经得起时间检验。

来源