]> gitweb.factorcode.org Git - factor.git/blob - basis/tools/test/test-docs.factor
tools.test: Fix documentation
[factor.git] / basis / tools / test / test-docs.factor
1 USING: help.markup help.syntax kernel quotations io ;
2 IN: tools.test
3
4 ARTICLE: "tools.test" "Unit testing"
5 "A unit test is a piece of code which starts with known input values, then compares the output of a word with an expected output, where the expected output is defined by the word's contract."
6 $nl
7 "For example, if you were developing a word for computing symbolic derivatives, your unit tests would apply the word to certain input functions, comparing the results against the correct values. While the passing of these tests would not guarantee the algorithm is correct, it would at least ensure that what used to work keeps working, in that as soon as something breaks due to a change in another part of your program, failing tests will let you know."
8 $nl
9 "Unit tests for a vocabulary are placed in test files in the same directory as the vocabulary source file (see " { $link "vocabs.loader" } "). Two possibilities are supported:"
10 { $list
11     { "Tests can be placed in a file named " { $snippet { $emphasis "vocab" } "-tests.factor" } "." }
12     { "Tests can be placed in files in the " { $snippet "tests" } " subdirectory." }
13 }
14 "The latter is used for vocabularies with more extensive test suites."
15 $nl
16 "If the test harness needs to define words, they should be placed in a vocabulary named " { $snippet { $emphasis "vocab" } ".tests" } " where " { $emphasis "vocab" } " is the vocab being tested."
17 { $heading "Writing unit tests" }
18 "Several words exist for writing different kinds of unit tests. The most general one asserts that a quotation outputs a specific set of values:"
19 { $subsections POSTPONE: unit-test }
20 "Assert that a quotation throws an error:"
21 { $subsections
22     POSTPONE: must-fail
23     POSTPONE: must-fail-with
24 }
25 "Assert that a quotation or word has a specific static stack effect (see " { $link "inference" } "):"
26 { $subsections
27     POSTPONE: must-infer
28     POSTPONE: must-infer-as
29 }
30 "All of the above are used like ordinary words but are actually parsing words. This ensures that parse-time state, namely the line number, can be associated with the test in question, and reported in test failures."
31 $nl
32 "Some words help the test writer using temporary files:"
33 { $subsections
34   with-test-directory
35   with-test-file
36 }
37 { $heading "Running unit tests" }
38 "The following words run test harness files; any test failures are collected and printed at the end:"
39 { $subsections
40     test
41     test-all
42 }
43 "The following word prints failures:"
44 { $subsections :test-failures }
45 "Test failures are reported using the " { $link "tools.errors" } " mechanism and are shown in the " { $link "ui.tools.error-list" } "."
46 $nl
47 "Unit test failures are instances of a class, and are stored in a global variable:"
48 { $subsections
49     test-failure
50     test-failures
51 } ;
52
53
54
55 HELP: must-fail
56 { $syntax "[ quot ] must-fail" }
57 { $values { "quot" "a quotation run with an empty stack" } }
58 { $description "Runs a quotation with an empty stack, expecting it to throw an error. If the quotation throws an error, this word returns normally. If the quotation does not throw an error, this word " { $emphasis "does" } " raise an error." }
59 { $notes "This word is used to test boundary conditions and fail-fast behavior." } ;
60
61 HELP: must-fail-with
62 { $syntax "[ quot ] [ pred ] must-fail-with" }
63 { $values { "quot" "a quotation run with an empty stack" } { "pred" { $quotation ( error -- ? ) } } }
64 { $description "Runs a quotation with an empty stack, expecting it to throw an error which must satisfy " { $snippet "pred" } ". If the quotation does not throw an error, or if the error does not match the predicate, the unit test fails." }
65 { $notes "This word is used to test error handling code, ensuring that errors thrown by code contain the relevant debugging information." } ;
66
67 HELP: must-infer
68 { $syntax "[ quot ] must-infer" }
69 { $values { "quot" quotation } }
70 { $description "Ensures that the quotation has a static stack effect without running it." }
71 { $notes "This word is used to test that code will compile with the optimizing compiler for optimum performance. See " { $link "compiler" } "." } ;
72
73 HELP: must-infer-as
74 { $syntax "{ effect } [ quot ] must-infer-as" }
75 { $values { "effect" "a pair with shape " { $snippet "{ inputs outputs }" } } { "quot" quotation } }
76 { $description "Ensures that the quotation has the indicated stack effect without running it." }
77 { $notes "This word is used to test that code will compile with the optimizing compiler for optimum performance. See " { $link "compiler" } "." } ;
78
79 HELP: test
80 { $values { "prefix" "a vocabulary name" } }
81 { $description "Runs unit tests for the vocabulary named " { $snippet "prefix" } " and all of its child vocabularies." } ;
82
83 HELP: test-all
84 { $description "Runs unit tests for all loaded vocabularies." } ;
85
86 HELP: :test-failures
87 { $description "Prints all pending unit test failures." } ;
88
89 HELP: unit-test
90 { $syntax "{ output } [ input ] unit-test" }
91 { $values { "output" "a sequence of expected stack elements" } { "input" "a quotation run with an empty stack" } }
92 { $description "Runs a quotation with an empty stack, comparing the resulting stack with " { $snippet "output" } ". Elements are compared using " { $link = } ". Throws an error if the expected stack does not match the resulting stack." } ;
93
94 HELP: with-test-file
95 { $values { "quot" quotation } }
96 { $description "Creates an empty temporary file and applies the quotation to it. The file is deleted after the word returns." } ;
97
98 ABOUT: "tools.test"