3 ms·
> add assertions to your code. Yes, and many programming languages have assertions such as "assert greater than or equal to". For example with Rust and the As
by jph 2y ago
> add assertions to your code.
Yes, and many programming languages have assertions such as "assert greater than or equal to".
For example with Rust and the Assertables crate:
fn calculate_something() -> f64 {
let big = get_big_number();
let small = get_small_number();
assert_ge!(big, small); // >= or panic with message
(big - small).sqrt
}
It turns out it's even better if your code has good error handling, such as a runtime assert macro that can return a result that is NaN (not a number) or a "maybe" result that is either Ok or Err.
For example with Rust and the Assertables crate:
fn calculate_something() -> Result(f64, String) {
let big = get_big_number()
let small = get_small_number()
assert_ge!(big, small)?; // >= or return Err(message)
(big - small).sqrt
}
- aftbit 2y agoIs there a reason you need specialized assertions over something like Python's generic assert? >>> big = 2; small = 3 >>> assert big >= small, "big is smaller than small" Traceback (most recent call last): File "<stdin>", line 1, in <module> AssertionError: big is smaller than small In pytest, assertions are rewritten[1] to return something more useful like: def test(): big = 2 small = 3 > assert big > small E assert 2 > 3 test/test_dumb.py:4: AssertionError ========== short test summary info ========== FAILED test/test_dumb.py::test - assert 2 > 3 1: https://github.com/pytest-dev/pytest/blob/f373974707f57a0b28d12563e4d03c7cd54c70d9/src/_pytest/assertion/rewrite.py#L610 https://github.com/pytest-dev/pytest/blob/f373974707f57a0b28...
- Arnavion 2y agoRust has a generic assert too `assert!(foo >= bar);`. I assume (haven't used the crate myself) the advantage of `assertable::assert_ge!(foo, bar)` is that it prints the values of foo and bar in the assert message. The `assert_eq!(foo, bar)` and `assert_ne!(foo, bar)` macros provided by Rust libstd also do this. But the generic `assert!()` just sees the boolean result of its expression and only prints that in its message. The values of the variables can be included in the generic macro's message via a custom message format, like `assert!(foo >= bar, "foo = {foo}, bar = {bar}");` but having the macro do it by default is convenient. There is an old discussion to have the `assert!()` macro parse its expression to figure out what variables are there and print them out by default, but it's still WIP. ( https://github.com/rust-lang/rfcs/blob/master/text/2011-generic-assert.md https://github.com/rust-lang/rfcs/blob/master/text/2011-gene... https://github.com/rust-lang/rust/issues/44838 https://github.com/rust-lang/rust/issues/44838 )
- o11c 2y agoWhat's more, pytest errs on the side of "just capture more" and In my experience it's quite useful: ============================= test session starts ============================== platform linux -- Python 3.11.2, pytest-7.2.1, pluggy-1.0.0+repack rootdir: /tmp/dl/py collected 1 item test_bigsmall.py F [100%] =================================== FAILURES =================================== ________________________________ test_something ________________________________ def test_something(): > assert get_big_number() > get_small_number() E assert 0 > 1 E + where 0 = get_big_number() E + and 1 = get_small_number() test_bigsmall.py:8: AssertionError =========================== short test summary info ============================ FAILED test_bigsmall.py::test_something - assert 0 > 1 ============================== 1 failed in 0.06s ===============================
- lispm 2y agoOr even better have the assertion offer a way to repair the problem: CL-USER 1 > (defun calculate-something (big small) (assert (>= big small) (big small) ; these can be reset "Big ~a must be bigger than small ~a" big small) (sqrt (- big small))) calculate-something The error handling will now offer me to repair it, if necessary: CL-USER 2 > (calculate-something 4 7) Error: Big 4 must be bigger than small 7 1 (continue) Retry assertion with new values for BIG, SMALL. 2 (abort) Return to debug level 0. 3 Restart top-level loop. Type :b for backtrace or :c <option number> to proceed. Type :bug-form "<subject>" for a bug report template or :? for other options. CL-USER 3 : 1 > :c 1 The old value of BIG is 4. Do you want to supply a new value? yes Enter a form to be evaluated: 17 The old value of SMALL is 7. Do you want to supply a new value? yes Enter a form to be evaluated: 5 3.4641016 The last number is the return value