Skip to content

Refactor the test suite using pytest for array and matrix types #438

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 30 commits into from
Dec 30, 2020

Conversation

bnavigator
Copy link
Contributor

@bnavigator bnavigator commented Jul 25, 2020

Inspired by the discussion in #433 I created a pytest fixture matarrayout that parametrizes all the test functions and runs them both with use_numpy_matrix(True) and ...(False) for the two available output conventions. To turn on the autouse fixture, export the environment variable PYTHON_CONTROL_ARRAY_AND_MATRIX=1. There is an additional Travis CI job for this.

It turned out, that the unittest.TestCase inheriting test classes don't like using the autoused fixture. So one thing let to the other and I converted all the test files to conform to pytest.

Test suite changes

  • There are several tests that use config.reset_defaults() working against the functionality of the new fixture. So I changed that too and created the fixture editsdefaults. BTW, I think defaults is a misnomer. It should be settings that can be reset to default values.
  • robust_array_test.py is removed and its functionality completely replaced by the usage of matarrayin in robust_test.py
  • statefbk_array_test.py and state_fbk_matrix_test.py are merged into statefbk_test.py with matarrayin.
  • statesp_array_test.py is merged into statesp_test.py
  • timeresp_test.py looks completeley different now. The tests are organized more systematically to test the time response functions with a more complete set of parameter variations. This revealed the issue described in do not override squeeze parameter in forced_response #442.
  • xferfcn_test.py::test_matrix_multiply() now checks both left and right multiplication with np.matrix and is prepared for array matmul, if we ever succeed to implement it (currently xfails for array).
  • the Travis CI test matrix is extended to Python 3.8 and the matrix definition is cleaned up.
  • There are a few new named pytest marks importable from control.tests.conftest which can be used as decorators on tests for easier definition of skips:
    • @slycotonly
    • @nopython2
    • @noscipy0
  • The matarrayout fixture updates the warnings filter for numpy matrix deprecation warnings. No global filter anymore, so unexpected usage gets revealed for matarrayout=np.array.
  • For checking that functions work with matrix or arrays as input, you can use the fixture matarrayin. The new statefbk_test.py makes use of this -- No test code should directly use deprecated np.matrix anymore.

@coveralls
Copy link

coveralls commented Jul 25, 2020

Coverage Status

Coverage increased (+0.4%) to 87.04% when pulling 2b98769 on bnavigator:array-matrix-tests into 4eee1f3 on python-control:master.

ssxfrm_real = ssxfrm_mag * np.cos(ssxfrm_phase)
ssxfrm_imag = ssxfrm_mag * np.sin(ssxfrm_phase)
np.testing.assert_array_almost_equal(
ssorig_real, ssxfrm_real, decimal=5)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to reduce precision here, because running the test with matrix and array advances the random seed and produces different random systems.

Comment on lines -131 to -136
try:
tf2*tf3 # Error; incompatible timebases
raise ValueError("incompatible operation allowed")
except ValueError:
pass
try:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pytest code makes this look a lot cleaner.

