## Pytest approximately equal scalars and arrays

Pytest cleanly handles many continuous integration issues.
Pytest is worthwhile to setup tests and improve test coverage.
It’s straightforward to incrementally upgrade from obsolete `nose`

and legacy `unittest`

modules to Pytest.

A frequent CI task is comparing floating point numbers. Computer representations of floating point numbers have finite precision. Real numbers associativity doesn’t completely apply to digital floating point representations. A practical solution to this problem is to compare numbers (scalars or arrays) to within an absolute and relative tolerance. Widely known functions exist to compare “equality” of floating point numbers in Python and Fortran real/assert.F90 among other numerical languages.

pytest.approx
provides a syntactically clean approach that may be more intuitive and readable for CI applications.
It works with scalars and arrays of all sorts including the ubiquitous `numpy.ndarray`

.

This example shows how to replace `numpy.testing.assert_allclose()`

with `pytest.approx()`

:

```
import numpy as np
from pytest import approx
def test_mynums():
x = np.array([2.00000000001, 1.99999999999])
assert x == approx(2.)
```

Whereas with Numpy, the last line would have been `np.testing.assert_allclose(x, 2.)`

.
The Pytest syntax and appearance are more readable.

NaN is an unrepresentable, undefined quantity as results from invalid computations like:

- ∞ / ∞
- 0 / 0

NaN are also useful as sentinel values to indicate a problem with a computation for example.
Python sentinel
values include `NaN`

and `None`

.
In Julia, performance is approximately the same for `nan`

vs. `nothing`

sentinel values.

The option `pytest.approx(nan_ok=True)`

allows one or more NaN’s in the test array.

Absolute and relative **tolerance** are important considerations for CI, particularly across OS and computer types, where order of operation and numerical CPU/GPU/APU/etc. tolerances and low level math routines (BLAS, AVX, etc.) differ.
Especially (perhaps obviously) for single precision arithmetic vs. double precision arithmetic, tolerances will be larger.
pytest.approx() default tolerances work for many situations.
Absolute tolerance shouldn’t be 0 to avoid unexpected effects near 0.
Depending on the parameter, `rel=1e-4`

may be more appropriate for CI tests that need to work on a variety of systems.