Skip to content

Commit e66ef93

Browse files
committed
frd_test.py convert pytest
1 parent 632589a commit e66ef93

1 file changed

Lines changed: 64 additions & 69 deletions

File tree

control/tests/frd_test.py

Lines changed: 64 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,36 @@
1-
#!/usr/bin/env python
2-
#
3-
# frd_test.py - test FRD class
4-
# RvP, 4 Oct 2012
1+
"""frd_test.py - test FRD class
52
3+
RvP, 4 Oct 2012
4+
"""
65

7-
import unittest
86
import sys as pysys
7+
98
import numpy as np
9+
import matplotlib.pyplot as plt
10+
import pytest
11+
1012
import control as ct
1113
from control.statesp import StateSpace
1214
from control.xferfcn import TransferFunction
1315
from control.frdata import FRD, _convertToFRD, FrequencyResponseData
14-
from control import bdalg
15-
from control import freqplot
16-
from control.exception import slycot_check
17-
import matplotlib.pyplot as plt
16+
from control import bdalg, evalfr, freqplot
17+
from control.tests.conftest import slycotonly
1818

1919

20-
class TestFRD(unittest.TestCase):
20+
class TestFRD:
2121
"""These are tests for functionality and correct reporting of the
2222
frequency response data class."""
2323

2424
def testBadInputType(self):
2525
"""Give the constructor invalid input types."""
26-
self.assertRaises(ValueError, FRD)
27-
self.assertRaises(TypeError, FRD, [1])
26+
with pytest.raises(ValueError):
27+
FRD()
28+
with pytest.raises(TypeError):
29+
FRD([1])
2830

2931
def testInconsistentDimension(self):
30-
self.assertRaises(TypeError, FRD, [1, 1], [1, 2, 3])
32+
with pytest.raises(TypeError):
33+
FRD([1, 1], [1, 2, 3])
3134

3235
def testSISOtf(self):
3336
# get a SISO transfer function
@@ -169,7 +172,7 @@ def testFeedback2(self):
169172
def testAuto(self):
170173
omega = np.logspace(-1, 2, 10)
171174
f1 = _convertToFRD(1, omega)
172-
f2 = _convertToFRD(np.matrix([[1, 0], [0.1, -1]]), omega)
175+
f2 = _convertToFRD(np.array([[1, 0], [0.1, -1]]), omega)
173176
f2 = _convertToFRD([[1, 0], [0.1, -1]], omega)
174177
f1, f2 # reference to avoid pyflakes error
175178

@@ -183,7 +186,7 @@ def testNyquist(self):
183186
freqplot.nyquist(f1, f1.omega)
184187
# plt.savefig('/dev/null', format='svg')
185188

186-
@unittest.skipIf(not slycot_check(), "slycot not installed")
189+
@slycotonly
187190
def testMIMO(self):
188191
sys = StateSpace([[-0.5, 0.0], [0.0, -1.0]],
189192
[[1.0, 0.0], [0.0, 1.0]],
@@ -198,7 +201,7 @@ def testMIMO(self):
198201
sys.freqresp([0.1, 1.0, 10])[1],
199202
f1.freqresp([0.1, 1.0, 10])[1])
200203

201-
@unittest.skipIf(not slycot_check(), "slycot not installed")
204+
@slycotonly
202205
def testMIMOfb(self):
203206
sys = StateSpace([[-0.5, 0.0], [0.0, -1.0]],
204207
[[1.0, 0.0], [0.0, 1.0]],
@@ -214,13 +217,15 @@ def testMIMOfb(self):
214217
f1.freqresp([0.1, 1.0, 10])[1],
215218
f2.freqresp([0.1, 1.0, 10])[1])
216219

