Failures vs errors

Tests can have tree different outcomes; success, failure and error.

Success and failure are the two common cases where success is when the test meets the expected assertions and a failure is when it fails to meet a test assertion like testing.assertEqual(1, 2). We also distinguish a third case for test errors which is when a test does not run as expected, hitting an unexpected exception. This could indicate a design issue or that the test environment is not as expected.

All test assertions raise exceptions inheriting from AssertionError which are considered test failures. Any other exception will be considered a test error.

For example, if a test attempts to retrieve https://dummyjson.com/products/1 and check that the returned JSON looks a certain way, it would be a test failure if the returned JSON does not match the expected value. If we try to connect with an invalid URL, like htp:// we would get a different exception and that would be considered a test error. It's probably a bad idea to try to connect to something on the Internet in a test, so avoid that and other sources of non-determinism when possible.

Unit tests

Source:

import random
import testing

def _test_failure():
    testing.assertEqual(1, 2)

def _test_flaky():
    i = random.randint(0, 2)
    if i == 0:
        return
    elif i == 1:
        testing.assertEqual(1, 2)
    else:
        raise ValueError("Random failure")

def _test_error() -> None:
    # Now we could never use a unit test to fetch things from the Internet
    # anyway, but it's just to show what the results look like
    raise ValueError()

Run:

acton test

Output:

Building project in /home/user/foo
  Compiling example.act for release
   Finished compilation in   0.020 s
  Final compilation step
   Finished final compilation step in   0.482 s

Tests - module example:
  error:                 ERR: 454 errors out of  454 runs in 52.733ms
    ValueError: 
  flaky:                 FLAKY FAIL: 231 failures out of  471 runs in 52.819ms
    testing.NotEqualError: Expected equal values but they are non-equal. A: 1 B: 2
  failure:               FAIL: 408 failures out of  408 runs in 52.837ms
    testing.NotEqualError: Expected equal values but they are non-equal. A: 1 B: 2

1 error and 2 failure out of 3 tests (0.691s)

Unit tests are a good starting point for testing small units of your program. Pure functions are deterministic and are thus preferable for tests over non-deterministic tests using actors. You are limited in what you can do though, since all called functions must be pure.