Unit Testing
ISL Unit Testing
The ISL unit testing framework lets you write and run tests entirely in ISL. Tests live alongside your transformation code, use the same syntax, and can verify behavior without learning a separate testing language.
Quick Start
- Create an
.islfile with@test-annotated functions:
@test
fun test_simpleAssertion() {
$value: 42;
@.Assert.equal(42, $value);
}
- Run tests from the command line:
isl test
# or specify a path
isl test tests/
isl test tests/sample.isl
isl test tests/calculator.tests.yaml # YAML-driven suite
- Or run tests programmatically from Kotlin/Java (see Test Setup).
Two Ways to Define Tests
- Annotation-based – In
.islfiles with@setupand@test(see Test Annotations). - YAML-driven – In
*.tests.yamlfiles: specifysetup.islSource, optional mocks, and a list of tests withfunctionName,input, andexpected. No ISL test code required. See YAML-Driven Test Suites for the full format, includingassertOptionsandmockSource/mocks.
What You Can Test
- Transformations – Call your ISL functions and assert on the output
- Conditions – Verify branching logic, edge cases
- Modifiers – Test
| trim,| map,| filter, etc. - External integrations – Use mocking to replace
@.Call.Apiand similar
File Format and Structure
Tests are written in standard .isl files. A test file typically contains:
- One optional
@setupfunction (runs before each test) - One or more
@testfunctions (each is a test case)
@setup
fun setup() {
$x: 1; // Shared setup runs before each test
}
@test
fun test_basic() {
@.Assert.equal(1, 1);
}
@test("Custom display name")
fun test_withName() {
@.Assert.equal(2, 2);
}
@test({ name: "Grouped test", group: "math" })
fun test_grouped() {
@.Assert.equal(3, 3);
}
File discovery:
- CLI:
isl testfinds all.islfiles (by default**/*.isl) containing@setupor@test - API: You pass the list of files to
TransformTestPackageBuilder
Attributes (Annotations)
| Attribute | Description |
|---|---|
@test |
Marks a function as a test. Runs as a test case. |
@test("Name") |
Same, with a custom display name |
@test(name, group) |
Custom name and group for organization |
@test({ name: "x", group: "y" }) |
Object form for name and group |
@setup |
Marks a function to run before each test in the file (at most one per file) |
See Test Annotations for details.
Assertions
Use @.Assert to verify values:
| Assertion | Description |
|---|---|
@.Assert.equal(expected, actual, message?) |
Deep equality (objects, arrays, primitives) |
@.Assert.notEqual(expected, actual, message?) |
Values must differ |
@.Assert.notNull(value, message?) |
Value must not be null |
@.Assert.isNull(value, message?) |
Value must be null |
@.Assert.contains(expected, actual) |
actual contains expected |
@.Assert.matches(pattern, value) |
value matches regex |
@.Assert.startsWith(prefix, value) |
value starts with prefix |
| … | See Assertions for the full list |
Loading Test Fixtures
Use @.Load.From(fileName) to load JSON, YAML, or CSV files relative to the current ISL file:
@test
fun test_withFixture() {
$data = @.Load.From("fixtures/input.json")
@.Assert.equal("expected", $data.name)
$config = @.Load.From("config.yaml")
@.Assert.equal(10, $config.count)
$rows = @.Load.From("fixtures/data.csv")
@.Assert.equal(2, $rows | length)
}
Supported formats: .json, .yaml, .yml, .csv (all converted to JSON). See Loading Fixtures.
How to Run Tests
Command Line (Recommended)
isl test [path] [options]
path: Directory, single file (e.g.sample.islorsuite.tests.yaml), or default: current directory--glob PATTERN: Filter .isl files when path is a directory (YAML suites use**/*.tests.yamlwhen not set)-f, --function NAME: Run only tests whose function name matches; usefile:functionfor a specific file (e.g.sample.isl:test_customerorcalculator.tests.yaml:add)-o, --output FILE: Write results to JSON
Programmatic (Kotlin/Java)
See Test Setup for adding the isl-test dependency and running tests from code.
Mocking
Mock external functions (e.g. @.Call.Api) so tests don’t hit real services:
@test
fun test_withMock() {
@.Mock.Func("Call.Api", { status: 200, body: "ok" })
$result = @.Call.Api("https://example.com")
@.Assert.equal(200, $result.status)
}
See Mocking for parameter matching, indexed (sequential) returns, loading mocks from files, captures, and annotation mocks.
Test Output
- CLI: Prints pass/fail per test, with failure messages and locations
- JSON: Use
-o results.jsonfor machine-readable output - Exit code: 1 if any test failed, 0 if all passed
Next Steps
- Test Setup – CLI usage, dependencies, programmatic API
- YAML-Driven Test Suites –
*.tests.yamlformat, assertOptions, mocks - Test Annotations –
@testand@setupin detail - Assertions – Full assertion reference
- Loading Fixtures –
@.Load.Fromfor JSON/YAML/CSV - Mocking – Mock functions and annotations