AtlatestRepositorysigil-web-styles
1# Testing
2
3> Test framework with groups, assertions, and structured results.
4
5```scheme
6(import (sigil test))
7```
8
9## Defining Tests
11Use `test` to define a test case and `test-group` to organize related tests.
13```scheme
14(test "addition works"
15 (assert-equal 4 (+ 2 2)))
17(test-group "String operations"
18 (test "concatenation"
19 (assert-equal "hello world" (string-append "hello" " " "world")))
20 (test "length"
21 (assert-equal 5 (string-length "hello"))))
23;; Groups can be nested
24(test-group "Collections"
25 (test-group "Lists"
26 (test "map doubles"
27 (assert-equal '(2 4 6) (map (lambda (x) (* x 2)) '(1 2 3))))))
28```
30## Skipping and Pending Tests
32```scheme
33;; Skip a test (temporarily disabled, body not executed)
34(test-skip "broken feature"
35 (assert-equal 42 (broken-function)))
37;; Pending test (placeholder for future work, body not executed)
38(test-pending "not yet implemented"
39 (assert-true (new-feature-works)))
40```
42Both are counted separately in the test summary.
44## Assertions
46### Value Equality
48```scheme
49(assert-equal expected actual) ; deep equality (equal?)
50(assert-eqv expected actual) ; value equivalence (eqv?)
51(assert-eq expected actual) ; object identity (eq?)
52```
54```scheme
55(assert-equal '(1 2 3) (iota 3 1)) ; pass — deep list comparison
56(assert-eqv 3.14 3.14) ; pass — numeric equivalence
57(assert-eq 'foo 'foo) ; pass — symbols are interned
58```
60### Boolean
62```scheme
63(assert-true val) ; passes if val is not #f
64(assert-false val) ; passes if val is #f
65```
67```scheme
68(assert-true (> 5 3))
69(assert-false (member 'x '(a b c)))
70```
72### Null Checks
74```scheme
75(assert-null val) ; passes if val is '()
76(assert-not-null val) ; passes if val is not '()
77```
79```scheme
80(assert-null (cdr '(1)))
81(assert-not-null (filter odd? '(1 2 3)))
82```
84### Error Checking
86```scheme
87(assert-error expr) ; passes if expr raises an error
88```
90```scheme
91(assert-error (car '()))
92(assert-error (error "expected failure"))
93```
95### Unconditional Failure
97```scheme
98(assert-fail message) ; always fails with message
99```
101```scheme
102(test "should not reach else branch"
103 (if (valid? input)
104 (assert-true (process input))
105 (assert-fail "input was invalid")))
106```
108## Running Tests
110Every test file should end with `(run-tests)`.
112```scheme
113(import (sigil test))
115(test "example" (assert-true #t))
116(run-tests)
117```
119The CLI runs all test files in the workspace:
121```
122sigil test # Run all tests (native + Sigil)
123sigil test --sgl # Run only Sigil tests
124sigil test --native # Run only native (C) tests
125```
127## Test Results
129`run-tests` produces a `test-summary` with aggregate results.
131- `test-summary-total` — total tests run
132- `test-summary-passed` — tests that passed
133- `test-summary-failed` — tests that failed
134- `test-summary-skipped` — tests skipped or pending
135- `test-summary-duration-ms` — total time in milliseconds
136- `test-summary-results` — list of `test-result` records
138Each `test-result` has:
140- `test-result-name` — test name string
141- `test-result-group` — group path or `#f`
142- `test-result-passed?` — boolean
143- `test-result-message` — failure message or `#f`
144- `test-result-expected` / `test-result-actual` — values on failure
146## Common Patterns
148### Testing a Module
150```scheme
151(import (sigil test)
152 (sigil json))
154(test-group "json-encode"
155 (test "encodes string"
156 (assert-equal "\"hello\"" (json-encode "hello")))
157 (test "encodes number"
158 (assert-equal "42" (json-encode 42)))
159 (test "encodes dict"
160 (let ((result (json-decode (json-encode #{ a: 1 }))))
161 (assert-equal 1 (dict-ref result a:)))))
163(run-tests)
164```
166### Testing Error Conditions
168```scheme
169(test-group "input validation"
170 (test "rejects empty input"
171 (assert-error (parse-config "")))
172 (test "rejects missing required field"
173 (assert-error (parse-config "{}"))))
174```
176### Test File Structure
178```
179packages/my-package/
180 test/
181 test-core.sgl # Core functionality tests
182 test-parsing.sgl # Parser tests
183 test-output.sgl # Output formatting tests
184```
186Each file is self-contained with its own imports and `(run-tests)` call.