r3144: *** empty log message ***
[xptest.git] / xptest-example.lisp
1 ;;; -*- Mode: Lisp -*-
2 ;;;; xptest-eaxmple.lisp --- Example of test suite based on Extreme
3 ;;;;                         Programming Framework by Kent Beck
4 ;;;;
5 ;;;; Author: Craig Brozefsky <craig@onshore.com>
6 ;;;; Put in public domain by onShore, Inc
7 (in-package :xp-test-example)
8
9 ;;; First we define some basic fixtures that we are going to need to
10 ;;; perform our tests.  A fixture is a place to hold data we need
11 ;;; during testing.  Often there are many test cases that use the same
12 ;;; data.  Each of these test cases is an instance of a test-fixture.
13
14 (def-test-fixture math-fixture ()
15   ((numbera
16     :accessor numbera)
17    (numberb
18     :accessor numberb))
19   (:documentation "Test fixture for math testing"))
20
21 ;;; Then we define a setup method for the fixture.  This method is run
22 ;;; prior to perfoming any test with an instance of this fixture.  It
23 ;;; should perform all initialization needed, and assume that it is starting
24 ;;; with a pristine environment, well to a point, use your head here.
25
26 (defmethod setup ((fix math-fixture))
27   (setf (numbera fix) 2)
28   (setf (numberb fix) 3))
29
30 ;;; Then we define a teardown method, which should return the instance
31 ;;; to it's original form and reset the environment.  In this case
32 ;;; there is little for us to do since the fixture is quite static.
33 ;;; In other cases we may need to clear some database tables, or
34 ;;; otherwise get rid of state built up while perofmring the test.
35 ;;; Here we just return T.
36
37 (defmethod teardown ((fix math-fixture))
38   t)
39
40 ;;; Once we hav a fixture we can start defining method on it which
41 ;;; will perform tests.  These methods should take one argument, an
42 ;;; instance of the fixture.  The method performs some operation and
43 ;;; then performs some tests to determine if the proper behavior
44 ;;; occured.  If there is a failure to behave as excpeted the method
45 ;;; raises a test-failure object by calling the method FAILURE.  This
46 ;;; is much like calling ERROR in that it stops processing that
47 ;;; method.  Each method should only check for one aspect of behavior.
48 ;;; This way triggering one failure would not result in another
49 ;;; behavior check from being skipped.  It does not matter what these
50 ;;; methods return
51
52 (defmethod addition-test ((test math-fixture))
53   (let ((result (+ (numbera test) (numberb test))))
54     (unless (= result 5)
55       (failure "Result was not 5 when adding ~A and ~A"
56                (numbera test) (numberb test)))))
57
58 (defmethod subtraction-test ((test math-fixture))
59   (let ((result (- (numberb test) (numbera test))))
60     (unless (= result 1)
61       (failure "Result was not 1 when subtracting ~A ~A"
62               (numberb test) (numbera test)))))
63
64 ;;; This method is meant to signal a failure
65 (defmethod subtraction-test2 ((test math-fixture))
66   (let ((result (- (numbera test) (numberb test))))
67     (unless (= result 1)
68       (failure "Result was not 1 when subtracting ~A ~A"
69               (numbera test) (numberb test)))))
70
71
72 ;;; Now we can create a test-suite.  A test-suite contains a group of
73 ;;; test-cases (instances of test-fixture) and/or other test-suites.
74 ;;; We can specify which tests are in a test-suite when we define the
75 ;;; test-suite, or we can add them later.  See the documentation and
76 ;;; argument list for make-test-case for details on how to specify a
77 ;;; test-case.
78
79 (setf math-test-suite (make-test-suite
80                        "Math Test Suite"
81                        "Simple test suite for arithmetic operators."
82                        ("Addition Test" 'math-fixture
83                         :test-thunk 'addition-test
84                         :description "A simple test of the + operator")
85                        ("Subtraction Test" 'math-fixture
86                         :test-thunk 'subtraction-test
87                         :description "A simple test of the - operator")))
88
89 (add-test (make-test-case "Substraction Test 2" 'math-fixture
90                           :test-thunk 'subtraction-test2
91                           :description "A broken substraction test, should fail.")
92           math-test-suite)
93
94 ;;;; Finally we can run our test suite and see how it performs.
95 ;;;; (report-result (run-test math-test-suite) :verbose t)