Testing
Sigil provides a built-in test framework through (sigil test) and a CLI command for discovering and running tests with helpful output.
Quick Start
Create a test file in your package's test/ directory:
;; test/test-math.sgl
(import (sigil test))
(test-group "arithmetic"
(test "addition works"
(assert-equal 4 (+ 2 2)))
(test "multiplication works"
(assert-equal 6 (* 2 3))))Run tests:
sigil testWriting Tests
Test Structure
Tests are organized with test-group and test:
(import (sigil test))
(test-group "Reader"
(test "reads integers"
(assert-equal 42 (read-from-string "42")))
(test "reads symbols"
(assert-equal 'foo (read-from-string "foo"))))
(test-group "Compiler"
(test "compiles lambda"
(assert-true (procedure? (eval '(lambda (x) x))))))Assertions
The (sigil test) module provides several assertion functions:
| Function | Purpose |
|---|---|
(assert-equal expected actual) | Check values are equal |
(assert-true expr) | Check expression is truthy |
(assert-false expr) | Check expression is #f |
(assert-error thunk) | Check that thunk raises an error |
Examples:
(test "equality checks"
(assert-equal '(1 2 3) (list 1 2 3))
(assert-equal "hello" (string-append "hel" "lo")))
(test "boolean checks"
(assert-true (pair? '(a . b)))
(assert-false (null? '(1 2 3))))
(test "error checking"
(assert-error (lambda () (car 5))))Test Discovery
Default Behavior
With no arguments, sigil test discovers tests by:
- Looking for
test/directory in the project root - Finding all
*.sglfiles matching patterns:
test-*.sgl*-test.sgl- Files directly in
test/directory
Running Specific Tests
sigil test test/test-compiler.sgl # Single file
sigil test test/compiler/ # Directory
sigil test test-*.sgl # Glob pattern
sigil test test/test-reader.sgl test/test-vm.sgl # Multiple filesCommand Line Options
sigil test [options] [file-or-pattern...] Options: --native Run only native (C) tests --sgl Run only Sigil tests -f, --filter PAT Run only tests matching pattern -c, --compact Compact output (dots instead of names) -q, --quiet Minimal output (exit code only) --no-color Disable colored output --fail-fast Stop on first failure -h, --help Show help
Output Formats
Default (Verbose)
Shows all test names with results:
Running tests...
Reader
✓ reads integers (2ms)
✓ reads symbols (1ms)
✗ reads floats
Expected: 3.14
Actual: 3.14000000001
at test/test-reader.sgl:42
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Tests: 156 passed, 1 failed (157 total)
Time: 1.23s
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━Compact Mode (-c)
For faster scanning with many tests:
Reader ✓✓✓✓✓✓✓✓ (8/8)
Compiler ✓✓✓✓✓✗✓✓✓✓ (9/10)
✗ handles edge case
Expected: #t
Actual: #f
VM ✓✓✓✓✓✓✓✓✓✓✓✓ (12/12)
✓ 29 passed, 1 failedQuiet Mode (-q)
No output except errors. Exit code indicates pass/fail:
0— All tests passed1— One or more tests failed2— Test execution error
Filtering Tests
Run specific tests by pattern:
sigil test -f "reader" # Tests with "reader" in name
sigil test -f "Reader > int" # More specific
sigil test -f "compile*" # Glob patternTest File Locations
Tests are organized per-package:
packages/
├── sigil-stdlib/
│ └── test/
│ ├── test-core.sgl
│ ├── test-string.sgl
│ └── test-hygiene.sgl
├── sigil-json/
│ └── test/
│ └── test-json.sgl
└── sigil-http/
└── test/
└── test-http.sglNative Tests
For packages with C code, native tests use the test framework in packages/sigil-lib/test/test.h:
#include "test.h"
TEST(reader_integers) {
Value v = sigil_read_string(vm, "42");
ASSERT(sigil_is_fixnum(v));
ASSERT_EQ(sigil_fixnum_value(v), 42);
}
TEST(reader_symbols) {
Value v = sigil_read_string(vm, "foo");
ASSERT(sigil_is_symbol(v));
}
int main(void) {
RUN_TEST(reader_integers);
RUN_TEST(reader_symbols);
return test_summary();
}Run native tests only:
sigil test --nativeBest Practices
- Test file naming: Use
test-<feature>.sglfor clarity - Group related tests: Use
test-groupto organize - Descriptive names: Test names should describe expected behavior
- One assertion per test: When possible, keep tests focused
- Test edge cases: Include boundary conditions and error cases
Integration with CI
Add to your CI pipeline:
sigil test --quietThe exit code indicates success (0) or failure (non-zero).