我可以对ELisp函数进行文档测试吗?

时间:2019-09-26 19:44:31

标签: testing elisp regression-testing

我喜欢doc-tests的Python功能,用于独立测试功能。 Emacs Lisp是否有类似的东西,或者我可以以某种方式模仿它?

例如,此函数从组织模式时钟段获取时间戳:

(defun org-get-timestamps (line)
  "Parses a clock segment line and returns the first and last timestamps in a list."
  (let* ((org-clock-regexp (concat "CLOCK: " org-ts-regexp3 "--" org-ts-regexp3))
     (t1 (if (string-match org-clock-regexp line)
         (match-string 1 line)
           (user-error "The argument must have a valid CLOCK range")))
     (t2 (match-string 9 line)))
    (cons t1 (cons t2 '()))))

我想要一个文档测试,例如:

(org-get-timestamps "CLOCK: [2019-09-26 Thu 00:29]--[2019-09-26 Thu 01:11] =>  0:42")
("2019-09-26 Thu 00:29" "2019-09-26 Thu 01:11")

user-error进行测试也很好。

我还想确保任何重构都能通过文档测试,因此它也是回归测试。

存在吗?

1 个答案:

答案 0 :(得分:1)

Python doctest的一个重要功能是其输入看起来像Python交互式REPL会话,如doctest documentation中所述:

  

doctest模块搜索看起来像   交互式Python会话,然后执行这些会话以   验证它们是否完全按照所示方式工作。

我不知道有什么像这样的elisp设施,但我认为您可以使用Emacs Lisp Regression Testing (ERT) framework来实现所需的功能,该版本支持交互式和批处理测试执行。

要测试org-get-timestamps函数,您可以定义如下测试:

(require 'ert)

(ert-deftest org-timestamp-test ()
  (should (equal
           (org-get-timestamps "CLOCK: [2019-09-26 Thu 00:29]--[2019-09-26 Thu 01:11] => 0:42")
           '("2019-09-26 Thu 00:29" "2019-09-26 Thu 01:11"))))

要以交互方式运行测试,可以键入 Mx ert ,按Enter键,然后再次按Enter键以使用默认的t参数选择所有测试,或键入测试名称。运行测试并按Enter键,测试结果将显示在*ert*缓冲区中:

Selector: org-timestamp-test
Passed:  1
Failed:  0
Skipped: 0
Total:   1/1

Started at:   2019-09-27 08:44:57-0400
Finished.
Finished at:  2019-09-27 08:44:57-0400

.

上面最后的点字符代表已运行的测试。如果执行了多个测试,将有多个点。

要以批处理模式运行测试,请将其保存到文件org-timestamp-test.el中,并假设org-get-timestamps函数位于文件org-timestamps.el中,请从您的shell命令行像这样运行它:

emacs -batch -l ert -l org-timestamps.el -l org-timestamp-test.el -f ert-run-tests-batch-and-exit

然后将测试结果显示在shell输出中:

  

运行1个测试(2019-09-27 06:03:09-0700)通过了1/1   org-timestamp-test

     

进行了1次测试,结果达到了预期的1个结果(2019-09-27 06:03:09-0700)