Writing tests
The @test decorator
Mark any function as a test with the @test decorator:
tryke also discovers functions with the test_ prefix, so existing pytest-style tests work without changes:
Custom test names
Pass name= to give a test a human-readable label:
This is especially useful when generating tests in a loop:
for x, expected in [(1, 2), (2, 3), (3, 4)]:
@test(name=f"increment {x}")
def _(x=x, expected=expected):
expect(x + 1).to_equal(expected)
Tags
Tag tests for filtering with -m:
Assertions with expect()
Every assertion starts with expect() and chains a matcher:
from tryke import expect, test
@test
def assertions():
expect(1 + 1).to_equal(2)
expect(None).to_be_none()
expect("hello").to_be_truthy()
expect([1, 2, 3]).to_contain(2)
expect([1, 2, 3]).to_have_length(3)
Available matchers:
| Matcher | Checks |
|---|---|
to_equal(y) |
x == y |
to_be(y) |
x is y |
to_be_truthy() |
bool(x) is True |
to_be_falsy() |
bool(x) is False |
to_be_none() |
x is None |
to_be_greater_than(y) |
x > y |
to_be_less_than(y) |
x < y |
to_be_greater_than_or_equal(y) |
x >= y |
to_be_less_than_or_equal(y) |
x <= y |
to_contain(item) |
item in x |
to_have_length(n) |
len(x) == n |
to_match(pattern) |
Regex match on str(x) |
to_raise(exc, match=) |
Callable raises exception |
Negation
Use .not_ to negate any matcher:
Exception testing
Pass a callable to expect() and use to_raise():
@test
def raises_on_invalid_input():
expect(lambda: int("abc")).to_raise(ValueError, match="invalid")
to_raise() accepts an optional exception type and an optional match= regex pattern.
Fatal assertions
Assertions are soft by default — all assertions in a test run even if earlier ones fail. Chain .fatal() to stop on failure:
@test
def check_response():
expect(response.status).to_equal(200).fatal()
expect(response.body).to_contain("ok")
Grouping tests with describe()
Use describe() to group related tests under a label:
from tryke import describe, expect, test
with describe("math"):
@test
def addition():
expect(1 + 1).to_equal(2)
@test
def subtraction():
expect(3 - 1).to_equal(2)
The group name appears as a prefix in test output.
Skipping tests
Skip a test unconditionally:
Skip conditionally at import time:
Todo tests
Mark a test as planned but not yet implemented. Todo tests are collected but never executed:
Expected failures
Mark a test that is known to fail:
If the test passes unexpectedly, tryke reports it so you know the issue may be resolved.