added test-* shortcuts to docs, other edits
This commit is contained in:
parent
962ceb6b63
commit
c5e6580f02
|
@ -26,10 +26,10 @@ can create your own checks using @racket[define-check].
|
||||||
[(check-equal? (v1 any) (v2 any) (message string? "")) void?]
|
[(check-equal? (v1 any) (v2 any) (message string? "")) void?]
|
||||||
[(check-not-equal? (v1 any) (v2 any) (message string? "")) void?])]{
|
[(check-not-equal? (v1 any) (v2 any) (message string? "")) void?])]{
|
||||||
|
|
||||||
Checks that @racket[v1] is (not) @racket[eq?],
|
Checks that @racket[v1] is equal (or not equal) to @racket[v2], using
|
||||||
@racket[eqv?], or @racket[equal?] to @racket[v2]. The
|
@racket[eq?], @racket[eqv?], or @racket[equal?], respectively. The
|
||||||
optional @racket[message] is included in the output if the
|
optional @racket[message] is included in the output if the check
|
||||||
check fails.}
|
fails.
|
||||||
|
|
||||||
For example, the following checks all fail:
|
For example, the following checks all fail:
|
||||||
|
|
||||||
|
@ -41,39 +41,52 @@ For example, the following checks all fail:
|
||||||
(check-equal? 1 1.0 "not equal?")
|
(check-equal? 1 1.0 "not equal?")
|
||||||
(check-not-equal? (list 1) (list 1) "equal?")
|
(check-not-equal? (list 1) (list 1) "equal?")
|
||||||
]
|
]
|
||||||
|
}
|
||||||
|
|
||||||
@defproc[(check-pred (pred (-> any any)) (v any) (message string? ""))
|
@defproc[(check-pred (pred (-> any any)) (v any) (message string? ""))
|
||||||
void?]{Checks that @racket[pred] returns a value that is not @racket[#f] when applied to @racket[v]. The optional @racket[message] is included in the output if the check fails. The value returned by a successful check is the value returned by @racket[pred].}
|
void?]{
|
||||||
|
|
||||||
Here's an example that passes and an example that fails:
|
Checks that @racket[pred] returns a value that is not @racket[#f] when
|
||||||
|
applied to @racket[v]. The optional @racket[message] is included in
|
||||||
|
the output if the check fails. The value returned by a successful
|
||||||
|
check is the value returned by @racket[pred].
|
||||||
|
|
||||||
|
For example, the following check passes:
|
||||||
@racketblock[
|
@racketblock[
|
||||||
(check-pred string? "I work")
|
(check-pred string? "I work")
|
||||||
|
]
|
||||||
|
The following check fails:
|
||||||
|
@racketblock[
|
||||||
(check-pred number? "I fail")
|
(check-pred number? "I fail")
|
||||||
]
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
@defproc[(check-= (v1 any) (v2 any) (epsilon number?) (message string? ""))
|
||||||
@defproc[(check-= (v1 any) (v2 any) (epsilon number?) (message string? "")) void?]{
|
void?]{
|
||||||
|
|
||||||
Checks that @racket[v1] and @racket[v2] are within
|
Checks that @racket[v1] and @racket[v2] are within
|
||||||
@racket[epsilon] of one another. The optional
|
@racket[epsilon] of one another. The optional
|
||||||
@racket[message] is included in the output if the check
|
@racket[message] is included in the output if the check
|
||||||
fails.}
|
fails.
|
||||||
|
|
||||||
Here's an example that passes and an example that fails:
|
For example, the following check passes:
|
||||||
|
|
||||||
@racketblock[
|
@racketblock[
|
||||||
(check-= 1.0 1.01 0.01 "I work")
|
(check-= 1.0 1.01 0.01 "I work")
|
||||||
|
]
|
||||||
|
The following check fails:
|
||||||
|
@racketblock[
|
||||||
(check-= 1.0 1.01 0.005 "I fail")
|
(check-= 1.0 1.01 0.005 "I fail")
|
||||||
]
|
]
|
||||||
|
}
|
||||||
|
|
||||||
@defproc*[([(check-true (v any) (message string? "")) void?]
|
@defproc*[([(check-true (v any) (message string? "")) void?]
|
||||||
[(check-false (v any) (message string? "")) void?]
|
[(check-false (v any) (message string? "")) void?]
|
||||||
[(check-not-false (v any) (message string? "")) void?])]{
|
[(check-not-false (v any) (message string? "")) void?])]{
|
||||||
|
|
||||||
Checks that @racket[v] is @racket[#t], @racket[#f], or not
|
Checks that @racket[v] is @racket[#t], is @racket[#f], or is not
|
||||||
@racket[#f] as appropriate. The optional @racket[message]
|
@racket[#f], respectively. The optional @racket[message] is included
|
||||||
is included in the output if the check fails.}
|
in the output if the check fails.
|
||||||
|
|
||||||
For example, the following checks all fail:
|
For example, the following checks all fail:
|
||||||
|
|
||||||
|
@ -82,49 +95,76 @@ For example, the following checks all fail:
|
||||||
(check-false 1)
|
(check-false 1)
|
||||||
(check-not-false #f)
|
(check-not-false #f)
|
||||||
]
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
@defproc[(check-exn (exn-predicate (or/c (-> any boolean?) regexp?))
|
||||||
@defproc[(check-exn (exn-predicate (or/c (-> any boolean?) regexp?)) (thunk (-> any)) (message string? ""))
|
(thunk (-> any)) (message string? ""))
|
||||||
void?]{
|
void?]{
|
||||||
Checks that @racket[thunk] raises an exception and that
|
|
||||||
either @racket[exn-predicate] returns @racket[#t] if it is a function,
|
|
||||||
or that it matches the message in the exception if @racket[exn-predicate]
|
|
||||||
is a regexp. In the latter case, the exception raised must be
|
|
||||||
an @racket[exn:fail?].
|
|
||||||
The optional
|
|
||||||
@racket[message] is included in the output if the check
|
|
||||||
fails. A common error is to use an expression instead of a
|
|
||||||
function of no arguments for @racket[thunk]. Remember that
|
|
||||||
checks are conceptually functions.}
|
|
||||||
|
|
||||||
Here are two examples, one showing a test that succeeds, and one showing
|
Checks that @racket[thunk] raises an exception and that either
|
||||||
a common error:
|
@racket[exn-predicate] returns @racket[#t] if it is a function, or
|
||||||
|
that it matches the message in the exception if @racket[exn-predicate]
|
||||||
|
is a regexp. In the latter case, the exception raised must be an
|
||||||
|
@racket[exn:fail?]. The optional @racket[message] is included in the
|
||||||
|
output if the check fails. A common error is to use an expression
|
||||||
|
instead of a function of no arguments for @racket[thunk]. Remember
|
||||||
|
that checks are conceptually functions.
|
||||||
|
|
||||||
|
For example, the following check succeeds:
|
||||||
|
|
||||||
@racketblock[
|
@racketblock[
|
||||||
(check-exn exn:fail?
|
(check-exn exn:fail?
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(raise (make-exn "Hi there"
|
(raise (make-exn "Hi there"
|
||||||
(current-continuation-marks)))))
|
(current-continuation-marks)))))
|
||||||
|
]
|
||||||
|
|
||||||
|
The following check fails:
|
||||||
|
|
||||||
|
@racketblock[
|
||||||
|
(check-exn exn:fail?
|
||||||
|
(lambda ()
|
||||||
|
(break-thread (current-thread))))
|
||||||
|
]
|
||||||
|
|
||||||
|
The following example is a common mistake. The call to @racket[error]
|
||||||
|
is not within a @racket[lambda], so it bypasses @racket[check-exn]
|
||||||
|
entirely.
|
||||||
|
|
||||||
|
@racketblock[
|
||||||
(code:comment "Forgot to wrap the expression in a thunk. Don't do this!")
|
(code:comment "Forgot to wrap the expression in a thunk. Don't do this!")
|
||||||
(check-exn exn:fail?
|
(check-exn exn:fail?
|
||||||
(error 'hi "there"))
|
(error 'hi "there"))
|
||||||
]
|
]
|
||||||
|
}
|
||||||
|
|
||||||
@defproc[(check-not-exn (thunk (-> any)) (message string? "")) void?]{
|
@defproc[(check-not-exn (thunk (-> any)) (message string? "")) void?]{
|
||||||
|
|
||||||
Checks that @racket[thunk] does not raise any exceptions.
|
Checks that @racket[thunk] does not raise any exceptions.
|
||||||
The optional @racket[message] is included in the output if
|
The optional @racket[message] is included in the output if
|
||||||
the check fails.}
|
the check fails.
|
||||||
|
}
|
||||||
|
|
||||||
@defproc[(check-regexp-match (regexp regexp?) (string string?)) void?]{Checks that @racket[regexp] matches the @racket[string].}
|
@defproc[(check-regexp-match (regexp regexp?)
|
||||||
|
(string string?))
|
||||||
|
void?]{
|
||||||
|
|
||||||
The following check will succeed:
|
Checks that @racket[regexp] matches the @racket[string].
|
||||||
|
|
||||||
@racketblock[(check-regexp-match "a+bba" "aaaaaabba")]
|
|
||||||
|
|
||||||
This check will fail:
|
For example, the following check succeeds:
|
||||||
|
|
||||||
|
@racketblock[
|
||||||
|
(check-regexp-match "a+bba" "aaaaaabba")
|
||||||
|
]
|
||||||
|
|
||||||
|
The following check fails:
|
||||||
|
|
||||||
|
@racketblock[
|
||||||
|
(check-regexp-match "a+bba" "aaaabbba")
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
@racketblock[(check-regexp-match "a+bba" "aaaabbba")]
|
|
||||||
|
|
||||||
@defproc[(check (op (-> any any any))
|
@defproc[(check (op (-> any any any))
|
||||||
(v1 any)
|
(v1 any)
|
||||||
|
@ -132,16 +172,31 @@ This check will fail:
|
||||||
(message string? ""))
|
(message string? ""))
|
||||||
void?]{
|
void?]{
|
||||||
|
|
||||||
The most generic check. Succeeds if @racket[op] applied to @racket[v1] and @racket[v2] is not @racket[#f], otherwise raises an exception of type @racket[exn:test:check]. The optional @racket[message] is included in the output if the check fails.
|
The most generic check. Succeeds if @racket[op] applied to
|
||||||
|
@racket[v1] and @racket[v2] is not @racket[#f], otherwise raises an
|
||||||
|
exception of type @racket[exn:test:check]. The optional
|
||||||
|
@racket[message] is included in the output if the check fails.
|
||||||
|
|
||||||
For example, the following check succeeds:
|
For example, the following check succeeds:
|
||||||
|
|
||||||
@racketblock[
|
@racketblock[
|
||||||
(check < 2 3)
|
(check < 2 3)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
The following check fails:
|
||||||
|
|
||||||
|
@racketblock[
|
||||||
|
(check memq 'pine '(apple orange pear))
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(fail (message string? "")) void?]{This checks fails unconditionally. Good for creating test stubs that you intend to fill out later. The optional @racket[message] is included in the output.}
|
@defproc[(fail (message string? ""))
|
||||||
|
void?]{
|
||||||
|
|
||||||
|
This check fails unconditionally. Good for creating test stubs that
|
||||||
|
you intend to fill out later. The optional @racket[message] is
|
||||||
|
included in the output.
|
||||||
|
}
|
||||||
|
|
||||||
@section{Augmenting Information on Check Failure}
|
@section{Augmenting Information on Check Failure}
|
||||||
|
|
||||||
|
@ -189,8 +244,7 @@ When this check fails the message
|
||||||
|
|
||||||
@verbatim{time: <current-seconds-at-time-of-running-check>}
|
@verbatim{time: <current-seconds-at-time-of-running-check>}
|
||||||
|
|
||||||
will be printed along with the usual information on an
|
is printed along with the usual information on an check failure.
|
||||||
check failure.
|
|
||||||
|
|
||||||
@defform[(with-check-info ((name val) ...) body ...)]{
|
@defform[(with-check-info ((name val) ...) body ...)]{
|
||||||
|
|
||||||
|
@ -214,8 +268,7 @@ When this test fails the message
|
||||||
|
|
||||||
@verbatim{current-element: 8}
|
@verbatim{current-element: 8}
|
||||||
|
|
||||||
will be displayed along with the usual information on an
|
is displayed along with the usual information on an check failure.
|
||||||
check failure.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -235,18 +288,16 @@ that code must be wrapped in a thunk (a function of no
|
||||||
arguments) by the user. The predefined @racket[check-exn]
|
arguments) by the user. The predefined @racket[check-exn]
|
||||||
is an example of this type of check.
|
is an example of this type of check.
|
||||||
|
|
||||||
It is also useful to understand how the check information
|
It is also useful to understand how the check information stack
|
||||||
stack operates. The stack is stored in a parameter and the
|
operates. The stack is stored in a parameter and the
|
||||||
@racket[with-check-info] forms evaluate to calls to
|
@racket[with-check-info] forms evaluate to calls to
|
||||||
@racket[parameterize]. Hence check information has lexical
|
@racket[parameterize]. For this reason simple checks (see below)
|
||||||
scope. For this reason simple checks (see below) cannot
|
cannot usefully contain calls to @racket[with-check-info] to report
|
||||||
usefully contain calls to @racket[with-check-info] to report
|
|
||||||
additional information. All checks created using
|
additional information. All checks created using
|
||||||
@racket[define-simple-check] or @racket[define-check] grab
|
@racket[define-simple-check] or @racket[define-check] grab some
|
||||||
some information by default: the name of the checks and the
|
information by default: the name of the checks and the values of the
|
||||||
values of the parameters. Additionally the macro forms of
|
parameters. Additionally the macro forms of checks grab location
|
||||||
checks grab location information and the expressions passed
|
information and the expressions passed as parameters.
|
||||||
as parameters.
|
|
||||||
|
|
||||||
@defform[(define-simple-check (name param ...) expr ...)]{
|
@defform[(define-simple-check (name param ...) expr ...)]{
|
||||||
|
|
||||||
|
@ -258,9 +309,7 @@ check fails if the result of the @racket[expr]s is
|
||||||
simple checks cannot report extra information using
|
simple checks cannot report extra information using
|
||||||
@racket[with-check-info].}
|
@racket[with-check-info].}
|
||||||
|
|
||||||
Example:
|
For example, the following code defines a check @racket[check-odd?]
|
||||||
|
|
||||||
To define a check @racket[check-odd?]
|
|
||||||
|
|
||||||
@racketblock[
|
@racketblock[
|
||||||
(define-simple-check (check-odd? number)
|
(define-simple-check (check-odd? number)
|
||||||
|
@ -309,7 +358,6 @@ tests a number if within 0.01 of the expected value:
|
||||||
(< (abs (- actual expected)) 0.01))
|
(< (abs (- actual expected)) 0.01))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@defform[(define-check (name param ...) expr ...)]{
|
@defform[(define-check (name param ...) expr ...)]{
|
||||||
|
|
||||||
The @racket[define-check] macro acts in exactly the same way
|
The @racket[define-check] macro acts in exactly the same way
|
||||||
|
@ -318,8 +366,12 @@ if the macro @racket[fail-check] is called in the body of
|
||||||
the check. This allows more flexible checks, and in
|
the check. This allows more flexible checks, and in
|
||||||
particular more flexible reporting options.}
|
particular more flexible reporting options.}
|
||||||
|
|
||||||
@defform[(fail-check)]{The @racket[fail-check] macro raises an @racket[exn:test:check] with
|
@defform[(fail-check)]{
|
||||||
the contents of the check information stack.}
|
|
||||||
|
The @racket[fail-check] macro raises an @racket[exn:test:check] with
|
||||||
|
the contents of the check information stack.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@section{The Check Evaluation Context}
|
@section{The Check Evaluation Context}
|
||||||
|
|
|
@ -48,9 +48,37 @@ so the test can be named.
|
||||||
|
|
||||||
|
|
||||||
@defproc[(test-case? (obj any)) boolean?]{
|
@defproc[(test-case? (obj any)) boolean?]{
|
||||||
True if @racket[obj] is a test case, and false otherwise
|
True if @racket[obj] is a test case, and false otherwise.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@subsection{Shortcuts for Defining Test Cases}
|
||||||
|
|
||||||
|
@defproc*[([(test-check [name string?]
|
||||||
|
[operator (-> any/c any/c any/c)]
|
||||||
|
[v1 any/c]
|
||||||
|
[v2 any/c])
|
||||||
|
void?]
|
||||||
|
[(test-pred [name string?]
|
||||||
|
[pred (-> any/c any/c)]
|
||||||
|
[v any/c])
|
||||||
|
void?]
|
||||||
|
[(test-equal? [name string?] [v1 any/c] [v2 any/c]) (void?)]
|
||||||
|
[(test-eq? [name string?] [v1 any/c] [v2 any/c]) void?]
|
||||||
|
[(test-eqv? [name string?] [v1 any/c] [v2 any/c]) void?]
|
||||||
|
[(test-= [name string?] [v1 real?] [v2 real?] [epsilon real?]) void?]
|
||||||
|
[(test-true [name string?] [v any/c]) void?]
|
||||||
|
[(test-false [name string?] [v any/c]) void?]
|
||||||
|
[(test-not-false [name string?] [v any/c]) void?]
|
||||||
|
[(test-exn [name string?] [pred (-> exn? any/c)] [thunk (-> any)]) void?]
|
||||||
|
[(test-not-exn [name string?] [thunk (-> any)]) void?])]{
|
||||||
|
|
||||||
|
Creates a test case with the given @racket[name] that performs the
|
||||||
|
corresponding check. For example,
|
||||||
|
|
||||||
|
@racketblock[(test-equal? "Fruit test" "apple" "pear")]
|
||||||
|
is equivalent to
|
||||||
|
@racketblock[(test-case "Fruit test" (check-equal? "apple" "pear"))]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@section{Test Suites}
|
@section{Test Suites}
|
||||||
|
|
|
@ -3,13 +3,17 @@
|
||||||
|
|
||||||
@title{Overview of RackUnit}
|
@title{Overview of RackUnit}
|
||||||
|
|
||||||
There are three basic data types in RackUnit:
|
There are three basic concepts in RackUnit:
|
||||||
|
|
||||||
@itemize[
|
@itemize[
|
||||||
|
|
||||||
@item{A @italic{check} is the basic unit of a test. As the name suggests, it checks some condition is true.}
|
@item{A @italic{check} is the basic unit of a test. As the name
|
||||||
|
suggests, it checks some condition is true.}
|
||||||
|
|
||||||
@item{A @italic{test case} is a group of checks that form one conceptual unit. If any check within the case fails, the entire case fails.}
|
@item{A @italic{test case} is a group of checks that form one
|
||||||
|
conceptual unit. If any check within the case fails, the entire case
|
||||||
|
fails.}
|
||||||
|
|
||||||
@item{A @italic{test suite} is a group of test cases and test suites that has a name.}
|
@item{A @italic{test suite} is a group of test cases and test suites
|
||||||
|
that has a name.}
|
||||||
]
|
]
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
@title{@bold{RackUnit}: Unit Testing for Racket}
|
@title{@bold{RackUnit}: Unit Testing for Racket}
|
||||||
|
|
||||||
@author[(author+email "Noel Welsh" "noelwelsh@gmail.com")
|
@author[(author+email "Noel Welsh" "noelwelsh@gmail.com")
|
||||||
(author+email "Ryan Culpepper" "ryan_sml@yahoo.com")]
|
(author+email "Ryan Culpepper" "ryanc@racket-lang.org")]
|
||||||
|
|
||||||
RackUnit is a unit-testing framework for Racket. It
|
RackUnit is a unit-testing framework for Racket. It
|
||||||
is designed to handle the needs of all Racket programmers,
|
is designed to handle the needs of all Racket programmers,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user