7

我是 CL 新手,正在使用 AllegroCL。我试图弄清楚如何组织我的源代码以满足以下要求:

  1. 我想阻止 src 代码包含我的测试套件。
  2. 我想以可移植的方式声明项目依赖项(src 和 test deps),这样我团队中的其他成员就不必修改他们的系统。
  3. 我想简化签入的持续集成,包括构建和测试。

我一直在尝试创造性地使用 ASDF 来满足这些要求,但我无法做到。其他人如何解决这个问题?这两个要求不是“Lispy”吗?

4

5 回答 5

5

使用 ASDF 或使用 Allegro CL defsystem 工具。

  1. 使它们成为两个不同的系统。测试套件系统依赖于软件系统。
  2. 使用相对路径名,根据系统定义文件的位置计算绝对路径名,或者,“pro”版本,使用逻辑路径名(它们是 CL 中的路径名,可以根据规则重新映射)。
  3. 可能有一个用于 Common Lisp 的持续集成工具,但我还没有使用任何工具。拥有 defsystem 描述是一个好的开始。
于 2012-08-15T16:02:18.743 回答
5

我正在使用 quicklisp,它会在您的主文件夹中创建一个“quicklisp”文件夹,其中可以找到一个“本地项目”文件夹。此文件包含一个 txt 文件,您可以在其中将 URI 插入 .asd 文件。

如何使用该实用程序:

  • 在项目文件夹中创建“project.asd”和“project-test.asd”

project.asd(管理纯项目代码的包含)

(asdf:defsystem :project-name
  :description "description here"
  :version "version here"
  :author "your name here"
  :depends-on (:a
               :list 
               :of
               :dependencie
               :libraries)
  :components ((:file "sourcefileone")
               (:file "sourcefiletwo")))

project-test.asd(管理测试代码的包含)

(asdf:defsystem :project-name-test
  :description "testing"
  ...
  :depends-on (:project-name)
  :components ((:file "sourcefileone-test")
               (:file "sourcefiletwo-test")))
  • 现在将这些文件的 URI 插入到上面命名的 local-projects.txt 中

  • 程序并行处理 <filename>.lisp 文件中的项目源代码和 <filename>-test.lisp 文件中的测试调用(*-test.lisp 文件必须包含测试执行调用)

  • 启动您的 sbcl 或您使用的任何东西,然后使用(ql:quickload "project-name")(ql:quickload "project-name-test")取决于您是否只想加载项目或测试它。

您唯一需要做的就是将它移植到其他任何地方,就是在复制项目的计算机上编写 local-projects.txt。之后,您的大学可能会在他们想要的任何其他项目中使用 asdf 文件和快速加载来依赖它。要复制项目文件夹,您可以使用 ctr+c/v 或者更复杂的 git。

为了测试,我编写了自己的小型测试套件,但我敢打赌那里有很好的测试套件。更多关于 quicklisp 的信息可以在这里找到,关于 asdf在这里。如果您在配置 quicklisp 时遇到困难,也许这个问题可以帮助您。

于 2012-08-16T09:56:13.137 回答
5

如果安装了 Quicklisp,您可以使用内置功能 Quickproject。

(ql:quickload "quickproject")
(quickproject:make-project "~/src/lisp/swatchblade/"
                         :depends-on '(vecto hunchentoot))

这将创建 4 个文件:

  • 包.lisp
  • swatchblade.lisp
  • 色板刀片.asd
  • 自述文件.txt

package.lisp 定义包命名空间:

(defpackage #:swatchblade  
(:use #:cl)
  (:shadowing-import-from #:vecto
                          #:with-canvas
                          #:rounded-rectangle
                          #:set-rgb-fill
                          #:save-png-stream))

swatchblade.asd 定义系统/项目、源代码文件、依赖项等。

(asdf:defsystem #:swatchblade 
 :serial t
  :depends-on (#:vecto
               #:hunchentoot
               #:cl-colors)
  :components ((:file "package")
               (:file "swatchblade")))

swatchblade.lisp 是源代码所在的位置。

您可以通过 Quicklisp 的快速加载加载项目:

* (ql:quickload "swatchblade")
loading output
* (swatchblade:start-web-server :port 8080)
Server started on port 8080.

如果您随后创建另一个依赖于 swatchblade 系统的项目:

quickproject:make-project "~/src/lisp/whimsytron/" 
                       :depends-on '(swatchblade))

关于测试,您可以在 package.lisp 中为您的测试添加另一个命名空间:

    (defpackage #:swatchblade-tests  
      (:use #:cl #:swatchblade))

创建一个测试文件,编写代码,并将文件添加到系统定义中:

(asdf:defsystem #:swatchblade 
 :serial t
  :depends-on (#:vecto
               #:hunchentoot
               #:cl-colors)
  :components ((:file "package")
               (:file "swatchblade")
               (:file "swatchglade-tests")))

加载swatchblade-tests命名空间以运行测试。

带有测试的示例项目在这里

如果您想避免 Quicklisp 将所有依赖项安装到系统中,据我所知,您必须安装依赖项并手动加载系统。

Quicklisp 的作者 Zach Beane 有一篇关于使用 quickproject的更详细的帖子。

于 2012-08-20T13:06:35.713 回答
4

根据 Rainer 的建议,我建议您使用 ASDF 系统定义工具来定义两个系统,即您的主系统foo和辅助系统foo-tests

foo系统的定义中,添加一个在 foo 上做的规范,in-order-to需要在foo -tests上做。这样可以确保如果您这样做,将加载相应的测试系统及其依赖项,然后 ASDF 将执行测试操作。test-optest-op(asdf:test-system "foo")

我发现 FiveAM 是一个适合构建测试的库。

以上将加载所有内容,但现在您需要确保执行test-opon foo-tests实际运行测试!为此,您需要在PERFORMforTEST-OP和上添加一个方法(eql (find-system "foo-tests"))。该PERFORM方法应该调用您定义的所有 FiveAM 测试,并且要么成功,要么在测试失败时引发错误。

我为 ASDF 制作了一个 FiveAM-tester 插件。我将尝试将其公开。

于 2012-08-16T18:54:04.313 回答
1

重要的

上面的建议很好,但你会在尝试测试未导出的东西时感到沮丧。一个简单的解决方法是不要定义两个包。只需将您的测试与其他来源放在同一个包中。有什么害处?

如果您认为会有伤害,那么您将不得不这样做:

(defpackage #:sources
  (:use #:cl))

(defpackage #:tests
  (:use #:cl #:lisp-unit)
  (:import-from #:sources))

重要的部分是:import-from你的源代码包而不是:useing 它。

然后,当您在测试包中使用它们时,您必须对源包中的符号进行限定。例如,假设你有这个功能:

(defun return-true () t)

您的测试可能如下所示:

(define-test test-return-true
  "Make sure it works"
  (assert-equal t (sources::return-true)))

重要的部分是你的意思,(sources::return-true)而不是仅仅(return-true)。像'sym;这样的符号也是如此。将其称为'sources::sym.

于 2017-02-08T20:19:36.330 回答