# Make sure that we get a pending deprecation warning
self.assertRaises(PendingDeprecationWarning, frd_tf.evalfr, 1.)
with pytest.deprecated_call():
frd_tf.evalfr(1.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pytest takes care of this just fine

@@ -1,393 +0,0 @@
import unittest
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same code as robust_test.py, just different setup and teardown. So obsolete with the new fixture.

@bnavigator bnavigator force-pushed the array-matrix-tests branch 2 times, most recently from 9500543 to b7b7f7b Compare July 26, 2020 00:05
@bnavigator
Copy link
Contributor Author

the iosys_test now fails with incompatible timebases. probably need to merge #431 too. Has some merge conflicts, will need to rebase and apply #431, #433 in order...

@bnavigator bnavigator force-pushed the array-matrix-tests branch 3 times, most recently from 273a80b to e7affff Compare July 26, 2020 14:31
@bnavigator
Copy link
Contributor Author

@sawyerbfuller, can I pick 8e3ddd2 from your branch fix-lti-evalfr into this PR and pytestify it right away? That way you don't have to submit a PR yourself and I don't have to rebase those fixes later.

@sawyerbfuller
Copy link
Contributor

sawyerbfuller commented Jul 26, 2020 via email

@bnavigator bnavigator force-pushed the array-matrix-tests branch from 9804e7b to 8ee73b9 Compare July 26, 2020 21:42
@sawyerbfuller
Copy link
Contributor

BTW, I think 'defaults' is a misnomer. It should be 'settings' that can be reset to default values.

I agree with this statement.

@bnavigator bnavigator force-pushed the array-matrix-tests branch from 0bd120d to 45d677f Compare July 29, 2020 21:12
@bnavigator bnavigator force-pushed the array-matrix-tests branch 4 times, most recently from 90582e5 to da1c517 Compare August 1, 2020 13:46
@bnavigator bnavigator marked this pull request as ready for review August 1, 2020 18:21
bnavigator added a commit to bnavigator/python-control that referenced this pull request Aug 2, 2020
bnavigator added a commit to bnavigator/python-control that referenced this pull request Aug 2, 2020
@bnavigator bnavigator force-pushed the array-matrix-tests branch 2 times, most recently from e96f365 to ab77e02 Compare August 2, 2020 22:55
@bnavigator
Copy link
Contributor Author

Rebase is done. I pulled everything not directly related to the testsuite out into different PRs. The new timevector calculation needs a minor change (#485) to fix the failing tests here.

revert this commit when merging a rebased python-control#431

(remove statesp_test.py::test_copy_constructor_nodt if not applicable)
Copy link
Member

@murrayrm murrayrm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few small things that could be fixed, but OK to merge.

Comment on lines +17 to 18
- "3.8"
- "3.7"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To minimize CI resource usage, would it make sense to just check against the earliest supported Python 3 release and the latest stable Python 3 release? So 3.6 and 3.9, with the idea that if it works in those two then 3.7, and 3.8 are probably OK as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely. AFAIK we do not make use of any of the changed Python stdlib changes like importlib-metadata, -resources, -dataclasses or the like.

We will need to revisit the test strategy matrix when moving from travis-ci.org to travis-ci.com or Github Actions. (#446)

@@ -4,5 +4,4 @@ universal=1
[tool:pytest]
filterwarnings =
ignore:.*matrix subclass:PendingDeprecationWarning
ignore:.*scipy:DeprecationWarning
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want to ignore these? Seems like something we would want to flag in a CI test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change removes one ignore. We can also remove the other and should track down any remaining matrix usage (in a separate PR, if outside of the test suite). Without the remaining filter, I get this summary:

============================================= warnings summary ==============================================
control/tests/bdalg_test.py: 387 warnings
control/tests/canonical_test.py: 180 warnings
control/tests/config_test.py: 8 warnings
control/tests/convert_test.py: 3080 warnings
control/tests/discrete_test.py: 964 warnings
control/tests/flatsys_test.py: 54 warnings
control/tests/frd_test.py: 87 warnings
control/tests/freqresp_test.py: 84 warnings
control/tests/input_element_int_test.py: 8 warnings
control/tests/iosys_test.py: 728 warnings
control/tests/lti_test.py: 8 warnings
control/tests/margin_test.py: 20 warnings
control/tests/mateqn_test.py: 30 warnings
control/tests/matlab2_test.py: 96 warnings
control/tests/matlab_test.py: 896 warnings
control/tests/minreal_test.py: 4496 warnings
control/tests/modelsimp_test.py: 36 warnings
control/tests/statefbk_test.py: 53 warnings
  /home/greiner/src/python-control/control/statesp.py:102: PendingDeprecationWarning: the matrix subclass is not the recommended way to represent matrices or deal with linear algebra (see https://docs.scipy.org/doc/numpy/user/numpy-for-matlab-users.html). Please adjust your code to use regular ndarray.
    arr = np.matrix(data, dtype=float)

control/tests/iosys_test.py::TestIOSys::test_named_signals_linearize_inconsistent
control/tests/iosys_test.py::TestIOSys::test_named_signals_linearize_inconsistent
control/tests/iosys_test.py::TestIOSys::test_named_signals_linearize_inconsistent
control/tests/iosys_test.py::TestIOSys::test_named_signals_linearize_inconsistent
control/tests/matlab_test.py::TestMatlab::testDcgain
control/tests/matlab_test.py::TestMatlab::testDcgain
control/tests/statefbk_test.py::TestStatefbk::test_LQE[arrayin]
control/tests/statefbk_test.py::TestStatefbk::test_LQE[arrayin]
  /usr/lib64/python3.8/site-packages/numpy/matrixlib/defmatrix.py:69: PendingDeprecationWarning: the matrix subclass is not the recommended way to represent matrices or deal with linear algebra (see https://docs.scipy.org/doc/numpy/user/numpy-for-matlab-users.html). Please adjust your code to use regular ndarray.
    return matrix(data, dtype=dtype, copy=False)

-- Docs: https://docs.pytest.org/en/stable/warnings.html

These warnings vanish, when I activate PYTHON_CONTROL_ARRAY_AND_MATRIX=1. Seems like the default when this is not set is wrong. Will track it down in a few hours.

Comment on lines 22 to 24
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure whether we should only list versions we are explicitly testing against (so this would match .travis.yml list).

@murrayrm murrayrm merged commit c432fd5 into python-control:master Dec 30, 2020
bnavigator added a commit to bnavigator/python-control that referenced this pull request Dec 31, 2020
@bnavigator bnavigator deleted the array-matrix-tests branch February 18, 2024 20:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants