0

---+ 简介

问:如果我对 ert 有多个单独的独立调用,我可以安排将这些测试的输出连接到同一个缓冲区中吗?对 ert 的调用是在不同的时间进行的?

(没有一个了解这些独立测试的集中式 thingamajig。)

例如,如果我有两个(或更多)测试,例如在 .emacs 文件中

 (ert-deftest test1 ()(should t))
 (ert 'test1)

 ... many miles away, quite likely in a separate file ...

 (ert-deftest test2 ()(should t))
 (ert 'test2)

两者都会运行 - 我可以通过查看*Messages*

...
Running 1 tests (2017-07-07 12:10:39-0700)
   passed  1/1  test_ag_non-null_and_true
...
Running 1 tests (2017-07-07 12:10:39-0700)
   passed  1/1  test-ag-code-disabling
...

但是*ert*缓冲区将只包含最后一次测试运行的输出。

---+ 详情

---++ 动机

问:我为什么要这样做?

答:“在线测试”。特别是对我的 .emacs 文件(以及它加载和/或需要的文件)中的内容进行内联测试。

每次加载 .emacs 或类似文件时运行的测试。(可能还有其他我在批处理模式下运行的测试 - 但在这里我谈论的是我想在每次加载 .emacs 时立即运行的测试(并且在修改 .emacs 时便于编辑/调试)。

即我正在寻找内联测试的成语。

我一直将代码放入我的 .emacs 和 ~/lib/gnu-emacs/**.el 文件中,如下所示:

;; some blob of code
(defun foo (arg) ... )

(ert-deftest test-foo () ... )
(ert 'test-foo)

即我定义函数、测试并运行测试,就在彼此旁边。

......我不妨承认我经常包裹一个“progn”,

(progn     
   ;; some blob of code
   (defun foo (arg) ... ) 
   (ert-deftest test-foo () ... )
   (ert 'test-foo)
)

因为这样可以很容易地对函数 foo 或测试进行编辑,然后跳转到 progn 的末尾并执行 eval-last-sexp(我已绑定到 Cj)。而且我还经常包装 if 或 and and ,以便轻松禁用正在开发的功能。如果特征有变量,有时用 let* in 然后混合。

(我使用过其他ert - family 跑步者,例如ert-run-tests-batchert-run-tests-interactively。但普通的旧ert似乎就足够了。)

(将defundeftest放在progn或其他文件中会破坏一些期望 defun 始终处于顶层的工具。它使多行文档字符串更加丑陋。但这非常方便,恕我直言,对编程语言文件进行操作的工具应该解析编程语。)

所以,稍后,我将为另一个模块做同样的事情。远处。可能在一个单独的文件中,可能是一个库文件。

(progn     
   ;; some blob of code
   (defun bar (arg) ... ) 
   (ert-deftest test-bar () ... )
   (ert 'test-bar)
)

两个模块都不应该知道另一个模块。

也不应该有一个集中的模块,其中包含所有此类测试的列表,并在最后运行。

如果只是因为加载文件的中途可能会失败。并且可以很方便地知道到目前为止哪些测试通过或失败。

(而在最后收集和运行所有测试会失去增量测试运行能力。)

---++ 应该是宏

我讨厌重复。例如,在下面的内容中,我讨厌必须输入三遍 BAR。

(progn     
   ;; some blob of code
   (defun BAR (arg) ... ) 
   (ert-deftest test-BAR () ... )
   (ert 'test-BAR)
)

因此,我当然会创建一个宏来减少这种重复。虽然那时寻找ert-deftest 的人会感到困惑......

---++ 中等长度的简单示例

如果我有

  (ert-deftest test1 ()(should t))
  (ert 'test1)

我会得到一个很好的*ert*缓冲区

Selector: test1
Passed:  1
Failed:  0
Skipped: 0
Total:   1/1

Started at:   2017-07-07 14:16:06-0700
Finished.
Finished at:  2017-07-07 14:16:07-0700

.

如果以后我有

(ert-deftest test2 () (should t))
(ert 'test2)

它将擦除*ert*缓冲区中 test1 的输出,并将其替换为

Selector: test2
Passed:  1
Failed:  0
Skipped: 0
Total:   1/1

Started at:   2017-07-07 14:15:47-0700
Finished.
Finished at:  2017-07-07 14:15:47-0700

.

我想要的是连接两个测试的输出:

Selector: test1
Passed:  1
Failed:  0
Skipped: 0
Total:   1/1

Started at:   2017-07-07 14:16:06-0700
Finished.
Finished at:  2017-07-07 14:16:07-0700

.

Selector: test2
Passed:  1
Failed:  0
Skipped: 0
Total:   1/1

Started at:   2017-07-07 14:15:47-0700
Finished.
Finished at:  2017-07-07 14:15:47-0700

.
4

1 回答 1

0

正如经常发生的那样,发布问题的行为暗示了答案。

虽然它有些丑陋,而且肯定是不标准的。因此,如果有人发布简洁的标准方式,我会接受这样的答案。

恕我直言丑陋的方式:

当我做

(progn     
   ;; some blob of code
   (defun foo (arg) ... ) 
   (ert-deftest test-foo () ... )
   (ert 'test-foo)
)

我可以添加更多代码来操作ert输出缓冲区:

(progn     
   ;; some blob of code
   (defun foo (arg) ... ) 
   (ert-deftest test-foo () ... )
   (ert 'test-foo)
   ...append `*ert*' contents to `*ert-multiple-independent-tests*'
)

(如果是宏字段,则更少键入)

这是显而易见的。我希望 'ert' 的“自动自检”参数可能会完成类似的事情。

ert is an alias for ‘ert-run-tests-interactively’ in ‘ert.el’.

(ert SELECTOR &optional OUTPUT-BUFFER-NAME MESSAGE-FN)

Run the tests specified by SELECTOR and display the results in a buffer.

SELECTOR works as described in ‘ert-select-tests’.
OUTPUT-BUFFER-NAME and MESSAGE-FN should normally be nil; they
are used for automated self-tests and specify which buffer to use
and how to display message.

迄今为止,敷衍的调查收效甚微。

我希望有一个更好的方法,如果只是因为它可能已经确定了是否在批处理模式下执行此操作等的详细信息。

或者,如果有人不仅设法将独立测试的ert缓冲区连接起来,而且还设法创建了一个融合缓冲区,可以简明扼要地报告所有内容。

于 2017-07-07T22:34:13.010 回答