Tests
Module tests
import tests
| Module | tests |
| Source | tests/module-docs.zirr, tests/types.zirr |
What a test is, before anything runs it.
A test is a function carrying Test that returns a prelude.Result. Nothing else is required: there is no registry and no base type, so the runner reaches for reflect and finds tests by reading a module rather than by being told about them.
The other attributes adjust what happens to one. Skip keeps it out of the run, Todo marks it as expected to be unfinished, Only narrows the run to itself, and Comment attaches a note that reporters print.
This module is only the vocabulary. tests.assert writes the assertions, tests.runner finds and runs them, and tests.tap reports what happened.
Where tests live
zirric test runs every module of the project whose name ends in _t. Both shapes count: a foo/_t/foo_t.zirr submodule beside the code it tests, and a sibling module named foo_t. Nothing has to be registered — the name is the whole convention, and a project has a working zirric test before it has written anything about testing. A Cavefile that declares a test task takes over from the built-in entirely.
mod example.strings._t
import tests { Test, Skip, Comment }
import tests.assert
import strings
@Test()
fn testJoinsWithSeparator() {
assert.equal("a,b", strings.join(["a", "b"], ","))
}
@Test()
fn testReportsEveryFailedCheck() {
assert.all([
assert.equal(0, len("")),
assert.isTrue(strings.hasPrefix("abc", "a")),
])
}
@Skip()
@Comment("waiting on the parser")
fn testNotYet() {
assert.fail("unreachable")
}
A test takes no arguments and returns a prelude.Result — which the assertions above already are, so returning one is the whole body. zirric test exits non-zero when any of them is an Err.
Contents
- Unions —
TestCaseDetails,TestEvent - Data —
Completed,Discovered,FailureRecord,Finished,Skipped,Started,TestCase,TestCaseDetailsOnly,TestCaseDetailsSkip,TestCaseDetailsTodo,TestReport - Attributes —
Comment,Only,Skip,Test,Todo
Unions
TestCaseDetails
`tests/types.zirr:47`
union TestCaseDetails {
None
TestCaseDetailsSkip
TestCaseDetailsTodo
TestCaseDetailsOnly
}
What Skip, Todo or Only was written on a test, or None when none of them was.
Each member says how to be read as an Option, the way prelude’s own Result members do: a union’s attributes are not read off a value of one of its members.
Cases
| Case | Interpretation |
|---|---|
None |
The absent value. |
TestCaseDetailsSkip |
The test carries Skip. |
TestCaseDetailsTodo |
The test carries Todo. |
TestCaseDetailsOnly |
The test carries Only. |
TestEvent
`tests/types.zirr:63`
union TestEvent {
Discovered
Skipped
Started
Finished
Completed
}
What a run emits as it proceeds, in the order a reporter sees it.
Cases
| Case | Interpretation |
|---|---|
Discovered |
Emitted once, before anything runs, with every case the run will cover. |
Skipped |
A case that will not run. |
Started |
A case that is about to run. |
Finished |
A case that has run, with what it returned. |
Completed |
Emitted once, after everything has run. |
Data
Completed
`tests/types.zirr:87`
data Completed {
report: TestReport
}
Emitted once, after everything has run.
Fields
| Field | Description |
|---|---|
report |
What the run amounted to. |
Discovered
`tests/types.zirr:65`
data Discovered {
cases: [TestCase]
}
Emitted once, before anything runs, with every case the run will cover.
Fields
| Field | Description |
|---|---|
cases |
Every case the run will cover, skipped ones included. |
FailureRecord
`tests/types.zirr:106`
data FailureRecord {
test: TestCase
error: Err
}
A failed case together with the error it returned.
Fields
| Field | Description |
|---|---|
test |
The case that failed. |
error |
The Err it returned, whose reason says what went wrong. |
Finished
`tests/types.zirr:80`
data Finished {
test: TestCase
outcome: Result
}
A case that has run, with what it returned.
Fields
| Field | Description |
|---|---|
test |
The case that ran. |
outcome |
What it returned: an Ok, or an Err whose reason says what went wrong. |
Skipped
`tests/types.zirr:70`
data Skipped {
test: TestCase
}
A case that will not run.
Fields
| Field | Description |
|---|---|
test |
The case being skipped. |
Started
`tests/types.zirr:75`
data Started {
test: TestCase
}
A case that is about to run.
Fields
| Field | Description |
|---|---|
test |
The case about to run. |
TestCase
`tests/types.zirr:23`
data TestCase {
name: String
impl: fn() -> Result
skipped: Bool
comment: String
details: TestCaseDetails
}
One test, as the runner will execute it.
Fields
| Field | Description |
|---|---|
name |
The fully qualified name, which is the module’s name and the function’s joined with a dot. |
impl |
The test function itself. |
skipped |
Whether the runner will report it without running it. |
comment |
The Comment written on it, or the empty String when none was. |
details |
What Skip, Todo or Only was written on it, if any. |
TestCaseDetailsOnly
`tests/types.zirr:59`
data TestCaseDetailsOnly
The test carries Only.
TestCaseDetailsSkip
`tests/types.zirr:53`
data TestCaseDetailsSkip
The test carries Skip.
TestCaseDetailsTodo
`tests/types.zirr:56`
data TestCaseDetailsTodo
The test carries Todo.
TestReport
`tests/types.zirr:94`
data TestReport {
pass: [TestCase]
fail: [FailureRecord]
skip: [TestCase]
todo: [TestCase]
}
What a run amounted to. A case appears in exactly one of the four.
Fields
| Field | Description |
|---|---|
pass |
The cases that returned an Ok. |
fail |
The cases that returned an Err, with the error each returned. |
skip |
The cases that carried Skip and so were not run. |
todo |
The cases that carried Todo, whatever they returned. |
Attributes
Comment
`tests/types.zirr:17`
attr Comment {
text: String
}
Attaches a note to a test that reporters print alongside it.
Fields
| Field | Description |
|---|---|
text |
The note to print. |
Only
`tests/types.zirr:11`
attr Only
Narrows the run to the tests carrying it. With no such test, every test runs.
Skip
`tests/types.zirr:8`
attr Skip
Keeps a test out of the run. It is reported as skipped rather than omitted.
Test
`tests/types.zirr:5`
attr Test
Marks a function as a test. The function takes no arguments and returns a Result.
This is the whole of what makes a test: the runner finds functions carrying it by reading a module through reflect.
Todo
`tests/types.zirr:14`
attr Todo
Marks a test as expected to be unfinished. It runs, and its outcome is reported as a todo either way.