217-
@unittest.skipIf(not slycot_check(), "slycot not installed")
220+
@slycotonly
218221
def testMIMOfb2(self):
219-
sys = StateSpace(np.matrix('-2.0 0 0; 0 -1 1; 0 0 -3'),
220-
np.matrix('1.0 0; 0 0; 0 1'),
222+
sys = StateSpace(np.array([[-2.0, 0, 0],
223+
[0, -1, 1],
224+
[0, 0, -3]]),
225+
np.array([[1.0, 0], [0, 0], [0, 1]]),
221226
np.eye(3), np.zeros((3, 2)))
222227
omega = np.logspace(-1, 2, 10)
223-
K = np.matrix('1 0.3 0; 0.1 0 0')
228+
K = np.array([[1, 0.3, 0], [0.1, 0, 0]])
224229
f1 = FRD(sys, omega).feedback(K)
225230
f2 = FRD(sys.feedback(K), omega)
226231
np.testing.assert_array_almost_equal(
@@ -230,7 +235,7 @@ def testMIMOfb2(self):
230235
f1.freqresp([0.1, 1.0, 10])[1],
231236
f2.freqresp([0.1, 1.0, 10])[1])
232237

233-
@unittest.skipIf(not slycot_check(), "slycot not installed")
238+
@slycotonly
234239
def testMIMOMult(self):
235240
sys = StateSpace([[-0.5, 0.0], [0.0, -1.0]],
236241
[[1.0, 0.0], [0.0, 1.0]],
@@ -246,13 +251,13 @@ def testMIMOMult(self):
246251
(f1*f2).freqresp([0.1, 1.0, 10])[1],
247252
(sys*sys).freqresp([0.1, 1.0, 10])[1])
248253

249-
@unittest.skipIf(not slycot_check(), "slycot not installed")
254+
@slycotonly
250255
def testMIMOSmooth(self):
251256
sys = StateSpace([[-0.5, 0.0], [0.0, -1.0]],
252257
[[1.0, 0.0], [0.0, 1.0]],
253258
[[1.0, 0.0], [0.0, 1.0], [1.0, 1.0]],
254259
[[0.0, 0.0], [0.0, 0.0], [0.0, 0.0]])
255-
sys2 = np.matrix([[1, 0, 0], [0, 1, 0]]) * sys
260+
sys2 = np.array([[1, 0, 0], [0, 1, 0]]) * sys
256261
omega = np.logspace(-1, 2, 10)
257262
f1 = FRD(sys, omega, smooth=True)
258263
f2 = FRD(sys2, omega, smooth=True)
@@ -271,47 +276,54 @@ def testAgainstOctave(self):
271276
# sys = ss([-2 0 0; 0 -1 1; 0 0 -3],
272277
# [1 0; 0 0; 0 1], eye(3), zeros(3,2))
273278
# bfr = frd(bsys, [1])
274-
sys = StateSpace(np.matrix('-2.0 0 0; 0 -1 1; 0 0 -3'),
275-
np.matrix('1.0 0; 0 0; 0 1'),
279+
sys = StateSpace(np.array([[-2.0, 0, 0], [0, -1, 1], [0, 0, -3]]),
280+
np.array([[1.0, 0], [0, 0], [0, 1]]),
276281
np.eye(3), np.zeros((3, 2)))
277282
omega = np.logspace(-1, 2, 10)
278283
f1 = FRD(sys, omega)
279284
np.testing.assert_array_almost_equal(
280285
(f1.freqresp([1.0])[0] *
281-
np.exp(1j*f1.freqresp([1.0])[1])).reshape(3, 2),
282-
np.matrix('0.4-0.2j 0; 0 0.1-0.2j; 0 0.3-0.1j'))
286+
np.exp(1j * f1.freqresp([1.0])[1])).reshape(3, 2),
287+
np.matrix([[0.4 - 0.2j, 0], [0, 0.1 - 0.2j], [0, 0.3 - 0.1j]]))
283288

284-
def test_string_representation(self):
289+
def test_string_representation(self, capsys):
285290
sys = FRD([1, 2, 3], [4, 5, 6])
286291
print(sys) # Just print without checking
287292

288-
def test_frequency_mismatch(self):
293+
def test_frequency_mismatch(self, recwarn):
294+
# recwarn: there may be a warning before the error!
289295
# Overlapping but non-equal frequency ranges
290296
sys1 = FRD([1, 2, 3], [4, 5, 6])
291297
sys2 = FRD([2, 3, 4], [5, 6, 7])
292-
self.assertRaises(NotImplementedError, FRD.__add__, sys1, sys2)
298+
with pytest.raises(NotImplementedError):
299+
FRD.__add__(sys1, sys2)
293300

294301
# One frequency range is a subset of another
295302
sys1 = FRD([1, 2, 3], [4, 5, 6])
296303
sys2 = FRD([2, 3], [4, 5])
297-
self.assertRaises(NotImplementedError, FRD.__add__, sys1, sys2)
304+
with pytest.raises(NotImplementedError):
305+
FRD.__add__(sys1, sys2)
298306

299307
def test_size_mismatch(self):
300308
sys1 = FRD(ct.rss(2, 2, 2), np.logspace(-1, 1, 10))
301309

302310
# Different number of inputs
303311
sys2 = FRD(ct.rss(3, 1, 2), np.logspace(-1, 1, 10))
304-
self.assertRaises(ValueError, FRD.__add__, sys1, sys2)
312+
with pytest.raises(ValueError):
313+
FRD.__add__(sys1, sys2)
305314

306315
# Different number of outputs
307316
sys2 = FRD(ct.rss(3, 2, 1), np.logspace(-1, 1, 10))
308-
self.assertRaises(ValueError, FRD.__add__, sys1, sys2)
317+
with pytest.raises(ValueError):
318+
FRD.__add__(sys1, sys2)
309319

310320
# Inputs and outputs don't match
311-
self.assertRaises(ValueError, FRD.__mul__, sys2, sys1)
321+
with pytest.raises(ValueError):
322+
FRD.__mul__(sys2, sys1)
312323

