在我正在上课的课程中,我们使用旧的R5RS标准来解决SICP作业。我喜欢测试第一次开发,所以我认为单元测试框架会很好,我选择了SchemeUnit来编写小测试。
到目前为止这个工作正常,只是测试输出中的基元(字符串,数字......),但是在尝试测试列表时遇到了障碍。它可能与用于运行测试的Scheme方言的差异有关:
foo.scm: (define a-list (list 2))
foo-tests.scm: (check-equal? a-list (list 2))
运行测试时的结果:
Unnamed test
FAILURE
name: check-equal?
location: tester.scm:22:3
actual: {2}
expected: (2)
要使测试套件运行,我必须将"#lang scheme/base
添加到foo-tests.scm和require
schemeunit包的顶部。在foo.scm中,我需要在顶部显示#lang r5rs
和(#%provide (all-defined))
。
我猜在R5RS和“scheme / base”中,列表在某种程度上是不同的。有什么方法让他们一起工作?为什么它会失败({} vs())?
答案 0 :(得分:4)
是的,正如您所注意到的,列表在#lang r5rs
与#lang scheme/base
中的实施方式不同。如果可以在foo-tests.scm
的r5rs中编写测试,那将有助于消除可能的混淆。
您应该可以将此设置在foo-tests.scm
文件的顶部。
#lang r5rs
(#%require schemeunit)
(#%require "foo.scm")
;; Now you can add your tests here:
(check-equal? a-list (list 1 2 3))
如果测试套件是用相同的语言编写的,那么构造---特别是列表的表示 - 应该匹配。上述测试应该有希望通过。
详细说明r5rs
列表与#lang scheme
(和#lang racket
)中的列表之间的区别:Racket使用不可变的cons对来表示列表。不可变的cons对不支持r5rs的set-car!
和set-cdr!
函数,因此它不忠实#lang r5rs
语言的标准来使用内置的不可变对。为了支持r5rs标准,Racket包含一个单独的mutable pairs数据类型,并在r5rs中一致地使用它。但这意味着Racket和可变对中的标准对不能平等对比。