运行 docstring 中的测试

昨天看 The Python Tutorial 中有个 doctest 模块

可以把测试写在 docstring 里面,比如:

def average(values):
    """Computes the arithmetic mean of a list of numbers.

    >>> print(average([20, 30, 70]))
    40.0
    """
    return sum(values) / len(values)

import doctest
doctest.testmod()          # automatically validate the embedded tests

正好 Emacs Lisp 也有 docstring,所以也试试这个功能。

(defun average (values)
  "Return the arithmetic mean of a list of numbers.

>>> (average '(1 2 3))
2.0
>>> (average '(20 30 70))
40.0
"
  (/ (float (apply #'+ values)) (length values)))

(defun doctest (fun)
  "Run examples in docstring of FUN."
  (interactive "aFunction: ")
  (let (pairs (failures 0))
    ;; Collect examples
    (with-temp-buffer
      (insert (documentation fun t))
      (goto-char (point-min))
      (while (search-forward ">>>" nil t)
        (push (cons (read (current-buffer)) (read (current-buffer))) pairs))
      (setq pairs (nreverse pairs)))
    ;; Run examples
    (dolist (p pairs)
      (pcase-let ((`(,expr . ,result) p))
        (unless (equal (eval expr) result)
          (message "Eval %s failed, expected %s" expr result)
          (cl-incf failures))))
    ;; Final report
    (message "Test Results: failed=%d, attempted=%d" failures (length pairs))))

(doctest #'average)
     => "Test Results: failed=0, attempted=2"
2 个赞