313324
# Feedback mismatch
314-
self.assertRaises(ValueError, FRD.feedback, sys2, sys1)
325+
with pytest.raises(ValueError):
326+
FRD.feedback(sys2, sys1)
315327

316328
def test_operator_conversion(self):
317329
sys_tf = ct.tf([1], [1, 2, 1])
@@ -365,7 +377,8 @@ def test_operator_conversion(self):
365377
np.testing.assert_array_almost_equal(sys_pow.fresp, chk_pow.fresp)
366378

367379
# Assertion error if we try to raise to a non-integer power
368-
self.assertRaises(ValueError, FRD.__pow__, frd_tf, 0.5)
380+
with pytest.raises(ValueError):
381+
FRD.__pow__(frd_tf, 0.5)
369382

370383
# Selected testing on transfer function conversion
371384
sys_add = frd_2 + sys_tf
@@ -375,44 +388,29 @@ def test_operator_conversion(self):
375388

376389
# Input/output mismatch size mismatch in rmul
377390
sys1 = FRD(ct.rss(2, 2, 2), np.logspace(-1, 1, 10))
378-
self.assertRaises(ValueError, FRD.__rmul__, frd_2, sys1)
391+
with pytest.raises(ValueError):
392+
FRD.__rmul__(frd_2, sys1)
379393

380394
# Make sure conversion of something random generates exception
381-
self.assertRaises(TypeError, FRD.__add__, frd_tf, 'string')
395+
with pytest.raises(TypeError):
396+
FRD.__add__(frd_tf, 'string')
382397

383398
def test_eval(self):
384399
sys_tf = ct.tf([1], [1, 2, 1])
385400
frd_tf = FRD(sys_tf, np.logspace(-1, 1, 3))
386-
np.testing.assert_almost_equal(sys_tf.evalfr(1), frd_tf.eval(1))
401+
np.testing.assert_almost_equal(evalfr(sys_tf, 1J), frd_tf.eval(1))
387402

388403
# Should get an error if we evaluate at an unknown frequency
389-
self.assertRaises(ValueError, frd_tf.eval, 2)
404+
with pytest.raises(ValueError):
405+
frd_tf.eval(2)
406+
390407

391-
# This test only works in Python 3 due to a conflict with the same
392-
# warning type in other test modules (frd_test.py). See
393-
# https://bugs.python.org/issue4180 for more details
394-
@unittest.skipIf(pysys.version_info < (3, 0), "test requires Python 3+")
395408
def test_evalfr_deprecated(self):
396409
sys_tf = ct.tf([1], [1, 2, 1])
397410
frd_tf = FRD(sys_tf, np.logspace(-1, 1, 3))
398411

399-
# Deprecated version of the call (should generate warning)
400-
import warnings
401-
with warnings.catch_warnings():
402-
# Make warnings generate an exception
403-
warnings.simplefilter('error')
404-
405-
# Make sure that we get a pending deprecation warning
406-
self.assertRaises(PendingDeprecationWarning, frd_tf.evalfr, 1.)
407-
408-
# FRD.evalfr() is being deprecated
409-
import warnings
410-
with warnings.catch_warnings():
411-
# Make warnings generate an exception
412-
warnings.simplefilter('error')
413-
414-
# Make sure that we get a pending deprecation warning
415-
self.assertRaises(PendingDeprecationWarning, frd_tf.evalfr, 1.)
412+
with pytest.deprecated_call():
413+
frd_tf.evalfr(1.)
416414

417415
def test_repr_str(self):
418416
# repr printing
@@ -427,8 +425,8 @@ def test_repr_str(self):
427425
sysm = FrequencyResponseData(
428426
np.matmul(array([[1],[2]]), sys0.fresp), sys0.omega)
429427

430-
self.assertEqual(repr(sys0), ref0)
431-
self.assertEqual(repr(sys1), ref1)
428+
assert repr(sys0) == ref0
429+
assert repr(sys1) == ref1
432430
sys0r = eval(repr(sys0))
433431
np.testing.assert_array_almost_equal(sys0r.fresp, sys0.fresp)
434432
np.testing.assert_array_almost_equal(sys0r.omega, sys0.omega)
@@ -444,8 +442,8 @@ def test_repr_str(self):
444442
1.000 0.9 +0.1j
445443
10.000 0.1 +2j
446444
100.000 0.05 +3j"""
447-
self.assertEqual(str(sys0), refs)
448-
self.assertEqual(str(sys1), refs)
445+
assert str(sys0) == refs
446+
assert str(sys1) == refs
449447

450448
# print multi-input system
451449
refm = """Frequency response data
@@ -463,7 +461,4 @@ def test_repr_str(self):
463461
1.000 1.8 +0.2j
464462
10.000 0.2 +4j
465463
100.000 0.1 +6j"""
466-
self.assertEqual(str(sysm), refm)
467-
468-
if __name__ == "__main__":
469-
unittest.main()
464+
assert str(sysm) == refm

0 commit comments

Comments
 (0)