【问题标题】:Accessing Internal Symbols of a Package in Testing Package在测试包中访问包的内部符号
【发布时间】:2016-02-03 05:32:26
【问题描述】:

我有一个程序,我想使用证明进行测试。目前,我有一个单独的测试包。我面临的问题是我真的不想从主包中导出每个符号(我目前只导出一个),但我希望能够访问测试包中的所有内容。

使用main-package::symbol 可以,但我猜这很丑而且是个坏主意。有没有更好的方法来做到这一点,而不必为了测试它们而导出我的所有符号?我考虑过使用相同的包来编写测试,但是当我只将它用于测试代码时,我不想在我的主包中有一个(:use :prove)。有什么方法可以做类似(:use :package) 的事情,但只针对一个文件?如果有,在这里使用它是否有意义?

【问题讨论】:

    标签: testing common-lisp


    【解决方案1】:

    您可以将测试分离到它们自己的系统中。这样,您的主系统将完全不依赖于证明。在测试系统中,您可以加载相同的源文件,但不同的包定义(这当然假设您将包定义放在不同的文件中,而不是使用将它们放在源文件顶部的奇怪习惯......) .

    例如,主程序可能如下所示:

    foo.asd:

    ;; Here I'm obviously putting the package def in the same file
    (in-package :cl-user)
    (defpackage :foo-asd
      (:use :cl :asdf))
    (in-package :foo-asd)
    
    (defsystem "foo"
      :components ((:file "foo-package")
                   (:file "foo")))
    

    foo-package.lisp:

    (in-package :cl-user)
    (defpackage :foo
      (:use :cl)
      (:export :foo))
    

    foo.lisp:

    (in-package :foo)
    
    (defun foo (x)
      (+ (bar x)
         (bar x)))
    
    (defun bar (x)
      (* x x))
    

    和测试系统在同一目录下:

    foo-test.asd:

    (in-package :cl-user)
    (defpackage :foo-test-asd
      (:use :cl :asdf))
    (in-package :foo-test-asd)
    
    (defsystem "foo-test"
      :depends-on (:prove)
      :components ((:file "foo-test-package")
                   (:file "foo")
                   (:file "foo-test")))
    

    foo-test-package.lisp

    (in-package :cl-user)
    (defpackage :foo
      (:use :cl :prove))
    

    foo-test.lisp:

    (in-package :foo)
    
    (plan 2)
    (is (bar 2)
        4)
    (is (foo 2)
        8)
    (finalize)
    

    这使您可以使用sbcl --noinform --eval "(ql:quickload :foo-test)" --eval "(sb-ext:quit)" 之类的内容轻松地在新映像中运行测试(以确保实际在您磁盘上的代码版本有效)。如果您愿意,当然可以将测试放在函数后面。

    【讨论】:

    • 这是一个有趣的方法。我已经有一个单独的系统用于测试,但我没有想过要定义使用证明的包的替代版本。缺点是这需要我复制测试包和测试 asd 文件中的所有依赖项和文件,并且每当我对主包或 asd 文件进行更改时,我都必须在对应的测试文件。
    • @noctuid 确实如此,但我认为没有什么好的办法。我想您可以使用宏(/a 功能)有条件地添加测试并构建defpackages,但这可能会有点混乱。这种方法的优点是保持主代码干净。
    • 您的建议比在foo-tests.lisp 文件中拥有一个(:depends-on :foo :prove) 并在foo-tests.lisp 文件中拥有(in-package :foo) (use-package :prove)(我一直在寻找使用包)的单独系统有什么好处?重新定义 foo 包?
    • @noctuid 这将达到相同的效果,但您不能确保证明与您正在测试的包之间不会存在名称冲突。如果你确定这不会是一个问题,你也可以这样做。我认为您必须将use-package 包装在eval-when 中((eval-when (:compile-toplevel) (use-package :prove)))。
    猜你喜欢
    • 1970-01-01
    • 2014-07-16
    • 1970-01-01
    • 2023-01-04
    • 2013-01-27
    • 1970-01-01
    • 2015-09-25
    • 2017-06-17
    • 1970-01-01
    相关资源
    最近更新 更多