Zulip Chat Archive
Stream: general
Topic: Framework for testing at runtime
Oliver Dressler (Aug 19 2025 at 09:51):
I have been enjoying runtime Lean but miss a more streamlined testing experience.
Users of runtime Lean, what have you been using for testing?
After some planning, I want to implement the following API to fit my needs.
Would this also fit your projects? Any oversights, name collisions, or additions?
Test Definition
import LeanTest
-- BASIC TESTING
#test_eq "named test": a b "custom error message"
#test_eq a b
#test_ne a b
#test_true condition
#test_false condition
-- GROUPING
#test_group "name" do
-- tests
-- PROPERTY TESTING
#test_forall (cases? := n) (seed? := m) (generator? := custom_gen) (x : T) => property
#test_forall (generators? := [custom_gen, custom_gen2]) (x : T) (y : U) ... => property
-- EQUALITY ASSERTIONS
#test_eq a b
#test_ne a b
#test_beq a b
#test_bne a b
#test_equiv a b
#test_not_equiv a b
-- ORDERING ASSERTIONS
#test_lt a b
#test_le a b
#test_gt a b
#test_ge a b
-- MEMBERSHIP ASSERTIONS
#test_member x xs
#test_not_member x xs
#test_subset xs ys
#test_not_subset xs ys
#test_divides a b
#test_not_divides a b
-- RELATIONAL ASSERTIONS
#test_rel R a b
#test_not_rel R a b
#test_pred P x
#test_not_pred P x
-- COLLECTION ASSERTIONS
#test_empty collection
#test_not_empty collection
#test_size collection n
-- NUMERIC ASSERTIONS
#test_approx a b ε
-- OPTION ASSERTIONS
#test_some opt
#test_none opt
#test_some_eq opt expected
#test_some_ne opt forbidden
#test_some_lt opt bound
#test_some_le opt bound
#test_some_gt opt bound
#test_some_ge opt bound
#test_some_pred opt predicate
#test_some_not_pred opt predicate
-- EXCEPT ASSERTIONS
#test_ok result
#test_error result
#test_ok_eq result expected
#test_ok_ne result forbidden
#test_ok_lt result bound
#test_ok_le result bound
#test_ok_gt result bound
#test_ok_ge result bound
#test_ok_pred result predicate
#test_ok_not_pred result predicate
#test_error_eq result expected_error
#test_error_ne result forbidden_error
#test_error_pred result error_predicate
-- EXCEPTION TESTING
#test_throws expr
#test_not_throws expr
#test_panic expr
-- PERFORMANCE TESTING
#test_time (runs? := n) (timeout? := ms) expr
-- CONFIGURATION
#test_config do
cases := n
?? parallel := bool
seed := n
Setup and Execution
[[require]]
name = "LeanTest"
git = "https://github.com/.../LeanTest"
rev = "main"
testDriver = "LeanTest/driver"
lake test
lake test File.lean
lake test --watch
?? lake test --junit-xml=report.xml
Example Output
MathTests.lean [3 tests, 1 failed]
------------------------------
✗ simple_addition (MathTests.lean:12)
expected: 5
actual: 4
AlgebraTests.lean [3 tests, 1 failed]
------------------------------
quadratic_formula [1 test, 1 failed]
✗ solve_quadratic (AlgebraTests.lean:27)
property failed for inputs: x = 0, -1, 2
smallest failing case: x = 0
seed: 42
generator: small_ints
LogicTests.lean [2 tests, 1 failed]
------------------------------
✗ boolean_logic_test (LogicTests.lean:18)
expected: true
actual: false
PerformanceTests.lean [2 tests, 1 failed]
------------------------------
✗ fast_function (PerformanceTests.lean:40)
test_time exceeded timeout
measured time: 0.08s (timeout: 0.05s)
time_measurement_example (PerformanceTests.lean:45)
measured time per call: 0.03s
UtilityTests.lean [2 tests, 0 failed]
------------------------------
10 tests, 3 failed (0.56s)
Arthur Paulino (Aug 19 2025 at 10:23):
We (argumentcomputer) use LSpec
Oliver Dressler (Aug 19 2025 at 10:32):
Arthur Paulino said:
We (
argumentcomputer) use LSpec
Thanks, somehow I missed this on my (admittedly short) search. LSpec does a lot of what I was missing.
I'm looking through your yatima tests to see it in action now.
Arthur Paulino (Aug 19 2025 at 10:37):
yatima is no longer maintained and uses an old version of LSpec.
ix serves as a better example
Last updated: Dec 20 2025 at 21:32 UTC