comparison tests/automated/test-harness.el @ 5118:e0db3c197671 ben-lisp-object

merge up to latest default branch, doesn't compile yet
author Ben Wing <ben@xemacs.org>
date Sat, 26 Dec 2009 21:18:49 -0600
parents 294a86d29f99
children a3c673c0720b
comparison
equal deleted inserted replaced
5117:3742ea8250b5 5118:e0db3c197671
36 ;;; Don't suppress tests just because they're due to known bugs not yet 36 ;;; Don't suppress tests just because they're due to known bugs not yet
37 ;;; fixed -- use the Known-Bug-Expect-Failure and 37 ;;; fixed -- use the Known-Bug-Expect-Failure and
38 ;;; Implementation-Incomplete-Expect-Failure wrapper macros to mark them. 38 ;;; Implementation-Incomplete-Expect-Failure wrapper macros to mark them.
39 ;;; A lot of the tests we run push limits; suppress Ebola message with the 39 ;;; A lot of the tests we run push limits; suppress Ebola message with the
40 ;;; Ignore-Ebola wrapper macro. 40 ;;; Ignore-Ebola wrapper macro.
41 ;;; Some noisy code will call `message'. Output from `message' can be
42 ;;; suppressed with the Silence-Message macro. Functions that are known to
43 ;;; issue messages include `write-region', `find-tag', `tag-loop-continue',
44 ;;; `insert', and `mark-whole-buffer'. N.B. The Silence-Message macro
45 ;;; currently does not suppress the newlines printed by `message'.
46 ;;; Definitely do not use Silence-Message with Check-Message.
47 ;;; In general it should probably only be used on code that prepares for a
48 ;;; test, not on tests.
41 ;;; 49 ;;;
42 ;;; You run the tests using M-x test-emacs-test-file, 50 ;;; You run the tests using M-x test-emacs-test-file,
43 ;;; or $(EMACS) -batch -l .../test-harness.el -f batch-test-emacs file ... 51 ;;; or $(EMACS) -batch -l .../test-harness.el -f batch-test-emacs file ...
44 ;;; which is run for you by the `make check' target in the top-level Makefile. 52 ;;; which is run for you by the `make check' target in the top-level Makefile.
45 53
46 (require 'bytecomp) 54 (require 'bytecomp)
47 55
56 (defvar unexpected-test-suite-failures 0
57 "Cumulative number of unexpected failures since test-harness was loaded.
58
59 \"Unexpected failures\" are those caught by a generic handler established
60 outside of the test context. As such they involve an abort of the test
61 suite for the file being tested.
62
63 They often occur during preparation of a test or recording of the results.
64 For example, an executable used to generate test data might not be present
65 on the system, or a system error might occur while reading a data file.")
66
67 (defvar unexpected-test-suite-failure-files nil
68 "List of test files causing unexpected failures.")
69
70 ;; Declared for dynamic scope; _do not_ initialize here.
71 (defvar unexpected-test-file-failures)
72
48 (defvar test-harness-test-compiled nil 73 (defvar test-harness-test-compiled nil
49 "Non-nil means the test code was compiled before execution.") 74 "Non-nil means the test code was compiled before execution.
75
76 You probably should not make tests depend on compilation.
77 However, it can be useful to conditionally change messages based on whether
78 the code was compiled or not. For example, the case that motivated the
79 implementation of this variable:
80
81 \(when test-harness-test-compiled
82 ;; this ha-a-ack depends on the failing compiled test coming last
83 \(setq test-harness-failure-tag
84 \"KNOWN BUG - fix reverted; after 2003-10-31 notify stephen\n\"))")
50 85
51 (defvar test-harness-verbose 86 (defvar test-harness-verbose
52 (and (not noninteractive) (> (device-baud-rate) search-slow-speed)) 87 (and (not noninteractive) (> (device-baud-rate) search-slow-speed))
53 "*Non-nil means print messages describing progress of emacs-tester.") 88 "*Non-nil means print messages describing progress of emacs-tester.")
54 89
132 (condition-case error-info 167 (condition-case error-info
133 (while t 168 (while t
134 (setq body (cons (read buffer) body))) 169 (setq body (cons (read buffer) body)))
135 (end-of-file nil) 170 (end-of-file nil)
136 (error 171 (error
172 (incf unexpected-test-file-failures)
137 (princ (format "Unexpected error %S reading forms from buffer\n" 173 (princ (format "Unexpected error %S reading forms from buffer\n"
138 error-info)))) 174 error-info))))
139 `(lambda () 175 `(lambda ()
140 (defvar passes) 176 (defvar passes)
141 (defvar assertion-failures) 177 (defvar assertion-failures)
142 (defvar no-error-failures) 178 (defvar no-error-failures)
143 (defvar wrong-error-failures) 179 (defvar wrong-error-failures)
144 (defvar missing-message-failures) 180 (defvar missing-message-failures)
145 (defvar other-failures) 181 (defvar other-failures)
146 182
147 (defvar unexpected-test-suite-failure)
148 (defvar trick-optimizer) 183 (defvar trick-optimizer)
149 184
150 ,@(nreverse body)))) 185 ,@(nreverse body))))
151 186
152 (defun test-harness-from-buffer (inbuffer filename) 187 (defun test-harness-from-buffer (inbuffer filename)
156 (assertion-failures 0) 191 (assertion-failures 0)
157 (no-error-failures 0) 192 (no-error-failures 0)
158 (wrong-error-failures 0) 193 (wrong-error-failures 0)
159 (missing-message-failures 0) 194 (missing-message-failures 0)
160 (other-failures 0) 195 (other-failures 0)
196 (unexpected-test-file-failures 0)
161 197
162 ;; #### perhaps this should be a defvar, and output at the very end 198 ;; #### perhaps this should be a defvar, and output at the very end
163 ;; OTOH, this way AC types can use a null EMACSPACKAGEPATH to find 199 ;; OTOH, this way AC types can use a null EMACSPACKAGEPATH to find
164 ;; what stuff is needed, and ways to avoid using them 200 ;; what stuff is needed, and ways to avoid using them
165 (skipped-test-reasons (make-hash-table :test 'equal)) 201 (skipped-test-reasons (make-hash-table :test 'equal))
166 202
167 (trick-optimizer nil) 203 (trick-optimizer nil)
168 (unexpected-test-suite-failure nil)
169 (debug-on-error t) 204 (debug-on-error t)
170 (pass-stream nil)) 205 (pass-stream nil))
171 (with-output-to-temp-buffer "*Test-Log*" 206 (with-output-to-temp-buffer "*Test-Log*"
172 (princ (format "Testing %s...\n\n" filename)) 207 (princ (format "Testing %s...\n\n" filename))
173 208
176 211
177 (defmacro Known-Bug-Expect-Failure (&rest body) 212 (defmacro Known-Bug-Expect-Failure (&rest body)
178 `(let ((test-harness-failure-tag "KNOWN BUG") 213 `(let ((test-harness-failure-tag "KNOWN BUG")
179 (test-harness-success-tag "PASS (FAILURE EXPECTED)")) 214 (test-harness-success-tag "PASS (FAILURE EXPECTED)"))
180 ,@body)) 215 ,@body))
181 216
217 (defmacro Known-Bug-Expect-Error (expected-error &rest body)
218 (let ((quoted-body (if (= 1 (length body))
219 `(quote ,(car body)) `(quote (progn ,@body)))))
220 `(let ((test-harness-failure-tag "KNOWN BUG")
221 (test-harness-success-tag "PASS (FAILURE EXPECTED)"))
222 (condition-case error-info
223 (progn
224 (setq trick-optimizer (progn ,@body))
225 (Print-Pass
226 "%S executed successfully, but expected error %S"
227 ,quoted-body
228 ',expected-error)
229 (incf passes))
230 (,expected-error
231 (Print-Failure "%S ==> error %S, as expected"
232 ,quoted-body ',expected-error)
233 (incf no-error-failures))
234 (error
235 (Print-Failure "%S ==> expected error %S, got error %S instead"
236 ,quoted-body ',expected-error error-info)
237 (incf wrong-error-failures))))))
238
182 (defmacro Implementation-Incomplete-Expect-Failure (&rest body) 239 (defmacro Implementation-Incomplete-Expect-Failure (&rest body)
183 `(let ((test-harness-failure-tag "IMPLEMENTATION INCOMPLETE") 240 `(let ((test-harness-failure-tag "IMPLEMENTATION INCOMPLETE")
184 (test-harness-success-tag "PASS (FAILURE EXPECTED)")) 241 (test-harness-success-tag "PASS (FAILURE EXPECTED)"))
185 ,@body)) 242 ,@body))
186 243
208 (puthash ,reason (if (null count) 1 (1+ count)) 265 (puthash ,reason (if (null count) 1 (1+ count))
209 skipped-test-reasons) 266 skipped-test-reasons)
210 (Print-Skip ,description ,reason)) 267 (Print-Skip ,description ,reason))
211 ,@body)) 268 ,@body))
212 269
213 (defmacro Assert (assertion &optional failing-case) 270 (defmacro Assert (assertion &optional failing-case description)
271 "Test passes if ASSERTION is true.
272 Optional FAILING-CASE describes the particular failure.
273 Optional DESCRIPTION describes the assertion.
274 FAILING-CASE and DESCRIPTION are useful when Assert is used in a loop."
214 `(condition-case error-info 275 `(condition-case error-info
215 (progn 276 (progn
216 (assert ,assertion) 277 (assert ,assertion)
217 (Print-Pass "%S" (quote ,assertion)) 278 (Print-Pass "%S" (quote ,(or description assertion)))
218 (incf passes)) 279 (incf passes))
219 (cl-assertion-failed 280 (cl-assertion-failed
220 (Print-Failure (if ,failing-case 281 (Print-Failure (if ,failing-case
221 "Assertion failed: %S; failing case = %S" 282 "Assertion failed: %S; failing case = %S"
222 "Assertion failed: %S") 283 "Assertion failed: %S")
223 (quote ,assertion) ,failing-case) 284 (quote ,(or description assertion)) ,failing-case)
224 (incf assertion-failures)) 285 (incf assertion-failures))
225 (t (Print-Failure (if ,failing-case 286 (t (Print-Failure (if ,failing-case
226 "%S ==> error: %S; failing case = %S" 287 "%S ==> error: %S; failing case = %S"
227 "%S ==> error: %S") 288 "%S ==> error: %S")
228 (quote ,assertion) error-info ,failing-case) 289 (quote ,(or description assertion))
290 error-info ,failing-case)
229 (incf other-failures) 291 (incf other-failures)
230 ))) 292 )))
231 293
232 294
233 (defmacro Check-Error (expected-error &rest body) 295 (defmacro Check-Error (expected-error &rest body)
258 (setq trick-optimizer (progn ,@body)) 320 (setq trick-optimizer (progn ,@body))
259 (Print-Failure "%S executed successfully, but expected error %S" 321 (Print-Failure "%S executed successfully, but expected error %S"
260 ,quoted-body ',expected-error) 322 ,quoted-body ',expected-error)
261 (incf no-error-failures)) 323 (incf no-error-failures))
262 (,expected-error 324 (,expected-error
325 ;; #### Damn, this binding doesn't capture frobs, eg, for
326 ;; invalid_argument() ... you only get the REASON. And for
327 ;; wrong_type_argument(), there's no reason only FROBs.
328 ;; If this gets fixed, fix tests in regexp-tests.el.
263 (let ((error-message (second error-info))) 329 (let ((error-message (second error-info)))
264 (if (string-match ,expected-error-regexp error-message) 330 (if (string-match ,expected-error-regexp error-message)
265 (progn 331 (progn
266 (Print-Pass "%S ==> error %S %S, as expected" 332 (Print-Pass "%S ==> error %S %S, as expected"
267 ,quoted-body error-message ',expected-error) 333 ,quoted-body error-message ',expected-error)
272 (error 338 (error
273 (Print-Failure "%S ==> expected error %S, got error %S instead" 339 (Print-Failure "%S ==> expected error %S, got error %S instead"
274 ,quoted-body ',expected-error error-info) 340 ,quoted-body ',expected-error error-info)
275 (incf wrong-error-failures))))) 341 (incf wrong-error-failures)))))
276 342
277 343 ;; Do not use this with Silence-Message.
278 (defmacro Check-Message (expected-message-regexp &rest body) 344 (defmacro Check-Message (expected-message-regexp &rest body)
279 (Skip-Test-Unless (fboundp 'defadvice) 345 (Skip-Test-Unless (fboundp 'defadvice)
280 "can't defadvice" 346 "can't defadvice"
281 expected-message-regexp 347 expected-message-regexp
282 (let ((quoted-body (if (= 1 (length body)) 348 (let ((quoted-body (if (= 1 (length body))
304 (Print-Failure "%S ==> unexpected error %S" 370 (Print-Failure "%S ==> unexpected error %S"
305 ,quoted-body error-info) 371 ,quoted-body error-info)
306 (incf other-failures))) 372 (incf other-failures)))
307 (ad-unadvise 'message))))) 373 (ad-unadvise 'message)))))
308 374
375 ;; #### Perhaps this should override `message' itself, too?
376 (defmacro Silence-Message (&rest body)
377 `(flet ((append-message (&rest args) ())
378 (clear-message (&rest args) ()))
379 ,@body))
380
309 (defmacro Ignore-Ebola (&rest body) 381 (defmacro Ignore-Ebola (&rest body)
310 `(let ((debug-issue-ebola-notices -42)) ,@body)) 382 `(let ((debug-issue-ebola-notices -42)) ,@body))
311 383
312 (defun Int-to-Marker (pos) 384 (defun Int-to-Marker (pos)
313 (save-excursion 385 (save-excursion
318 390
319 (princ "Testing Interpreted Lisp\n\n") 391 (princ "Testing Interpreted Lisp\n\n")
320 (condition-case error-info 392 (condition-case error-info
321 (funcall (test-harness-read-from-buffer inbuffer)) 393 (funcall (test-harness-read-from-buffer inbuffer))
322 (error 394 (error
323 (setq unexpected-test-suite-failure t) 395 (incf unexpected-test-file-failures)
324 (princ (format "Unexpected error %S while executing interpreted code\n" 396 (princ (format "Unexpected error %S while executing interpreted code\n"
325 error-info)) 397 error-info))
326 (message "Unexpected error %S while executing interpreted code." error-info) 398 (message "Unexpected error %S while executing interpreted code." error-info)
327 (message "Test suite execution aborted." error-info) 399 (message "Test suite execution aborted." error-info)
328 )) 400 ))
339 (princ (format "Unexpected error %S while byte-compiling code\n" 411 (princ (format "Unexpected error %S while byte-compiling code\n"
340 error-info)))) 412 error-info))))
341 (condition-case error-info 413 (condition-case error-info
342 (if code (funcall code)) 414 (if code (funcall code))
343 (error 415 (error
416 (incf unexpected-test-file-failures)
344 (princ (format "Unexpected error %S while executing byte-compiled code\n" 417 (princ (format "Unexpected error %S while executing byte-compiled code\n"
345 error-info)) 418 error-info))
346 (message "Unexpected error %S while executing byte-compiled code." error-info) 419 (message "Unexpected error %S while executing byte-compiled code." error-info)
347 (message "Test suite execution aborted." error-info) 420 (message "Test suite execution aborted." error-info)
348 ))) 421 )))
374 (format "\n %d tests skipped because %s." 447 (format "\n %d tests skipped because %s."
375 value key)))) 448 value key))))
376 skipped-test-reasons) 449 skipped-test-reasons)
377 (when (> (length reasons) 1) 450 (when (> (length reasons) 1)
378 (setq summary-msg (concat summary-msg reasons " 451 (setq summary-msg (concat summary-msg reasons "
379 Probably XEmacs cannot find your installed packages. Set EMACSPACKAGEPATH 452 It may be that XEmacs cannot find your installed packages. Set
380 to the package hierarchy root or configure with --package-path to enable 453 EMACSPACKAGEPATH to the package hierarchy root or configure with
381 the skipped tests."))) 454 --package-path to enable the skipped tests.")))
382 (setq test-harness-file-results-alist 455 (setq test-harness-file-results-alist
383 (cons (list filename passes total) 456 (cons (list filename passes total)
384 test-harness-file-results-alist)) 457 test-harness-file-results-alist))
385 (message "%s" summary-msg)) 458 (message "%s" summary-msg))
386 (when unexpected-test-suite-failure 459 (when (> unexpected-test-file-failures 0)
460 (setq unexpected-test-suite-failure-files
461 (cons filename unexpected-test-suite-failure-files))
462 (setq unexpected-test-suite-failures
463 (+ unexpected-test-suite-failures unexpected-test-file-failures))
387 (message "Test suite execution failed unexpectedly.")) 464 (message "Test suite execution failed unexpectedly."))
388 (fmakunbound 'Assert) 465 (fmakunbound 'Assert)
389 (fmakunbound 'Check-Error) 466 (fmakunbound 'Check-Error)
390 (fmakunbound 'Check-Message) 467 (fmakunbound 'Check-Message)
391 (fmakunbound 'Check-Error-Message) 468 (fmakunbound 'Check-Error-Message)
508 nsucc 585 nsucc
509 ntest 586 ntest
510 (/ (* 100 nsucc) ntest)) 587 (/ (* 100 nsucc) ntest))
511 (message test-harness-null-summary-template 588 (message test-harness-null-summary-template
512 (concat basename ":"))) 589 (concat basename ":")))
513 (setq results (cdr results)))))) 590 (setq results (cdr results)))))
591 (when (> unexpected-test-suite-failures 0)
592 (message "\n***** There %s %d unexpected test suite %s in %s:"
593 (if (= unexpected-test-suite-failures 1) "was" "were")
594 unexpected-test-suite-failures
595 (if (= unexpected-test-suite-failures 1) "failure" "failures")
596 (if (= (length unexpected-test-suite-failure-files) 1)
597 "file"
598 "files"))
599 (while unexpected-test-suite-failure-files
600 (let ((line (pop unexpected-test-suite-failure-files)))
601 (while (and (< (length line) 61)
602 unexpected-test-suite-failure-files)
603 (setq line
604 (concat line " "
605 (pop unexpected-test-suite-failure-files))))
606 (message line)))))
514 (message "\nDone") 607 (message "\nDone")
515 (kill-emacs (if error 1 0)))) 608 (kill-emacs (if error 1 0))))
516 609
517 (provide 'test-harness) 610 (provide 'test-harness)
518 611