From d485940e9ee6b4e28b46fba67360bf51fecb1632 Mon Sep 17 00:00:00 2001
From: PeterMeisrimelModelon
<92585725+PeterMeisrimelModelon@users.noreply.github.com>
Date: Mon, 12 Feb 2024 17:01:50 +0100
Subject: [PATCH] Replacing nose by pytest
---
.github/workflows/build.yml | 4 +-
setup.cfg | 2 +-
src/pyfmi/__init__.py | 14 --
tests/test_fmi.py | 357 ++++++++++++++----------------------
tests/test_fmi_coupled.py | 63 +++----
tests/test_fmi_estimate.py | 3 -
tests/test_fmi_extended.py | 3 -
tests/test_fmi_master.py | 31 +---
tests/test_fmi_util.py | 4 -
tests/test_io.py | 263 ++++++++------------------
tests/test_log.py | 19 +-
tests/test_stream.py | 43 ++---
12 files changed, 270 insertions(+), 536 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 31cc431c..12bf70e9 100755
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -15,7 +15,7 @@ jobs:
python-version: '3.11.x'
- name: Setup Python
run: |
- python3 -m pip install Cython numpy scipy matplotlib nose-py3
+ python3 -m pip install Cython numpy scipy matplotlib pytest
- name: Install system
run: |
sudo apt-get -y install cmake liblapack-dev libsuitesparse-dev libhypre-dev
@@ -59,4 +59,4 @@ jobs:
run: |
rm src/pyfmi/__init__.py
cp -rv src/pyfmi/tests/files tests
- python3 -m nose --verbose tests/*.py
+ pytest --verbose tests/
diff --git a/setup.cfg b/setup.cfg
index ae02d747..50f3ede2 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -8,6 +8,6 @@ install_requires =
numpy >= 1.26.3
scipy >= 1.11.4
cython >= 3.0.7
- nose-py3 >= 1.6.3
+ pytest >= 7.4.4
matplotlib > 3
assimulo >= 3.5.0
diff --git a/src/pyfmi/__init__.py b/src/pyfmi/__init__.py
index 49d628c6..54ed6beb 100644
--- a/src/pyfmi/__init__.py
+++ b/src/pyfmi/__init__.py
@@ -34,20 +34,6 @@
int = np.int32
np.int = np.int32
-def testattr(**kwargs):
- """Add attributes to a test function/method/class.
-
- This function is needed to be able to add
- @attr(slow = True)
- for functions.
-
- """
- def wrap(func):
- func.__dict__.update(kwargs)
- return func
- return wrap
-
-
try:
curr_dir = os.path.dirname(os.path.abspath(__file__))
_fpath=os.path.join(curr_dir,'version.txt')
diff --git a/tests/test_fmi.py b/tests/test_fmi.py
index 3b46e907..88d73056 100644
--- a/tests/test_fmi.py
+++ b/tests/test_fmi.py
@@ -15,7 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-import nose
+import pytest
import os
import numpy as np
from zipfile import ZipFile
@@ -24,7 +24,6 @@
import logging
from io import StringIO
-from pyfmi import testattr
from pyfmi.fmi import FMUException, InvalidOptionException, InvalidXMLException, InvalidBinaryException, InvalidVersionException, FMUModelME1, FMUModelCS1, load_fmu, FMUModelCS2, FMUModelME2
import pyfmi.fmi as fmi
from pyfmi.fmi_algorithm_drivers import AssimuloFMIAlg, AssimuloFMIAlgOptions, \
@@ -70,12 +69,11 @@ def _helper_unzipped_fmu_exception_invalid_dir(fmu_loader):
"""
err_msg = "Specified fmu path '.*\\' needs to contain a modelDescription.xml according to the FMI specification"
with tempfile.TemporaryDirectory() as temp_dir:
- with np.testing.assert_raises_regex(FMUException, err_msg):
+ with pytest.raises(FMUException, match = err_msg):
fmu = fmu_loader(temp_dir, allow_unzipped_fmu = True)
if assimulo_installed:
class Test_FMUModelME1_Simulation:
- @testattr(stddist = True)
def test_simulate_with_debug_option_no_state(self):
""" Verify that an instance of CVodeDebugInformation is created """
model = Dummy_FMUModelME1([], os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "NoState.Example1.fmu"), _connect_dll=False)
@@ -90,7 +88,6 @@ def test_simulate_with_debug_option_no_state(self):
from pyfmi.debug import CVodeDebugInformation
debug = CVodeDebugInformation("NoState_Example1_debug.txt")
- @testattr(stddist = True)
def test_no_result(self):
model = Dummy_FMUModelME1([], os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "NegatedAlias.fmu"), _connect_dll=False)
@@ -98,7 +95,8 @@ def test_no_result(self):
opts["result_handling"] = None
res = model.simulate(options=opts)
- nose.tools.assert_raises(Exception,res._get_result_data)
+ with pytest.raises(Exception):
+ res._get_result_data()
model = Dummy_FMUModelME1([], os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "NegatedAlias.fmu"), _connect_dll=False)
@@ -106,9 +104,9 @@ def test_no_result(self):
opts["return_result"] = False
res = model.simulate(options=opts)
- nose.tools.assert_raises(Exception,res._get_result_data)
+ with pytest.raises(Exception):
+ res._get_result_data()
- @testattr(stddist = True)
def test_custom_result_handler(self):
model = Dummy_FMUModelME1([], os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "NegatedAlias.fmu"), _connect_dll=False)
@@ -120,11 +118,14 @@ def get_result(self):
opts = model.simulate_options()
opts["result_handling"] = "hejhej"
- nose.tools.assert_raises(Exception, model.simulate, options=opts)
+ with pytest.raises(Exception):
+ model.simulate(options=opts)
opts["result_handling"] = "custom"
- nose.tools.assert_raises(Exception, model.simulate, options=opts)
+ with pytest.raises(Exception):
+ model.simulate(options=opts)
opts["result_handler"] = A()
- nose.tools.assert_raises(Exception, model.simulate, options=opts)
+ with pytest.raises(Exception):
+ model.simulate(options=opts)
opts["result_handler"] = B()
res = model.simulate(options=opts)
@@ -136,7 +137,6 @@ def setup_atol_auto_update_test_base(self):
opts["solver"] = "CVode"
return model, opts
- @testattr(stddist = True)
def test_atol_auto_update1(self):
"""
Tests that atol automatically gets updated when "atol = factor * pre_init_nominals".
@@ -148,7 +148,6 @@ def test_atol_auto_update1(self):
model.simulate(options=opts, algorithm=NoSolveAlg)
np.testing.assert_allclose(opts["CVode_options"]["atol"], [0.03, 0.03])
- @testattr(stddist = True)
def test_atol_auto_update2(self):
"""
Tests that atol doesn't get auto-updated when heuristic fails.
@@ -160,7 +159,6 @@ def test_atol_auto_update2(self):
model.simulate(options=opts, algorithm=NoSolveAlg)
np.testing.assert_allclose(opts["CVode_options"]["atol"], [0.03, 0.02])
- @testattr(stddist = True)
def test_atol_auto_update3(self):
"""
Tests that atol doesn't get auto-updated when nominals are never retrieved.
@@ -178,8 +176,6 @@ def test_atol_auto_update3(self):
class Test_FMUModelME1:
-
- @testattr(stddist = True)
def test_unzipped_fmu_exception_invalid_dir(self):
""" Verify that we get an exception if unzipped FMU does not contain modelDescription.xml, which it should according to the FMI specification. """
_helper_unzipped_fmu_exception_invalid_dir(FMUModelME1)
@@ -197,31 +193,26 @@ def _test_unzipped_bouncing_ball(self, fmu_loader):
value = np.abs(res.final('h') - (0.0424044))
assert value < tol, "Assertion failed, value={} is not less than {}.".format(value, tol)
- @testattr(stddist = True)
def test_unzipped_fmu1(self):
""" Test load and simulate unzipped ME FMU 1.0 using FMUModelME1 """
self._test_unzipped_bouncing_ball(FMUModelME1)
- @testattr(stddist = True)
def test_unzipped_fmu2(self):
""" Test load and simulate unzipped ME FMU 1.0 using load_fmu """
self._test_unzipped_bouncing_ball(load_fmu)
- @testattr(stddist = True)
def test_invalid_binary(self):
err_msg = "The FMU could not be loaded."
fmu = os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "RLC_Circuit.fmu")
- with nose.tools.assert_raises_regex(InvalidBinaryException, err_msg):
+ with pytest.raises(InvalidBinaryException, match = err_msg):
model = FMUModelME1(fmu, _connect_dll=True)
- @testattr(stddist = True)
def test_invalid_version(self):
err_msg = "This class only supports FMI 1.0"
fmu = os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "LinearStability.SubSystem2.fmu")
- with nose.tools.assert_raises_regex(InvalidVersionException, err_msg):
+ with pytest.raises(InvalidVersionException, match = err_msg):
model = FMUModelME1(fmu, _connect_dll=True)
- @testattr(stddist = True)
def test_get_time_varying_variables(self):
model = FMUModelME1(os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "RLC_Circuit.fmu"), _connect_dll=False)
@@ -232,7 +223,6 @@ def test_get_time_varying_variables(self):
assert len(i) == len(i_f)
assert len(b) == len(b_f)
- @testattr(stddist = True)
def test_get_time_varying_variables_with_alias(self):
model = FMUModelME1(os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "Alias1.fmu"), _connect_dll=False)
@@ -241,20 +231,19 @@ def test_get_time_varying_variables_with_alias(self):
assert len(r) == 1
assert r[0] == model.get_variable_valueref("y")
- @testattr(stddist = True)
def test_get_variable_by_valueref(self):
bounce = FMUModelME1(os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "bouncingBall.fmu"), _connect_dll=False)
assert "der(v)" == bounce.get_variable_by_valueref(3)
assert "v" == bounce.get_variable_by_valueref(2)
- nose.tools.assert_raises(FMUException, bounce.get_variable_by_valueref,7)
+ with pytest.raises(FMUException):
+ bounce.get_variable_by_valueref(7)
- @testattr(stddist = True)
def test_get_variable_nominal_valueref(self):
bounce = FMUModelME1(os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "bouncingBall.fmu"), _connect_dll=False)
assert bounce.get_variable_nominal("v") == bounce.get_variable_nominal(valueref=2)
- @testattr(windows_full = True)
+ #@testattr(windows_full = True)
def test_default_experiment(self):
model = FMUModelME1(FMU_PATHS.ME1.coupled_clutches, _connect_dll=False)
@@ -263,14 +252,12 @@ def test_default_experiment(self):
assert np.abs(model.get_default_experiment_tolerance()-0.0001) < 1e-4
- @testattr(stddist = True)
def test_log_file_name(self):
model = FMUModelME1(os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "bouncingBall.fmu"), _connect_dll=False)
assert os.path.exists("bouncingBall_log.txt")
model = FMUModelME1(os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "bouncingBall.fmu"), _connect_dll=False, log_file_name="Test_log.txt")
assert os.path.exists("Test_log.txt")
- @testattr(stddist = True)
def test_ode_get_sizes(self):
bounce = FMUModelME1(os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "bouncingBall.fmu"), _connect_dll=False)
dq = FMUModelME1(os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "dq.fmu"), _connect_dll=False)
@@ -283,7 +270,6 @@ def test_ode_get_sizes(self):
assert nCont == 1
assert nEvent == 0
- @testattr(stddist = True)
def test_get_name(self):
bounce = FMUModelME1(os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "bouncingBall.fmu"), _connect_dll=False)
dq = FMUModelME1(os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "dq.fmu"), _connect_dll=False)
@@ -291,14 +277,13 @@ def test_get_name(self):
assert bounce.get_name() == 'bouncingBall'
assert dq.get_name() == 'dq'
- @testattr(stddist = True)
def test_instantiate_jmu(self):
"""
Test that FMUModelME1 can not be instantiated with a JMU file.
"""
- nose.tools.assert_raises(FMUException,FMUModelME1,'model.jmu')
+ with pytest.raises(FMUException):
+ FMUModelME1('model.jmu')
- @testattr(stddist = True)
def test_get_fmi_options(self):
"""
Test that simulate_options on an FMU returns the correct options
@@ -307,7 +292,6 @@ class instance.
bounce = FMUModelME1(os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "bouncingBall.fmu"), _connect_dll=False)
assert isinstance(bounce.simulate_options(), AssimuloFMIAlgOptions)
- @testattr(stddist = True)
def test_get_xxx_empty(self):
""" Test that get_xxx([]) do not calls do not trigger calls to FMU. """
model = FMUModelME1(os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "bouncingBall.fmu"), _connect_dll=False)
@@ -318,8 +302,6 @@ def test_get_xxx_empty(self):
assert len(model.get_string([])) == 0, "get_string ([]) has non-empty return"
class Test_FMUModelCS1:
-
- @testattr(stddist = True)
def test_unzipped_fmu_exception_invalid_dir(self):
""" Verify that we get an exception if unzipped FMU does not contain modelDescription.xml, which it should according to the FMI specification. """
_helper_unzipped_fmu_exception_invalid_dir(FMUModelCS1)
@@ -337,31 +319,26 @@ def _test_unzipped_bouncing_ball(self, fmu_loader):
value = np.abs(res.final('h') - (0.0424044))
assert value < tol, "Assertion failed, value={} is not less than {}.".format(value, tol)
- @testattr(stddist = True)
def test_unzipped_fmu1(self):
""" Test load and simulate unzipped CS FMU 1.0 using FMUModelCS1 """
self._test_unzipped_bouncing_ball(FMUModelCS1)
- @testattr(stddist = True)
def test_unzipped_fmu2(self):
""" Test load and simulate unzipped CS FMU 1.0 using load_fmu """
self._test_unzipped_bouncing_ball(load_fmu)
- @testattr(stddist = True)
def test_invalid_binary(self):
err_msg = "The FMU could not be loaded."
fmu = os.path.join(file_path, "files", "FMUs", "XML", "CS1.0", "NegatedAlias.fmu")
- with nose.tools.assert_raises_regex(InvalidBinaryException, err_msg):
+ with pytest.raises(InvalidBinaryException, match = err_msg):
model = FMUModelCS1(fmu, _connect_dll=True)
- @testattr(stddist = True)
def test_invalid_version(self):
err_msg = "This class only supports FMI 1.0"
fmu = os.path.join(file_path, "files", "FMUs", "XML", "CS2.0", "NegatedAlias.fmu")
- with nose.tools.assert_raises_regex(InvalidVersionException, err_msg):
+ with pytest.raises(InvalidVersionException, match = err_msg):
model = FMUModelCS1(fmu, _connect_dll=True)
- @testattr(stddist = True)
def test_custom_result_handler(self):
model = Dummy_FMUModelCS1([], os.path.join(file_path, "files", "FMUs", "XML", "CS1.0", "NegatedAlias.fmu"), _connect_dll=False)
@@ -373,15 +350,17 @@ def get_result(self):
opts = model.simulate_options()
opts["result_handling"] = "hejhej"
- nose.tools.assert_raises(Exception, model.simulate, options=opts)
+ with pytest.raises(Exception):
+ model.simulate(options=opts)
opts["result_handling"] = "custom"
- nose.tools.assert_raises(Exception, model.simulate, options=opts)
+ with pytest.raises(Exception):
+ model.simulate(options=opts)
opts["result_handler"] = A()
- nose.tools.assert_raises(Exception, model.simulate, options=opts)
+ with pytest.raises(Exception):
+ model.simulate(options=opts)
opts["result_handler"] = B()
res = model.simulate(options=opts)
- @testattr(stddist = True)
def test_no_result(self):
model = Dummy_FMUModelCS1([], os.path.join(file_path, "files", "FMUs", "XML", "CS1.0", "NegatedAlias.fmu"), _connect_dll=False)
@@ -389,7 +368,8 @@ def test_no_result(self):
opts["result_handling"] = None
res = model.simulate(options=opts)
- nose.tools.assert_raises(Exception,res._get_result_data)
+ with pytest.raises(Exception):
+ res._get_result_data()
model = Dummy_FMUModelCS1([], os.path.join(file_path, "files", "FMUs", "XML", "CS1.0", "NegatedAlias.fmu"), _connect_dll=False)
@@ -397,9 +377,9 @@ def test_no_result(self):
opts["return_result"] = False
res = model.simulate(options=opts)
- nose.tools.assert_raises(Exception,res._get_result_data)
+ with pytest.raises(Exception):
+ res._get_result_data()
- @testattr(stddist = True)
def test_result_name_file(self):
model = Dummy_FMUModelCS1([], os.path.join(file_path, "files", "FMUs", "XML", "CS1.0", "CoupledClutches.fmu"), _connect_dll=False)
@@ -417,7 +397,6 @@ def test_result_name_file(self):
assert res.result_file == "CoupledClutches_result_test.txt"
assert os.path.exists(res.result_file)
- @testattr(stddist = True)
def test_default_experiment(self):
model = FMUModelCS1(os.path.join(file_path, "files", "FMUs", "XML", "CS1.0", "CoupledClutches.fmu"), _connect_dll=False)
@@ -425,25 +404,24 @@ def test_default_experiment(self):
assert np.abs(model.get_default_experiment_stop_time()-1.5) < 1e-4
assert np.abs(model.get_default_experiment_tolerance()-0.0001) < 1e-4
- @testattr(stddist = True)
def test_log_file_name(self):
model = FMUModelCS1(os.path.join(file_path, "files", "FMUs", "XML", "CS1.0", "bouncingBall.fmu", ), _connect_dll=False)
assert os.path.exists("bouncingBall_log.txt")
model = FMUModelCS1(os.path.join(file_path, "files", "FMUs", "XML", "CS1.0", "bouncingBall.fmu"), _connect_dll=False, log_file_name="Test_log.txt")
assert os.path.exists("Test_log.txt")
- @testattr(stddist = True)
def test_erreneous_ncp(self):
model = Dummy_FMUModelCS1([], os.path.join(file_path, "files", "FMUs", "XML", "CS1.0", "NegatedAlias.fmu"), _connect_dll=False)
opts = model.simulate_options()
opts["ncp"] = 0
- nose.tools.assert_raises(FMUException, model.simulate, options=opts)
+ with pytest.raises(FMUException):
+ model.simulate(options=opts)
opts["ncp"] = -1
- nose.tools.assert_raises(FMUException, model.simulate, options=opts)
+ with pytest.raises(FMUException):
+ model.simulate(options=opts)
class Test_FMUModelBase:
- @testattr(stddist = True)
def test_unicode_description(self):
full_path = os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "Description.fmu")
model = FMUModelME1(full_path, _connect_dll=False)
@@ -452,14 +430,12 @@ def test_unicode_description(self):
assert desc == "Test symbols '' ‘’"
- @testattr(stddist = True)
def test_get_erronous_nominals(self):
model = FMUModelME1(FMU_PATHS.ME1.nominal_test4, _connect_dll=False)
- nose.tools.assert_almost_equal(model.get_variable_nominal("x"), 2.0)
- nose.tools.assert_almost_equal(model.get_variable_nominal("y"), 1.0)
+ assert model.get_variable_nominal("x") == pytest.approx(2.0)
+ assert model.get_variable_nominal("y") == pytest.approx(1.0)
- @testattr(stddist = True)
def test_caching(self):
negated_alias = FMUModelME1(os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "NegatedAlias.fmu"), _connect_dll=False)
@@ -487,7 +463,6 @@ def test_caching(self):
vars_6 = negated_alias.get_model_variables()
assert id(vars_1) != id(vars_6)
- @testattr(stddist = True)
def test_get_scalar_variable(self):
negated_alias = FMUModelME1(os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "NegatedAlias.fmu"), _connect_dll=False)
@@ -500,26 +475,27 @@ def test_get_scalar_variable(self):
assert sc_x.causality == fmi.FMI_INTERNAL
assert sc_x.alias == fmi.FMI_NO_ALIAS
- nose.tools.assert_raises(FMUException, negated_alias.get_scalar_variable, "not_existing")
+ with pytest.raises(FMUException):
+ negated_alias.get_scalar_variable("not_existing")
- @testattr(stddist = True)
def test_get_variable_description(self):
model = FMUModelME1(FMU_PATHS.ME1.coupled_clutches, _connect_dll=False)
assert model.get_variable_description("J1.phi") == "Absolute rotation angle of component"
- @testattr(stddist = True)
def test_simulation_without_initialization(self):
model = Dummy_FMUModelME1([], os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "bouncingBall.fmu"), _connect_dll=False)
opts = model.simulate_options()
opts["initialize"] = False
- nose.tools.assert_raises(FMUException, model.simulate, options=opts)
+ with pytest.raises(FMUException):
+ model.simulate(options=opts)
model = Dummy_FMUModelCS1([], os.path.join(file_path, "files", "FMUs", "XML", "CS1.0", "bouncingBall.fmu"), _connect_dll=False)
opts = model.simulate_options()
opts["initialize"] = False
- nose.tools.assert_raises(FMUException, model.simulate, options=opts)
+ with pytest.raises(FMUException):
+ model.simulate(options=opts)
def test_get_erroneous_nominals_capi_fmi1(self):
""" Tests that erroneous nominals returned from getting nominals of continuous states get auto-corrected. """
@@ -549,30 +525,26 @@ def test_get_erroneous_nominals_capi_fmi1(self):
expected_msg2 = "The nominal value for J4.w is 0.0 which is illegal according to the " \
+ "FMI specification. Setting the nominal to 1.0."
log = str(log_stream.getvalue())
- nose.tools.assert_in(expected_msg1, log) # First warning of 6.
- nose.tools.assert_in(expected_msg2, log) # Last warning of 6.
+ assert expected_msg1 in log # First warning of 6.
+ assert expected_msg2 in log # Last warning of 6.
# Check values are auto-corrected:
- nose.tools.assert_almost_equal(xn[0], 2.0) # -2.0
- nose.tools.assert_almost_equal(xn[1], 1.0) # 0.0
- nose.tools.assert_almost_equal(xn[2], 2.0) # 2.0
- nose.tools.assert_almost_equal(xn[3], 2.0) # -2.0
- nose.tools.assert_almost_equal(xn[4], 1.0) # 0.0
- nose.tools.assert_almost_equal(xn[5], 2.0) # 2.0
- nose.tools.assert_almost_equal(xn[6], 2.0) # -2.0
- nose.tools.assert_almost_equal(xn[7], 1.0) # 0,0
+ assert xn[0] == pytest.approx(2.0)
+ assert xn[1] == pytest.approx(1.0)
+ assert xn[2] == pytest.approx(2.0)
+ assert xn[3] == pytest.approx(2.0)
+ assert xn[4] == pytest.approx(1.0)
+ assert xn[5] == pytest.approx(2.0)
+ assert xn[6] == pytest.approx(2.0)
+ assert xn[7] == pytest.approx(1.0)
class Test_LoadFMU:
-
- @testattr(stddist = True)
def test_unzipped_fmu_exception_invalid_dir(self):
""" Verify that we get an exception if unzipped FMU does not contain modelDescription.xml, which it should according to the FMI specification. """
_helper_unzipped_fmu_exception_invalid_dir(load_fmu)
class Test_FMUModelCS2:
-
- @testattr(stddist = True)
def test_unzipped_fmu_exception_invalid_dir(self):
""" Verify that we get an exception if unzipped FMU does not contain modelDescription.xml, which it should according to the FMI specification. """
_helper_unzipped_fmu_exception_invalid_dir(FMUModelCS2)
@@ -590,17 +562,14 @@ def _test_unzipped_bouncing_ball(self, fmu_loader):
value = np.abs(res.final('h') - (0.0424044))
assert value < tol, "Assertion failed, value={} is not less than {}.".format(value, tol)
- @testattr(stddist = True)
def test_unzipped_fmu1(self):
""" Test load and simulate unzipped CS FMU 2.0 using FMUModelCS2 """
self._test_unzipped_bouncing_ball(FMUModelCS2)
- @testattr(stddist = True)
def test_unzipped_fmu2(self):
""" Test load and simulate unzipped CS FMU 2.0 using load_fmu """
self._test_unzipped_bouncing_ball(load_fmu)
- @testattr(stddist = True)
def test_log_file_name(self):
full_path = os.path.join(file_path, "files", "FMUs", "XML", "CS2.0", "CoupledClutches.fmu")
model = FMUModelCS2(full_path, _connect_dll=False)
@@ -608,40 +577,37 @@ def test_log_file_name(self):
path, file_name = os.path.split(full_path)
assert model.get_log_filename() == file_name.replace(".","_")[:-4]+"_log.txt"
- @testattr(stddist = True)
def test_invalid_binary(self):
err_msg = "The FMU could not be loaded."
fmu = os.path.join(file_path, "files", "FMUs", "XML", "CS2.0", "CoupledClutches.fmu")
- with nose.tools.assert_raises_regex(InvalidBinaryException, err_msg):
+ with pytest.raises(InvalidBinaryException, match = err_msg):
model = FMUModelCS2(fmu, _connect_dll=True)
- @testattr(stddist = True)
def test_invalid_version(self):
err_msg = "The FMU version is not supported"
fmu = os.path.join(file_path, "files", "FMUs", "XML", "CS1.0", "CoupledClutches.fmu")
- with nose.tools.assert_raises_regex(InvalidVersionException, err_msg):
+ with pytest.raises(InvalidVersionException, match = err_msg):
model = FMUModelCS2(fmu, _connect_dll=True)
- @testattr(stddist = True)
def test_unzipped_fmu_exceptions(self):
""" Verify exception is raised if 'fmu' is a file and allow_unzipped_fmu is set to True, with FMUModelCS2. """
err_msg = "Argument named 'fmu' must be a directory if argument 'allow_unzipped_fmu' is set to True."
- with nose.tools.assert_raises_regex(FMUException, err_msg):
+ with pytest.raises(FMUException, match = err_msg):
model = FMUModelCS2(os.path.join(file_path, "files", "FMUs", "XML", "CS2.0", "LinearStability.SubSystem1.fmu"), _connect_dll=False, allow_unzipped_fmu=True)
- @testattr(stddist = True)
def test_erreneous_ncp(self):
model = FMUModelCS2(os.path.join(file_path, "files", "FMUs", "XML", "CS2.0", "CoupledClutches.fmu"), _connect_dll=False)
opts = model.simulate_options()
opts["ncp"] = 0
- nose.tools.assert_raises(FMUException, model.simulate, options=opts)
+ with pytest.raises(FMUException):
+ model.simulate(options=opts)
opts["ncp"] = -1
- nose.tools.assert_raises(FMUException, model.simulate, options=opts)
+ with pytest.raises(FMUException):
+ model.simulate(options=opts)
if assimulo_installed:
class Test_FMUModelME2_Simulation:
- @testattr(stddist = True)
def test_basicsens1(self):
#Noncompliant FMI test as 'd' is parameter is not supposed to be able to be set during simulation
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "BasicSens1.fmu"), _connect_dll=False)
@@ -658,11 +624,10 @@ def f(*args, **kwargs):
opts["sensitivities"] = ["d"]
res = model.simulate(options=opts)
- nose.tools.assert_almost_equal(res.final('dx/dd'), 0.36789, 3)
+ assert res.final('dx/dd') == pytest.approx(0.36789, abs = 1e-3)
assert res.solver.statistics["nsensfcnfcns"] > 0
- @testattr(stddist = True)
def test_basicsens1dir(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "BasicSens1.fmu"), _connect_dll=False)
@@ -690,12 +655,11 @@ def d(*args, **kwargs):
opts["sensitivities"] = ["d"]
res = model.simulate(options=opts)
- nose.tools.assert_almost_equal(res.final('dx/dd'), 0.36789, 3)
+ assert res.final('dx/dd') == pytest.approx(0.36789, abs = 1e-3)
assert res.solver.statistics["nsensfcnfcns"] > 0
assert res.solver.statistics["nfcnjacs"] == 0
- @testattr(stddist = True)
def test_basicsens2(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "BasicSens2.fmu"), _connect_dll=False)
@@ -723,11 +687,10 @@ def d(*args, **kwargs):
opts["sensitivities"] = ["d"]
res = model.simulate(options=opts)
- nose.tools.assert_almost_equal(res.final('dx/dd'), 0.36789, 3)
+ assert res.final('dx/dd') == pytest.approx(0.36789, abs = 1e-3)
assert res.solver.statistics["nsensfcnfcns"] == 0
- @testattr(stddist = True)
def test_relative_tolerance(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "NoState.Example1.fmu"), _connect_dll=False)
@@ -738,7 +701,6 @@ def test_relative_tolerance(self):
assert res.options["CVode_options"]["atol"] == 1e-10
- @testattr(stddist = True)
def test_simulate_with_debug_option_no_state(self):
""" Verify that an instance of CVodeDebugInformation is created """
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "NoState.Example1.fmu"), _connect_dll=False)
@@ -753,7 +715,6 @@ def test_simulate_with_debug_option_no_state(self):
from pyfmi.debug import CVodeDebugInformation
debug = CVodeDebugInformation("NoState_Example1_debug.txt")
- @testattr(stddist = True)
def test_maxord_is_set(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "NoState.Example1.fmu"), _connect_dll=False)
opts = model.simulate_options()
@@ -764,7 +725,6 @@ def test_maxord_is_set(self):
assert res.solver.maxord == 1
- @testattr(stddist = True)
def test_with_jacobian_option(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "NoState.Example1.fmu"), _connect_dll=False)
opts = model.simulate_options()
@@ -793,7 +753,6 @@ def run_case(expected, default="Default"):
opts["with_jacobian"] = True
run_case(True, True)
- @testattr(stddist = True)
def test_sparse_option(self):
def run_case(expected_jacobian, expected_sparse, fnbr=0, nnz={}, set_sparse=False):
@@ -819,13 +778,11 @@ def get_derivatives_dependencies(self):
run_case(True, "SPARSE", PYFMI_JACOBIAN_SPARSE_SIZE_LIMIT+1, {"Dep": [1]*PYFMI_JACOBIAN_SPARSE_SIZE_LIMIT})
run_case(True, "SPARSE", PYFMI_JACOBIAN_SPARSE_SIZE_LIMIT+1, {"Dep": [1]*PYFMI_JACOBIAN_SPARSE_SIZE_LIMIT}, True)
- @testattr(stddist = True)
def test_ncp_option(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "NoState.Example1.fmu"), _connect_dll=False)
opts = model.simulate_options()
assert opts["ncp"] == 500, opts["ncp"]
- @testattr(stddist = True)
def test_solver_options(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "NoState.Example1.fmu"), _connect_dll=False)
opts = model.simulate_options()
@@ -840,7 +797,6 @@ def test_solver_options(self):
assert opts["CVode_options"]["atol"] == "Default", "Default should have been changed: " + opts["CVode_options"]["atol"]
assert opts["CVode_options"]["maxh"] == 1.0, "Value should have been changed to 1.0: " + opts["CVode_options"]["maxh"]
- @testattr(stddist = True)
def test_solver_options_using_defaults(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "NoState.Example1.fmu"), _connect_dll=False)
opts = model.simulate_options()
@@ -853,7 +809,6 @@ def test_solver_options_using_defaults(self):
assert opts["CVode_options"]["atol"] == 1e-6, "Default should have been changed: " + opts["CVode_options"]["atol"]
assert opts["CVode_options"]["maxh"] == "Default", "Value should have been default is: " + opts["CVode_options"]["maxh"]
- @testattr(stddist = True)
def test_deepcopy_option(self):
opts = AssimuloFMIAlgOptions()
opts["CVode_options"]["maxh"] = 2.0
@@ -864,7 +819,6 @@ def test_deepcopy_option(self):
assert opts["CVode_options"]["maxh"] == opts_copy["CVode_options"]["maxh"], "Deepcopy not working..."
- @testattr(stddist = True)
def test_maxh_option(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "NoState.Example1.fmu"), _connect_dll=False)
opts = model.simulate_options()
@@ -895,7 +849,6 @@ def run_case(tstart, tstop, solver, ncp="Default"):
run_case(0,1,"LSODAR")
run_case(0,1,"LSODAR")
- @testattr(stddist = True)
def test_rtol_auto_update(self):
""" Test that default rtol picks up the unbounded attribute. """
model = Dummy_FMUModelME2([], FMU_PATHS.ME2.coupled_clutches_modified, _connect_dll=False)
@@ -907,13 +860,12 @@ def test_rtol_auto_update(self):
if res.solver.supports.get('rtol_as_vector', False):
# automatic construction of rtol vector
if model.get_variable_unbounded(state):
- nose.tools.assert_equal(res.solver.rtol[i], 0)
+ assert res.solver.rtol[i] == 0
else:
- nose.tools.assert_greater(res.solver.rtol[i], 0)
+ assert res.solver.rtol[i] > 0
else: # no support: scalar rtol
- nose.tools.assert_true(isinstance(res.solver.rtol, float))
+ assert isinstance(res.solver.rtol, float)
- @testattr(stddist = True)
def test_rtol_vector_manual_valid(self):
""" Tests manual valid rtol vector works; if supported. """
@@ -925,12 +877,11 @@ def test_rtol_vector_manual_valid(self):
try:
res = model.simulate(options=opts)
# solver support
- nose.tools.assert_equal(res.solver.rtol[0], 1e-5)
- nose.tools.assert_equal(res.solver.rtol[1], 0.)
+ assert res.solver.rtol[0] == 1e-5
+ assert res.solver.rtol[1] == 0.
except InvalidOptionException as e: # if no solver support
- nose.tools.assert_true(str(e).startswith("Failed to set the solver option 'rtol'"))
+ assert str(e).startswith("Failed to set the solver option 'rtol'")
- @testattr(stddist = True)
def test_rtol_vector_manual_size_mismatch(self):
""" Tests invalid rtol vector: size mismatch. """
model = Dummy_FMUModelME2([], FMU_PATHS.ME2.nominal_test4, _connect_dll=False)
@@ -939,10 +890,9 @@ def test_rtol_vector_manual_size_mismatch(self):
opts["CVode_options"]["rtol"] = [1e-5, 0, 1e-5]
err_msg = "If the relative tolerance is provided as a vector, it need to be equal to the number of states."
- with nose.tools.assert_raises_regex(InvalidOptionException, err_msg):
+ with pytest.raises(InvalidOptionException, match = err_msg):
model.simulate(options=opts)
- @testattr(stddist = True)
def test_rtol_vector_manual_invalid(self):
""" Tests invalid rtol vector: different nonzero values. """
@@ -952,10 +902,9 @@ def test_rtol_vector_manual_invalid(self):
opts["CVode_options"]["rtol"] = [1e-5, 0, 1e-5, 1e-5, 0, 1e-5,1e-6, 0]
err_msg = "If the relative tolerance is provided as a vector, the values need to be equal except for zeros."
- with nose.tools.assert_raises_regex(InvalidOptionException, err_msg):
+ with pytest.raises(InvalidOptionException, match = err_msg):
model.simulate(options=opts)
- @testattr(stddist = True)
def test_rtol_vector_manual_scalar_conversion(self):
""" Test automatic scalar conversion of trivial rtol vector. """
model = Dummy_FMUModelME2([], FMU_PATHS.ME2.nominal_test4, _connect_dll=False)
@@ -965,9 +914,8 @@ def test_rtol_vector_manual_scalar_conversion(self):
#Verify no exception is raised as the rtol vector should be treated as a scalar
res = model.simulate(options=opts)
- nose.tools.assert_equal(res.solver.rtol, 1e-5)
+ assert res.solver.rtol == 1e-5
- @testattr(stddist = True)
def test_rtol_vector_unsupported(self):
""" Test that rtol as a vector triggers exceptions for unsupported solvers. """
model = Dummy_FMUModelME2([], FMU_PATHS.ME2.nominal_test4, _connect_dll=False)
@@ -983,10 +931,10 @@ def run_case(solver):
try:
res = model.simulate(options=opts)
# solver support; check tolerances
- nose.tools.assert_equal(res.solver.rtol[0], 1e-5)
- nose.tools.assert_equal(res.solver.rtol[1], 0.0)
+ assert res.solver.rtol[0] == 1e-5
+ assert res.solver.rtol[1] == 0.0
except InvalidOptionException as e:
- nose.tools.assert_true(str(e).startswith("Failed to set the solver option 'rtol'"))
+ assert str(e).startswith("Failed to set the solver option 'rtol'")
return # OK
run_case("CVode")
@@ -1003,7 +951,6 @@ def setup_atol_auto_update_test_base(self):
opts["solver"] = "CVode"
return model, opts
- @testattr(stddist = True)
def test_atol_auto_update1(self):
"""
Tests that atol automatically gets updated when "atol = factor * pre_init_nominals".
@@ -1015,7 +962,6 @@ def test_atol_auto_update1(self):
model.simulate(options=opts, algorithm=NoSolveAlg)
np.testing.assert_allclose(opts["CVode_options"]["atol"], [0.03, 0.03])
- @testattr(stddist = True)
def test_atol_auto_update2(self):
"""
Tests that atol doesn't get auto-updated when heuristic fails.
@@ -1027,7 +973,6 @@ def test_atol_auto_update2(self):
model.simulate(options=opts, algorithm=NoSolveAlg)
np.testing.assert_allclose(opts["CVode_options"]["atol"], [0.03, 0.02])
- @testattr(stddist = True)
def test_atol_auto_update3(self):
"""
Tests that atol doesn't get auto-updated when nominals are never retrieved.
@@ -1039,7 +984,6 @@ def test_atol_auto_update3(self):
model.simulate(options=opts, algorithm=NoSolveAlg)
np.testing.assert_allclose(opts["CVode_options"]["atol"], [0.02, 0.01])
- @testattr(stddist = True)
def test_atol_auto_update4(self):
"""
Tests that atol is not auto-updated when it's set the "correct" way (post initialization).
@@ -1054,7 +998,6 @@ def test_atol_auto_update4(self):
model.simulate(options=opts, algorithm=NoSolveAlg)
np.testing.assert_allclose(opts["CVode_options"]["atol"], [0.03, 0.03])
- @testattr(stddist = True)
def test_atol_auto_update5(self):
"""
Tests that atol is automatically set and depends on rtol.
@@ -1065,7 +1008,6 @@ def test_atol_auto_update5(self):
model.simulate(options=opts, algorithm=NoSolveAlg)
np.testing.assert_allclose(opts["CVode_options"]["atol"], [3e-8, 3e-8])
- @testattr(stddist = True)
def test_atol_auto_update6(self):
"""
Tests that rtol doesn't affect explicitly set atol.
@@ -1080,8 +1022,6 @@ def test_atol_auto_update6(self):
class Test_FMUModelME2:
-
- @testattr(stddist = True)
def test_unzipped_fmu_exception_invalid_dir(self):
""" Verify that we get an exception if unzipped FMU does not contain modelDescription.xml, which it should according to the FMI specification. """
_helper_unzipped_fmu_exception_invalid_dir(FMUModelME2)
@@ -1099,36 +1039,30 @@ def _test_unzipped_bouncing_ball(self, fmu_loader):
value = np.abs(res.final('h') - (0.0424044))
assert value < tol, "Assertion failed, value={} is not less than {}.".format(value, tol)
- @testattr(stddist = True)
def test_unzipped_fmu1(self):
""" Test load and simulate unzipped ME FMU 2.0 using FMUModelME2 """
self._test_unzipped_bouncing_ball(FMUModelME2)
- @testattr(stddist = True)
def test_unzipped_fmu2(self):
""" Test load and simulate unzipped ME FMU 2.0 using load_fmu """
self._test_unzipped_bouncing_ball(load_fmu)
- @testattr(stddist = True)
def test_unzipped_fmu_exceptions(self):
""" Verify exception is raised if 'fmu' is a file and allow_unzipped_fmu is set to True, with FMUModelME2. """
err_msg = "Argument named 'fmu' must be a directory if argument 'allow_unzipped_fmu' is set to True."
- with nose.tools.assert_raises_regex(FMUException, err_msg):
+ with pytest.raises(FMUException, match = err_msg):
model = FMUModelME2(os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "LinearStability.SubSystem2.fmu"), _connect_dll=False, allow_unzipped_fmu=True)
- @testattr(stddist = True)
def test_invalid_binary(self):
err_msg = "The FMU could not be loaded."
- with nose.tools.assert_raises_regex(InvalidBinaryException, err_msg):
+ with pytest.raises(InvalidBinaryException, match = err_msg):
model = FMUModelME2(os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "LinearStability.SubSystem2.fmu"), _connect_dll=True)
- @testattr(stddist = True)
def test_invalid_version(self):
err_msg = "The FMU version is not supported by this class"
- with nose.tools.assert_raises_regex(InvalidVersionException, err_msg):
+ with pytest.raises(InvalidVersionException, match = err_msg):
model = FMUModelME2(os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "RLC_Circuit.fmu"), _connect_dll=True)
- @testattr(stddist = True)
def test_estimate_directional_derivatives_linearstate(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "LinearStateSpace.fmu"), _connect_dll=False)
@@ -1158,7 +1092,6 @@ def f(*args, **kwargs):
assert np.allclose(Cs, C.toarray()), str(Cs)+' '+str(C.toarray())
assert np.allclose(Ds, D.toarray()), str(Ds)+' '+str(D.toarray())
- @testattr(stddist = True)
def test_estimate_directional_derivatives_without_structure_info(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "Bouncing_Ball.fmu"), _connect_dll=False)
@@ -1186,7 +1119,6 @@ def f(*args, **kwargs):
assert np.allclose(Cs, C.toarray()), str(Cs)+' '+str(C.toarray())
assert np.allclose(Ds, D.toarray()), str(Ds)+' '+str(D.toarray())
- @testattr(stddist = True)
def test_estimate_directional_derivatives_BCD(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "OutputTest2.fmu"), _connect_dll=False)
@@ -1242,7 +1174,6 @@ def f(*args, **kwargs):
assert np.allclose(C, np.array([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0]])), str(C.toarray())
assert np.allclose(D, np.array([[-1.0], [0.0], [1.0]])), str(D.toarray())
- @testattr(stddist = True)
def test_output_dependencies(self):
model = FMUModelME2(os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "OutputTest2.fmu"), _connect_dll=False)
@@ -1256,7 +1187,6 @@ def test_output_dependencies(self):
assert input_dep["y3"][0] == "u1"
assert len(input_dep["y2"]) == 0
- @testattr(stddist = True)
def test_output_dependencies_2(self):
model = FMUModelME2(FMU_PATHS.ME2.coupled_clutches, _connect_dll=False)
@@ -1265,7 +1195,6 @@ def test_output_dependencies_2(self):
assert len(state_dep.keys()) == 0, len(state_dep.keys())
assert len(input_dep.keys()) == 0, len(input_dep.keys())
- @testattr(stddist = True)
def test_derivative_dependencies(self):
model = FMUModelME2(os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "NoState.Example1.fmu"), _connect_dll=False)
@@ -1274,7 +1203,6 @@ def test_derivative_dependencies(self):
assert len(state_dep.keys()) == 0, len(state_dep.keys())
assert len(input_dep.keys()) == 0, len(input_dep.keys())
- @testattr(stddist = True)
def test_exception_with_load_fmu(self):
""" Verify exception is raised. """
err_msg = "Argument named 'fmu' must be a directory if argument 'allow_unzipped_fmu' is set to True."
@@ -1284,16 +1212,15 @@ def test_exception_with_load_fmu(self):
with open(test_file, 'w') as fh:
fh.write('')
rm_file = True
- with nose.tools.assert_raises_regex(FMUException, err_msg):
+ with pytest.raises(FMUException, match = err_msg):
fmu = load_fmu(test_file, allow_unzipped_fmu = True)
if rm_file:
os.remove(test_file)
- @testattr(stddist = True)
def test_malformed_xml(self):
- nose.tools.assert_raises(InvalidXMLException, load_fmu, os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "MalFormed.fmu"))
+ with pytest.raises(InvalidXMLException):
+ load_fmu(os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "MalFormed.fmu"))
- @testattr(stddist = True)
def test_log_file_name(self):
full_path = FMU_PATHS.ME2.coupled_clutches
@@ -1302,25 +1229,26 @@ def test_log_file_name(self):
path, file_name = os.path.split(full_path)
assert model.get_log_filename() == file_name.replace(".","_")[:-4]+"_log.txt"
- @testattr(stddist = True)
def test_units(self):
model = FMUModelME2(FMU_PATHS.ME2.coupled_clutches, _connect_dll=False)
assert model.get_variable_unit("J1.w") == "rad/s", model.get_variable_unit("J1.w")
assert model.get_variable_unit("J1.phi") == "rad", model.get_variable_unit("J1.phi")
- nose.tools.assert_raises(FMUException, model.get_variable_unit, "clutch1.useHeatPort")
- nose.tools.assert_raises(FMUException, model.get_variable_unit, "clutch1.sss")
- nose.tools.assert_raises(FMUException, model.get_variable_unit, "clutch1.sss")
+ with pytest.raises(FMUException):
+ model.get_variable_unit("clutch1.useHeatPort")
+ with pytest.raises(FMUException):
+ model.get_variable_unit("clutch1.sss")
+ with pytest.raises(FMUException):
+ model.get_variable_unit("clutch1.sss")
- @testattr(stddist = True)
def test_display_units(self):
model = FMUModelME2(FMU_PATHS.ME2.coupled_clutches, _connect_dll=False)
assert model.get_variable_display_unit("J1.phi") == "deg", model.get_variable_display_unit("J1.phi")
- nose.tools.assert_raises(FMUException, model.get_variable_display_unit, "J1.w")
+ with pytest.raises(FMUException):
+ model.get_variable_display_unit("J1.w")
- @testattr(stddist = True)
def test_get_xxx_empty(self):
""" Test that get_xxx([]) do not calls do not trigger calls to FMU. """
model = FMUModelME2(os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "bouncingBall.fmu"), _connect_dll=False)
@@ -1331,8 +1259,6 @@ def test_get_xxx_empty(self):
assert len(model.get_string([])) == 0, "get_string ([]) has non-empty return"
class Test_FMUModelBase2:
-
- @testattr(stddist = True)
def test_relative_quantity(self):
model = FMUModelME2(os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "test_type_definitions.fmu"), _connect_dll=False)
@@ -1347,9 +1273,9 @@ def test_relative_quantity(self):
rel = model.get_variable_relative_quantity("real_with_typedef")
assert rel is True, "Relative quantity should be True"
- nose.tools.assert_raises(FMUException, model.get_variable_relative_quantity, "int_with_attr")
+ with pytest.raises(FMUException):
+ model.get_variable_relative_quantity("int_with_attr")
- @testattr(stddist = True)
def test_unbounded_attribute(self):
model = FMUModelME2(os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "test_type_definitions.fmu"), _connect_dll=False)
@@ -1364,9 +1290,9 @@ def test_unbounded_attribute(self):
unbounded = model.get_variable_unbounded("real_with_typedef")
assert unbounded is True, "Unbounded should be True"
- nose.tools.assert_raises(FMUException, model.get_variable_unbounded, "int_with_attr")
+ with pytest.raises(FMUException):
+ model.get_variable_unbounded("int_with_attr")
- @testattr(stddist = True)
def test_unicode_description(self):
model = FMUModelME2(os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "Description.fmu"), _connect_dll=False)
@@ -1374,7 +1300,6 @@ def test_unicode_description(self):
assert desc == "Test symbols '' ‘’"
- @testattr(stddist = True)
def test_declared_enumeration_type(self):
model = FMUModelME2(os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "Enumerations.Enumeration3.fmu"), _connect_dll=False)
@@ -1387,26 +1312,26 @@ def test_declared_enumeration_type(self):
assert enum.name == "Enumerations.Enumeration3.cities", "Got: " + enum.name
assert enum.description == "", "Got: " + enum.description
- nose.tools.assert_raises(FMUException, model.get_variable_declared_type, "z")
+ with pytest.raises(FMUException):
+ model.get_variable_declared_type("z")
- @testattr(stddist = True)
def test_get_erroneous_nominals_xml(self):
model = FMUModelME2(FMU_PATHS.ME2.nominal_test4, _connect_dll=False)
- nose.tools.assert_almost_equal(model.get_variable_nominal("x"), 2.0)
- nose.tools.assert_almost_equal(model.get_variable_nominal("y"), 1.0)
+ assert model.get_variable_nominal("x") == pytest.approx(2.0)
+ assert model.get_variable_nominal("y") == pytest.approx(1.0)
- nose.tools.assert_almost_equal(model.get_variable_nominal("x", _override_erroneous_nominal=False), -2.0)
- nose.tools.assert_almost_equal(model.get_variable_nominal("y", _override_erroneous_nominal=False), 0.0)
+ assert model.get_variable_nominal("x", _override_erroneous_nominal=False) == pytest.approx(-2.0)
+ assert model.get_variable_nominal("y", _override_erroneous_nominal=False) == pytest.approx(0.0)
x_vref = model.get_variable_valueref("x")
y_vref = model.get_variable_valueref("y")
- nose.tools.assert_almost_equal(model.get_variable_nominal(valueref=x_vref), 2.0)
- nose.tools.assert_almost_equal(model.get_variable_nominal(valueref=y_vref), 1.0)
+ assert model.get_variable_nominal(valueref=x_vref) == pytest.approx(2.0)
+ assert model.get_variable_nominal(valueref=y_vref) == pytest.approx(1.0)
- nose.tools.assert_almost_equal(model.get_variable_nominal(valueref=x_vref, _override_erroneous_nominal=False), -2.0)
- nose.tools.assert_almost_equal(model.get_variable_nominal(valueref=y_vref, _override_erroneous_nominal=False), 0.0)
+ assert model.get_variable_nominal(valueref=x_vref, _override_erroneous_nominal=False) == pytest.approx(-2.0)
+ assert model.get_variable_nominal(valueref=y_vref, _override_erroneous_nominal=False) == pytest.approx(0.0)
def test_get_erroneous_nominals_capi(self):
""" Tests that erroneous nominals returned from GetNominalsOfContinuousStates get auto-corrected. """
@@ -1435,20 +1360,19 @@ def test_get_erroneous_nominals_capi(self):
expected_msg2 = "The nominal value for J4.w is 0.0 which is illegal according to the " \
+ "FMI specification. Setting the nominal to 1.0."
log = str(log_stream.getvalue())
- nose.tools.assert_in(expected_msg1, log) # First warning of 6.
- nose.tools.assert_in(expected_msg2, log) # Last warning of 6.
+ assert expected_msg1 in log # First warning of 6.
+ assert expected_msg2 in log # Last warning of 6.
# Check that values are auto-corrected:
- nose.tools.assert_almost_equal(xn[0], 2.0) # -2.0
- nose.tools.assert_almost_equal(xn[1], 1.0) # 0.0
- nose.tools.assert_almost_equal(xn[2], 2.0) # 2.0
- nose.tools.assert_almost_equal(xn[3], 2.0) # -2.0
- nose.tools.assert_almost_equal(xn[4], 1.0) # 0.0
- nose.tools.assert_almost_equal(xn[5], 2.0) # 2.0
- nose.tools.assert_almost_equal(xn[6], 2.0) # -2.0
- nose.tools.assert_almost_equal(xn[7], 1.0) # 0,0
-
- @testattr(stddist = True)
+ assert xn[0] == pytest.approx(2.0)
+ assert xn[1] == pytest.approx(1.0)
+ assert xn[2] == pytest.approx(2.0)
+ assert xn[3] == pytest.approx(2.0)
+ assert xn[4] == pytest.approx(1.0)
+ assert xn[5] == pytest.approx(2.0)
+ assert xn[6] == pytest.approx(2.0)
+ assert xn[7] == pytest.approx(1.0)
+
def test_get_time_varying_variables(self):
model = FMUModelME2(FMU_PATHS.ME2.coupled_clutches, _connect_dll=False)
@@ -1467,38 +1391,39 @@ def test_get_time_varying_variables(self):
[r,i,b] = model.get_model_time_varying_value_references(filter=list(vars.keys()))
assert len(r) == 1, len(r)
- @testattr(stddist = True)
def test_get_directional_derivative_capability(self):
bounce = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "bouncingBall.fmu"), _connect_dll=False)
bounce.setup_experiment()
bounce.initialize()
# Bouncing ball don't have the capability, check that this is handled
- nose.tools.assert_raises(FMUException, bounce.get_directional_derivative, [1], [1], [1])
+ with pytest.raises(FMUException):
+ bounce.get_directional_derivative([1], [1], [1])
bounce = Dummy_FMUModelCS2([], os.path.join(file_path, "files", "FMUs", "XML", "CS2.0", "bouncingBall.fmu"), _connect_dll=False)
bounce.setup_experiment()
bounce.initialize()
# Bouncing ball don't have the capability, check that this is handled
- nose.tools.assert_raises(FMUException, bounce.get_directional_derivative, [1], [1], [1])
+ with pytest.raises(FMUException):
+ bounce.get_directional_derivative([1], [1], [1])
- @testattr(stddist = True)
def test_simulation_without_initialization(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "bouncingBall.fmu"), _connect_dll=False)
opts = model.simulate_options()
opts["initialize"] = False
- nose.tools.assert_raises(FMUException, model.simulate, options=opts)
+ with pytest.raises(FMUException):
+ model.simulate(options=opts)
model = Dummy_FMUModelCS2([], os.path.join(file_path, "files", "FMUs", "XML", "CS2.0", "bouncingBall.fmu"), _connect_dll=False)
opts = model.simulate_options()
opts["initialize"] = False
- nose.tools.assert_raises(FMUException, model.simulate, options=opts)
+ with pytest.raises(FMUException):
+ model.simulate(options=opts)
- @testattr(stddist = True)
- def test_simulation_with_syncronization_exception_ME(self):
+ def test_simulation_with_synchronization_exception_ME(self):
"""
Verifies the allowed values for the option to synchronize simulations (ME)
"""
@@ -1506,16 +1431,17 @@ def test_simulation_with_syncronization_exception_ME(self):
opts = model.simulate_options()
opts["synchronize_simulation"] = "Hej"
- nose.tools.assert_raises(InvalidOptionException, model.simulate, options=opts)
+ with pytest.raises(InvalidOptionException):
+ model.simulate(options=opts)
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "bouncingBall.fmu"), _connect_dll=False)
opts = model.simulate_options()
opts["synchronize_simulation"] = -1.0
- nose.tools.assert_raises(InvalidOptionException, model.simulate, options=opts)
+ with pytest.raises(InvalidOptionException):
+ model.simulate(options=opts)
- @testattr(stddist = True)
- def test_simulation_with_syncronization_exception_CS(self):
+ def test_simulation_with_synchronization_exception_CS(self):
"""
Verifies the allowed values for the option to synchronize simulations (CS)
"""
@@ -1523,16 +1449,17 @@ def test_simulation_with_syncronization_exception_CS(self):
opts = model.simulate_options()
opts["synchronize_simulation"] = "Hej"
- nose.tools.assert_raises(InvalidOptionException, model.simulate, options=opts)
+ with pytest.raises(InvalidOptionException):
+ model.simulate(options=opts)
model = Dummy_FMUModelCS2([], os.path.join(file_path, "files", "FMUs", "XML", "CS2.0", "bouncingBall.fmu"), _connect_dll=False)
opts = model.simulate_options()
opts["synchronize_simulation"] = -1.0
- nose.tools.assert_raises(InvalidOptionException, model.simulate, options=opts)
+ with pytest.raises(InvalidOptionException):
+ model.simulate(options=opts)
- @testattr(stddist = True)
- def test_simulation_with_syncronization_ME(self):
+ def test_simulation_with_synchronization_ME(self):
"""
Verifies that the option synchronize simulation works as intended in the most basic test for ME FMUs.
"""
@@ -1550,11 +1477,10 @@ def test_simulation_with_syncronization_ME(self):
res = model.simulate(final_time=0.1, options=opts)
tsyn = res.detailed_timings["computing_solution"]
- assert tsyn > t, "Syncronization does not work: %d, %d"%(t, tsyn)
+ assert tsyn > t, "synchronization does not work: %d, %d"%(t, tsyn)
- @testattr(stddist = True)
- def test_simulation_with_syncronization_CS(self):
+ def test_simulation_with_synchronization_CS(self):
"""
Verifies that the option synchronize simulation works as intended in the most basic test for CS FMUs.
"""
@@ -1572,9 +1498,8 @@ def test_simulation_with_syncronization_CS(self):
res = model.simulate(final_time=0.1, options=opts)
tsyn = res.detailed_timings["computing_solution"]
- assert tsyn > t, "Syncronization does not work: %d, %d"%(t, tsyn)
+ assert tsyn > t, "synchronization does not work: %d, %d"%(t, tsyn)
- @testattr(stddist = True)
def test_caching(self):
negated_alias = FMUModelME2(os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "NegatedAlias.fmu"), _connect_dll=False)
@@ -1602,7 +1527,6 @@ def test_caching(self):
vars_6 = negated_alias.get_model_variables()
assert id(vars_1) != id(vars_6)
- @testattr(stddist = True)
def test_get_scalar_variable(self):
negated_alias = FMUModelME2(os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "NegatedAlias.fmu"), _connect_dll=False)
@@ -1615,38 +1539,33 @@ def test_get_scalar_variable(self):
assert sc_x.causality == fmi.FMI2_LOCAL, sc_x.causality
assert sc_x.initial == fmi.FMI2_INITIAL_APPROX, sc_x.initial
- nose.tools.assert_raises(FMUException, negated_alias.get_scalar_variable, "not_existing")
+ with pytest.raises(FMUException):
+ negated_alias.get_scalar_variable("not_existing")
- @testattr(stddist = True)
def test_get_variable_description(self):
model = FMUModelME2(FMU_PATHS.ME2.coupled_clutches, _connect_dll=False)
assert model.get_variable_description("J1.phi") == "Absolute rotation angle of component"
class Test_load_fmu_only_XML:
-
- @testattr(stddist = True)
def test_loading_xml_me1(self):
model = FMUModelME1(FMU_PATHS.ME1.coupled_clutches, _connect_dll=False)
assert model.get_name() == "CoupledClutches", model.get_name()
- @testattr(stddist = True)
def test_loading_xml_cs1(self):
model = FMUModelCS1(os.path.join(file_path, "files", "FMUs", "XML", "CS1.0", "CoupledClutches.fmu"), _connect_dll=False)
assert model.get_name() == "CoupledClutches", model.get_name()
- @testattr(stddist = True)
def test_loading_xml_me2(self):
model = FMUModelME2(FMU_PATHS.ME2.coupled_clutches, _connect_dll=False)
assert model.get_name() == "CoupledClutches", model.get_name()
- @testattr(stddist = True)
def test_loading_xml_cs2(self):
model = FMUModelCS2(os.path.join(file_path, "files", "FMUs", "XML", "CS2.0", "CoupledClutches.fmu"), _connect_dll=False)
diff --git a/tests/test_fmi_coupled.py b/tests/test_fmi_coupled.py
index b1b622a8..08899f8a 100644
--- a/tests/test_fmi_coupled.py
+++ b/tests/test_fmi_coupled.py
@@ -15,10 +15,9 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-import nose
+import pytest
import os
-from pyfmi import testattr
from pyfmi.fmi import FMUModelME2
from pyfmi.fmi_coupled import CoupledFMUModelME2
import pyfmi.fmi as fmi
@@ -36,7 +35,6 @@
if assimulo_installed:
class Test_CoupledFMUModelME2_Simulation:
- @testattr(stddist = True)
def test_linear_example(self):
model_sub_1 = Dummy_FMUModelME2([], os.path.join(me2_xml_path, "LinearStability.SubSystem1.fmu"), _connect_dll=False)
model_sub_2 = Dummy_FMUModelME2([], os.path.join(me2_xml_path, "LinearStability.SubSystem2.fmu"), _connect_dll=False)
@@ -76,20 +74,18 @@ def sub2(*args, **kwargs):
res = coupled.simulate(options=opts)
- nose.tools.assert_almost_equal(res.final("First.x1"),0.08597302307099872)
- nose.tools.assert_almost_equal(res.final("Second.x2"),0.0083923348082567)
- nose.tools.assert_almost_equal(res.initial("First.x1"),1.0)
- nose.tools.assert_almost_equal(res.initial("Second.x2"),1.0)
+ assert res.final("First.x1") == pytest.approx(0.08597302307099872)
+ assert res.final("Second.x2") == pytest.approx(0.0083923348082567)
+ assert res.initial("First.x1") == pytest.approx(1.0)
+ assert res.initial("Second.x2") == pytest.approx(1.0)
- nose.tools.assert_almost_equal(res.final("First.u1"),-0.25909975860402856)
- nose.tools.assert_almost_equal(res.final("Second.u2"),-0.0011806893910324295)
- nose.tools.assert_almost_equal(res.initial("First.u1"),-17.736842105263158)
- nose.tools.assert_almost_equal(res.initial("Second.u2"),-14.73684210526316)
+ assert res.final("First.u1") == pytest.approx(-0.25909975860402856)
+ assert res.final("Second.u2") == pytest.approx(-0.0011806893910324295)
+ assert res.initial("First.u1") == pytest.approx(-17.736842105263158)
+ assert res.initial("Second.u2") == pytest.approx(-14.73684210526316)
class Test_CoupledFMUModelME2:
-
- @testattr(stddist = True)
def test_reversed_connections(self):
model_sub_1 = FMUModelME2(os.path.join(me2_xml_path, "LinearStability.SubSystem1.fmu"), _connect_dll=False)
model_sub_2 = FMUModelME2(os.path.join(me2_xml_path, "LinearStability.SubSystem2.fmu"), _connect_dll=False)
@@ -99,16 +95,16 @@ def test_reversed_connections(self):
connections = [(model_sub_2,"y1",model_sub_1,"u2"),
(model_sub_1,"y2",model_sub_2,"u1")]
- nose.tools.assert_raises(fmi.FMUException, CoupledFMUModelME2, models, connections)
+ with pytest.raises(fmi.FMUException):
+ CoupledFMUModelME2(models, connections)
connections = [(model_sub_2,"u2",model_sub_1,"y1"),
(model_sub_1,"u1",model_sub_2,"y2")]
- nose.tools.assert_raises(fmi.FMUException, CoupledFMUModelME2, models, connections)
+ with pytest.raises(fmi.FMUException):
+ CoupledFMUModelME2(models, connections)
- @testattr(stddist = True)
def test_inputs_list(self):
-
model_sub_1 = FMUModelME2(os.path.join(me2_xml_path, "LinearStability.SubSystem1.fmu"), _connect_dll=False)
model_sub_2 = FMUModelME2(os.path.join(me2_xml_path, "LinearStability.SubSystem2.fmu"), _connect_dll=False)
model_full = FMUModelME2(os.path.join(me2_xml_path, "LinearStability.FullSystem.fmu"), _connect_dll=False)
@@ -128,7 +124,6 @@ def test_inputs_list(self):
assert "First.u1" in vars
assert "Second.u2" in vars
- @testattr(stddist = True)
def test_alias(self):
model_cc_1 = FMUModelME2(os.path.join(me2_xml_path, "CoupledClutches.fmu"), _connect_dll=False)
model_cc_2 = FMUModelME2(os.path.join(me2_xml_path, "CoupledClutches.fmu"), _connect_dll=False)
@@ -142,7 +137,6 @@ def test_alias(self):
assert "First.J4.phi" in aliases.keys()
assert coupled.get_variable_alias_base("First.J4.phi") == "First.J4.flange_a.phi"
- @testattr(stddist = True)
def test_loading(self):
model_cc_1 = FMUModelME2(os.path.join(me2_xml_path, "CoupledClutches.fmu"), _connect_dll=False)
model_cc_2 = FMUModelME2(os.path.join(me2_xml_path, "CoupledClutches.fmu"), _connect_dll=False)
@@ -150,24 +144,28 @@ def test_loading(self):
models = [model_cc_1, model_cc_2]
connections = []
- nose.tools.assert_raises(fmi.FMUException, CoupledFMUModelME2, models, connections)
+ with pytest.raises(fmi.FMUException):
+ CoupledFMUModelME2(models, connections)
models = [("First", model_cc_1), model_cc_2]
- nose.tools.assert_raises(fmi.FMUException, CoupledFMUModelME2, models, connections)
+ with pytest.raises(fmi.FMUException):
+ CoupledFMUModelME2(models, connections)
models = [("First", model_cc_1), ("First", model_cc_2)]
- nose.tools.assert_raises(fmi.FMUException, CoupledFMUModelME2, models, connections)
+ with pytest.raises(fmi.FMUException):
+ CoupledFMUModelME2(models, connections)
models = [("First", model_cc_1), ("Second", model_cc_2)]
coupled = CoupledFMUModelME2(models, connections)
connections = [("k")]
- nose.tools.assert_raises(fmi.FMUException, CoupledFMUModelME2, models, connections)
+ with pytest.raises(fmi.FMUException):
+ CoupledFMUModelME2(models, connections)
connections = [(model_cc_1, "J1.phi", model_cc_2, "J2.phi")]
- nose.tools.assert_raises(fmi.FMUException, CoupledFMUModelME2, models, connections)
+ with pytest.raises(fmi.FMUException):
+ CoupledFMUModelME2(models, connections)
- @testattr(stddist = True)
def test_get_variable_valueref(self):
model_cc_1 = FMUModelME2(os.path.join(me2_xml_path, "CoupledClutches.fmu"), _connect_dll=False)
model_cc_2 = FMUModelME2(os.path.join(me2_xml_path, "CoupledClutches.fmu"), _connect_dll=False)
@@ -177,7 +175,8 @@ def test_get_variable_valueref(self):
coupled = CoupledFMUModelME2(models, connections)
- nose.tools.assert_raises(fmi.FMUException, coupled.get_variable_valueref, "J1.w")
+ with pytest.raises(fmi.FMUException):
+ coupled.get_variable_valueref("J1.w")
vr_1 = coupled.get_variable_valueref("First.J1.w")
vr_2 = coupled.get_variable_valueref("Second.J1.w")
@@ -190,7 +189,6 @@ def test_get_variable_valueref(self):
assert var_name_1 == "First.J1.w"
assert var_name_2 == "Second.J1.w"
- @testattr(stddist = True)
def test_ode_sizes(self):
model_cc_1 = FMUModelME2(os.path.join(me2_xml_path, "CoupledClutches.fmu"), _connect_dll=False)
model_cc_2 = FMUModelME2(os.path.join(me2_xml_path, "CoupledClutches.fmu"), _connect_dll=False)
@@ -205,7 +203,6 @@ def test_ode_sizes(self):
assert nbr_states == 16
assert nbr_event_ind == 66
- @testattr(stddist = True)
def test_variable_variability(self):
model_cc_1 = FMUModelME2(os.path.join(me2_xml_path, "CoupledClutches.fmu"), _connect_dll=False)
model_cc_2 = FMUModelME2(os.path.join(me2_xml_path, "CoupledClutches.fmu"), _connect_dll=False)
@@ -215,13 +212,13 @@ def test_variable_variability(self):
coupled = CoupledFMUModelME2(models, connections)
- nose.tools.assert_raises(fmi.FMUException, coupled.get_variable_variability, "J1.w")
+ with pytest.raises(fmi.FMUException):
+ coupled.get_variable_variability("J1.w")
variability = coupled.get_variable_variability("First.J1.w")
assert variability == model_cc_1.get_variable_variability("J1.w")
- @testattr(stddist = True)
def test_variable_causality(self):
model_cc_1 = FMUModelME2(os.path.join(me2_xml_path, "CoupledClutches.fmu"), _connect_dll=False)
model_cc_2 = FMUModelME2(os.path.join(me2_xml_path, "CoupledClutches.fmu"), _connect_dll=False)
@@ -231,13 +228,13 @@ def test_variable_causality(self):
coupled = CoupledFMUModelME2(models, connections)
- nose.tools.assert_raises(fmi.FMUException, coupled.get_variable_causality, "J1.w")
+ with pytest.raises(fmi.FMUException):
+ coupled.get_variable_causality("J1.w")
causality = coupled.get_variable_causality("First.J1.w")
assert causality == model_cc_1.get_variable_causality("J1.w")
- @testattr(stddist = True)
def test_derivatives_list(self):
model_cc_1 = FMUModelME2(os.path.join(me2_xml_path, "CoupledClutches.fmu"), _connect_dll=False)
model_cc_2 = FMUModelME2(os.path.join(me2_xml_path, "CoupledClutches.fmu"), _connect_dll=False)
@@ -255,7 +252,6 @@ def test_derivatives_list(self):
alias_vars = coupled.get_variable_alias(var).keys()
assert state in alias_vars
- @testattr(stddist = True)
def test_states_list(self):
model_cc_1 = FMUModelME2(os.path.join(me2_xml_path, "CoupledClutches.fmu"), _connect_dll=False)
model_cc_2 = FMUModelME2(os.path.join(me2_xml_path, "CoupledClutches.fmu"), _connect_dll=False)
@@ -273,7 +269,6 @@ def test_states_list(self):
alias_vars = coupled.get_variable_alias(var).keys()
assert state in alias_vars
- @testattr(stddist = True)
def test_model_variables(self):
model_cc_1 = FMUModelME2(os.path.join(me2_xml_path, "CoupledClutches.fmu"), _connect_dll=False)
model_cc_2 = FMUModelME2(os.path.join(me2_xml_path, "CoupledClutches.fmu"), _connect_dll=False)
diff --git a/tests/test_fmi_estimate.py b/tests/test_fmi_estimate.py
index 0f438c09..a243b925 100644
--- a/tests/test_fmi_estimate.py
+++ b/tests/test_fmi_estimate.py
@@ -18,7 +18,6 @@
import os
import numpy as np
-from pyfmi import testattr
from pyfmi.tests.test_util import Dummy_FMUModelME2
from scipy.io.matlab.mio import loadmat
@@ -32,8 +31,6 @@
if assimulo_installed:
class Test_FMUModelME2_Estimate:
-
- @testattr(stddist = True)
def test_quadtank_estimate(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "QuadTankPack_Sim_QuadTank.fmu"), _connect_dll=False)
diff --git a/tests/test_fmi_extended.py b/tests/test_fmi_extended.py
index b0655012..f0045d89 100644
--- a/tests/test_fmi_extended.py
+++ b/tests/test_fmi_extended.py
@@ -18,7 +18,6 @@
import os
import numpy as np
-from pyfmi import testattr
from pyfmi.fmi_extended import FMUModelME1Extended
file_path = os.path.dirname(os.path.abspath(__file__))
@@ -27,14 +26,12 @@
class Test_FMUModelME1Extended:
- @testattr(stddist = True)
def test_log_file_name(self):
model = FMUModelME1Extended(os.path.join(me1_xml_path, "bouncingBall.fmu"), _connect_dll=False)
assert os.path.exists("bouncingBall_log.txt")
model = FMUModelME1Extended(os.path.join(me1_xml_path, "bouncingBall.fmu"), log_file_name="Test_log.txt", _connect_dll=False)
assert os.path.exists("Test_log.txt")
- @testattr(stddist = True)
def test_default_experiment(self):
model = FMUModelME1Extended(os.path.join(me1_xml_path, "CoupledClutches.fmu"), _connect_dll=False)
diff --git a/tests/test_fmi_master.py b/tests/test_fmi_master.py
index c8f04dc2..a0c3f9ef 100644
--- a/tests/test_fmi_master.py
+++ b/tests/test_fmi_master.py
@@ -15,11 +15,11 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-import nose
+import pytest
import os
import numpy as np
-from pyfmi import testattr, Master
+from pyfmi import Master
from pyfmi.fmi import FMUException, FMUModelCS2, FMUModelME2
from pyfmi.tests.test_util import Dummy_FMUModelCS2
from pyfmi.common.algorithm_drivers import UnrecognizedOptionError
@@ -33,8 +33,6 @@
warnings.filterwarnings("ignore")
class Test_Master:
-
- @testattr(stddist = True)
def test_loading_models(self):
model_sub1 = FMUModelCS2(os.path.join(cs2_xml_path, "LinearStability.SubSystem1.fmu"), _connect_dll=False)
model_sub2 = FMUModelCS2(os.path.join(cs2_xml_path, "LinearStability.SubSystem2.fmu"), _connect_dll=False)
@@ -46,7 +44,6 @@ def test_loading_models(self):
#Assert that loading is successful
sim = Master(models, connections)
- @testattr(stddist = True)
def test_loading_wrong_model(self):
model_sub1 = FMUModelCS2(os.path.join(cs2_xml_path, "LinearStability.SubSystem1.fmu"), _connect_dll=False)
model_sub2 = FMUModelME2(os.path.join(me2_xml_path, "LinearStability.SubSystem2.fmu"), _connect_dll=False)
@@ -55,9 +52,9 @@ def test_loading_wrong_model(self):
connections = [(model_sub1,"y1",model_sub2,"u2"),
(model_sub2,"y2",model_sub1,"u1")]
- nose.tools.assert_raises(FMUException, Master, models, connections)
+ with pytest.raises(FMUException):
+ Master(models, connections)
- @testattr(stddist = True)
def test_connection_variables(self):
model_sub1 = FMUModelCS2(os.path.join(cs2_xml_path, "LinearStability.SubSystem1.fmu"), _connect_dll=False)
model_sub2 = FMUModelCS2(os.path.join(cs2_xml_path, "LinearStability.SubSystem2.fmu"), _connect_dll=False)
@@ -68,15 +65,16 @@ def test_connection_variables(self):
connections = [(model_sub1,"y1",model_sub2,"x2"),
(model_sub2,"y2",model_sub1,"u1")]
- nose.tools.assert_raises(FMUException, Master, models, connections)
+ with pytest.raises(FMUException):
+ Master(models, connections)
#Test wrong input / output order
connections = [(model_sub2,"u2", model_sub1,"y1"),
(model_sub2,"y2",model_sub1,"u1")]
- nose.tools.assert_raises(FMUException, Master, models, connections)
+ with pytest.raises(FMUException):
+ Master(models, connections)
- @testattr(stddist = True)
def test_basic_algebraic_loop(self):
model_sub1 = FMUModelCS2(os.path.join(cs2_xml_path, "LinearStability.SubSystem1.fmu"), _connect_dll=False)
model_sub2 = FMUModelCS2(os.path.join(cs2_xml_path, "LinearStability.SubSystem2.fmu"), _connect_dll=False)
@@ -145,8 +143,8 @@ def _sim_basic_simulation(self, models, connections, opts_update):
opts.update(opts_update)
res = master.simulate(options=opts)
- nose.tools.assert_almost_equal(res[models[0]].final("x1"), 0.0859764038708439, 3)
- nose.tools.assert_almost_equal(res[models[1]].final("x2"), 0.008392664839635064, 4)
+ assert res[models[0]].final("x1") == pytest.approx(0.0859764038708439, abs = 1e-3)
+ assert res[models[1]].final("x2") == pytest.approx(0.008392664839635064, abs = 1e-4)
return res
@@ -155,17 +153,14 @@ def _basic_simulation(self, opts_update):
self._sim_basic_simulation(models, connections, opts_update)
- @testattr(stddist = True)
def test_basic_simulation_txt_file(self):
opts = {"result_handling":"file"}
self._basic_simulation(opts)
- @testattr(stddist = True)
def test_basic_simulation_mat_file(self):
opts = {"result_handling":"binary"}
self._basic_simulation(opts)
- @testattr(stddist = True)
def test_basic_simulation_mat_file_naming(self):
opts = {"result_handling":"binary", "result_file_name": "Should fail..."}
@@ -181,7 +176,6 @@ def test_basic_simulation_mat_file_naming(self):
except UnrecognizedOptionError:
pass
- @testattr(stddist = True)
def test_basic_simulation_mat_file_naming_exists(self):
models, connections = self._load_basic_simulation()
@@ -192,7 +186,6 @@ def test_basic_simulation_mat_file_naming_exists(self):
assert os.path.isfile("Test1.mat"), "Test1.mat does not exists"
assert os.path.isfile("Test2.mat"), "Test2.mat does not exists"
- @testattr(stddist = True)
def test_basic_simulation_txt_file_naming_exists(self):
models, connections = self._load_basic_simulation()
@@ -203,12 +196,10 @@ def test_basic_simulation_txt_file_naming_exists(self):
assert os.path.isfile("Test1.txt"), "Test1.txt does not exists"
assert os.path.isfile("Test2.txt"), "Test2.txt does not exists"
- @testattr(stddist = True)
def test_basic_simulation_with_block_initialization(self):
opts = {"block_initialization": True}
self._basic_simulation(opts)
- @testattr(stddist = True)
def test_integer_connections(self):
model_sub1 = Dummy_FMUModelCS2([], os.path.join(cs2_xml_path, "IntegerStep.fmu"), _connect_dll=False)
model_sub2 = Dummy_FMUModelCS2([], os.path.join(cs2_xml_path, "GainTestInteger.fmu"), _connect_dll=False)
@@ -241,7 +232,6 @@ def do_step2(current_t, step_size, new_step=True):
assert res[model_sub2]["u"][0] == 1
assert res[model_sub2]["u"][-1] == 3
- @testattr(stddist = True)
def test_integer_to_real_connections(self):
model_sub1 = Dummy_FMUModelCS2([], os.path.join(cs2_xml_path, "IntegerStep.fmu"), _connect_dll=False)
model_sub2 = Dummy_FMUModelCS2([], os.path.join(cs2_xml_path, "GainTestReal.fmu"), _connect_dll=False)
@@ -274,7 +264,6 @@ def do_step2(current_t, step_size, new_step=True):
assert res[model_sub2]["u"][0] == 1.0
assert res[model_sub2]["u"][-1] == 3.0
- @testattr(stddist = True)
def test_unstable_simulation(self):
model_sub1 = Dummy_FMUModelCS2([], os.path.join(cs2_xml_path, "LinearCoSimulation_LinearSubSystem1.fmu"), _connect_dll=False)
model_sub2 = Dummy_FMUModelCS2([], os.path.join(cs2_xml_path, "LinearCoSimulation_LinearSubSystem2.fmu"), _connect_dll=False)
diff --git a/tests/test_fmi_util.py b/tests/test_fmi_util.py
index 5c03a930..ac717872 100644
--- a/tests/test_fmi_util.py
+++ b/tests/test_fmi_util.py
@@ -22,12 +22,9 @@
import numpy as np
from collections import OrderedDict
-from pyfmi import testattr
import pyfmi.fmi_util as fmi_util
class Test_FMIUtil:
-
- @testattr(stddist = True)
def test_cpr_seed(self):
structure = OrderedDict([('der(inertia3.phi)', ['inertia3.w']),
('der(inertia3.w)', ['damper.phi_rel', 'inertia3.phi']),
@@ -46,7 +43,6 @@ def test_cpr_seed(self):
assert np.array(groups[1][4] == [3,4]).all()
assert np.array(groups[2][4] == [5,6]).all()
- @testattr(stddist = True)
def test_cpr_seed_interested_columns(self):
structure = OrderedDict([('der(inertia3.phi)', ['inertia3.w']),
('der(inertia3.w)', ['damper.phi_rel', 'inertia3.phi']),
diff --git a/tests/test_io.py b/tests/test_io.py
index 7232740c..47d5e262 100644
--- a/tests/test_io.py
+++ b/tests/test_io.py
@@ -15,21 +15,20 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see .
-import nose
+import pytest
import os
import numpy as np
import time
from io import StringIO, BytesIO
from collections import OrderedDict
-from pyfmi import testattr
from pyfmi.fmi import FMUException, FMUModelME2
from pyfmi.common.io import (ResultHandler, ResultDymolaTextual, ResultDymolaBinary, JIOError,
ResultHandlerCSV, ResultCSVTextual, ResultHandlerBinaryFile, ResultHandlerFile)
from pyfmi.common.diagnostics import DIAGNOSTICS_PREFIX
import pyfmi.fmi as fmi
-from pyfmi.tests.test_util import Dummy_FMUModelME1, Dummy_FMUModelME2, Dummy_FMUModelCS2
+from pyfmi.tests.test_util import Dummy_FMUModelME1, Dummy_FMUModelCS1, Dummy_FMUModelME2, Dummy_FMUModelCS2
file_path = os.path.dirname(os.path.abspath(__file__))
@@ -48,14 +47,13 @@ def _run_negated_alias(model, result_type, result_file_name=""):
# test that res['y'] returns a vector of the same length as the time
# vector
- nose.tools.assert_equal(len(res['y']),len(res['time']),
- "Wrong size of result vector.")
+ assert len(res['y']) ==len(res['time']), "Wrong size of result vector."
x = res["x"]
y = res["y"]
for i in range(len(x)):
- nose.tools.assert_equal(x[i], -y[i])
+ assert x[i] == -y[i]
if assimulo_installed:
class TestResultFileText_Simulation:
@@ -93,18 +91,15 @@ def f(*args, **kwargs):
assert len(x) > 2
for i in range(len(x)):
- nose.tools.assert_equal(x[i], -y[i])
+ assert x[i] == -y[i]
- @testattr(stddist = True)
def test_correct_file_after_simulation_failure(self):
self._correct_syntax_after_simulation_failure("NegatedAlias_result.txt")
- @testattr(stddist = True)
def test_correct_stream_after_simulation_failure(self):
stream = StringIO("")
self._correct_syntax_after_simulation_failure(stream)
- @testattr(stddist = True)
def test_read_all_variables_using_model_variables(self):
simple_alias = Dummy_FMUModelME2([("x", "y")], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "NegatedAlias.fmu"), _connect_dll=False)
@@ -117,7 +112,6 @@ def test_read_all_variables_using_model_variables(self):
for var in simple_alias.get_model_variables():
res[var]
- @testattr(stddist = True)
def test_read_alias_derivative(self):
simple_alias = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "Alias.fmu"), _connect_dll=False)
@@ -130,9 +124,8 @@ def test_read_alias_derivative(self):
dery = res["der(y)"]
for i in range(len(derx)):
- nose.tools.assert_equal(derx[i], dery[i])
+ assert derx[i] == dery[i]
- @testattr(stddist = True)
def test_no_variables(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "ParameterAlias.fmu"), _connect_dll=False)
@@ -143,9 +136,8 @@ def test_no_variables(self):
res = model.simulate(options=opts)
- nose.tools.assert_almost_equal(1.0, res["time"][-1])
+ assert 1.0 == pytest.approx(res["time"][-1])
- @testattr(stddist = True)
def test_enumeration_file(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "Friction2.fmu"), _connect_dll=False)
@@ -160,8 +152,6 @@ def test_enumeration_file(self):
res["mode"] #Check that the enumeration variable is in the dict, otherwise exception
class TestResultFileText:
-
-
def _get_description(self, result_file_name):
model = Dummy_FMUModelME1([], os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "CoupledClutches.fmu"), _connect_dll=False)
model.initialize()
@@ -179,16 +169,13 @@ def _get_description(self, result_file_name):
assert res.description[res.get_variable_index("J1.phi")] == "Absolute rotation angle of component"
- @testattr(stddist = True)
def test_get_description_file(self):
self._get_description('CoupledClutches_result.txt')
- @testattr(stddist = True)
def test_get_description_stream(self):
stream = StringIO()
self._get_description(stream)
- @testattr(stddist = True)
def test_description_not_stored(self):
model = Dummy_FMUModelME1([], os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "CoupledClutches.fmu"), _connect_dll=False)
model.initialize()
@@ -225,11 +212,9 @@ def _get_description_unicode(self, result_file_name):
assert desc == u"Test symbols '' ‘’"
- @testattr(stddist = True)
def _get_description_unicode_file(self):
self._get_description_unicode('Description_result.txt')
- @testattr(stddist = True)
def _get_description_unicode_stream(self):
stream = StringIO()
self._get_description_unicode(stream)
@@ -255,14 +240,12 @@ def _work_flow_me1(self, result_file_name):
derh = res.get_variable_data('der(h)')
g = res.get_variable_data('g')
- nose.tools.assert_almost_equal(h.x, 1.000000, 5)
- nose.tools.assert_almost_equal(derh.x, 0.000000, 5)
+ assert h.x == pytest.approx(1.000000, abs = 1e-5)
+ assert derh.x == pytest.approx(0.000000, abs = 1e-5)
- @testattr(stddist = True)
def test_work_flow_me1_file(self):
self._work_flow_me1('bouncingBall_result.txt')
- @testattr(stddist = True)
def test_work_flow_me1_stream(self):
stream = StringIO()
self._work_flow_me1(stream)
@@ -289,19 +272,16 @@ def _work_flow_me2(self, result_file_name):
derh = res.get_variable_data('der(h)')
g = res.get_variable_data('g')
- nose.tools.assert_almost_equal(h.x, 1.000000, 5)
- nose.tools.assert_almost_equal(derh.x, 0.000000, 5)
+ assert h.x == pytest.approx(1.000000, abs = 1e-5)
+ assert derh.x == pytest.approx(0.000000, abs = 1e-5)
- @testattr(stddist = True)
def test_work_flow_me2_file(self):
self._work_flow_me2('bouncingBall_result.txt')
- @testattr(stddist = True)
def test_work_flow_me2_stream(self):
stream = StringIO()
self._work_flow_me2(stream)
- @testattr(stddist = True)
def test_work_flow_me2_stream2(self):
""" Verify exception when using ResultHandlerFile with a stream that doesnt support 'seek'. """
class A:
@@ -309,10 +289,9 @@ def write(self):
pass
stream = A()
msg = "Failed to write the result file. Option 'result_file_name' needs to be a filename or a class that supports 'write' and 'seek'."
- with nose.tools.assert_raises_regex(FMUException, msg):
+ with pytest.raises(FMUException, match = msg):
self._work_flow_me2(stream)
- @testattr(stddist = True)
def test_work_flow_me2_stream3(self):
""" Verify exception when using ResultHandlerFile with a stream that doesnt support 'write'. """
class A:
@@ -320,10 +299,9 @@ def seek(self):
pass
stream = A()
msg = "Failed to write the result file. Option 'result_file_name' needs to be a filename or a class that supports 'write' and 'seek'."
- with nose.tools.assert_raises_regex(FMUException, msg):
+ with pytest.raises(FMUException, match = msg):
self._work_flow_me2(stream)
- @testattr(stddist = True)
def test_constructor_invalid_stream1(self):
""" Verify exception is raised for ResultDymolaTextual if fname argument is a stream not supporting 'readline'. """
class A:
@@ -331,10 +309,9 @@ def seek(self):
pass
stream = A()
msg = "Given stream needs to support 'readline' and 'seek' in order to retrieve the results."
- with nose.tools.assert_raises_regex(JIOError, msg):
+ with pytest.raises(JIOError, match = msg):
res = ResultDymolaTextual(stream)
- @testattr(stddist = True)
def test_constructor_invalid_stream2(self):
""" Verify exception is raised for ResultDymolaTextual if fname argument is a stream not supporting 'seek'. """
class A:
@@ -342,22 +319,19 @@ def readline(self):
pass
stream = A()
msg = "Given stream needs to support 'readline' and 'seek' in order to retrieve the results."
- with nose.tools.assert_raises_regex(JIOError, msg):
+ with pytest.raises(JIOError, match = msg):
res = ResultDymolaTextual(stream)
if assimulo_installed:
class TestResultMemory_Simulation:
- @testattr(stddist = True)
def test_memory_options_me1(self):
simple_alias = Dummy_FMUModelME1([40], os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "NegatedAlias.fmu"), _connect_dll=False)
_run_negated_alias(simple_alias, "memory")
- @testattr(stddist = True)
def test_memory_options_me2(self):
simple_alias = Dummy_FMUModelME2([("x", "y")], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "NegatedAlias.fmu"), _connect_dll=False)
_run_negated_alias(simple_alias, "memory")
- @testattr(stddist = True)
def test_only_parameters(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "ParameterAlias.fmu"), _connect_dll=False)
@@ -367,11 +341,10 @@ def test_only_parameters(self):
res = model.simulate(options=opts)
- nose.tools.assert_almost_equal(3.0, res["p2"][0])
+ assert 3.0 == pytest.approx(res["p2"][0])
assert not isinstance(res.initial("p2"), np.ndarray)
assert not isinstance(res.final("p2"), np.ndarray)
- @testattr(stddist = True)
def test_no_variables(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "ParameterAlias.fmu"), _connect_dll=False)
@@ -381,11 +354,9 @@ def test_no_variables(self):
res = model.simulate(options=opts)
- nose.tools.assert_almost_equal(1.0, res["time"][-1])
+ assert 1.0 == pytest.approx(res["time"][-1])
- @testattr(stddist = True)
def test_enumeration_memory(self):
-
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "Friction2.fmu"), _connect_dll=False)
data_type = model.get_variable_data_type("mode")
@@ -402,7 +373,6 @@ class TestResultMemory:
if assimulo_installed:
class TestResultFileBinary_Simulation:
-
def _correct_file_after_simulation_failure(self, result_file_name):
simple_alias = Dummy_FMUModelME2([("x", "y")], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "NegatedAlias.fmu"), _connect_dll=False)
@@ -436,14 +406,12 @@ def f(*args, **kwargs):
assert len(x) > 2
for i in range(len(x)):
- nose.tools.assert_equal(x[i], -y[i])
+ assert x[i] == -y[i]
- @testattr(stddist = True)
def test_work_flow_me2_file(self):
self._correct_file_after_simulation_failure("NegatedAlias_result.mat")
- @testattr(stddist = True)
def test_work_flow_me2_stream(self):
stream = BytesIO()
self._correct_file_after_simulation_failure(stream)
@@ -459,13 +427,11 @@ def _only_parameters(self, result_file_name):
res = model.simulate(options=opts)
- nose.tools.assert_almost_equal(3.0, res["p2"][0])
+ assert 3.0 == pytest.approx(res["p2"][0])
- @testattr(stddist = True)
def test_only_parameters_file(self):
self._only_parameters("ParameterAlias_result.mat")
- @testattr(stddist = True)
def test_only_parameters_stream(self):
stream = BytesIO()
self._only_parameters(stream)
@@ -481,19 +447,16 @@ def _no_variables(self, result_file_name):
res = model.simulate(options=opts)
- nose.tools.assert_almost_equal(1.0, res["time"][-1])
+ assert 1.0 == pytest.approx(res["time"][-1])
- @testattr(stddist = True)
def test_no_variables_file(self):
self._no_variables("ParameterAlias_result.mat")
- @testattr(stddist = True)
def test_no_variables_stream(self):
stream = BytesIO()
self._no_variables(stream)
- @testattr(stddist = True)
def test_read_alias_derivative(self):
simple_alias = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "Alias.fmu"), _connect_dll=False)
@@ -506,11 +469,9 @@ def test_read_alias_derivative(self):
dery = res["der(y)"]
for i in range(len(derx)):
- nose.tools.assert_equal(derx[i], dery[i])
+ assert derx[i] == dery[i]
- @testattr(stddist = True)
def test_enumeration_binary(self):
-
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "Friction2.fmu"), _connect_dll=False)
data_type = model.get_variable_data_type("mode")
@@ -523,7 +484,6 @@ def test_enumeration_binary(self):
res = model.simulate(options=opts)
res["mode"] #Check that the enumeration variable is in the dict, otherwise exception
- @testattr(stddist = True)
def test_integer_start_time(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "Alias.fmu"), _connect_dll=False)
@@ -533,7 +493,6 @@ def test_integer_start_time(self):
#Assert that there is no exception when reloading the file
res = model.simulate(start_time=0, options=opts)
- @testattr(stddist = True)
def test_read_all_variables_using_model_variables(self):
simple_alias = Dummy_FMUModelME2([("x", "y")], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "NegatedAlias.fmu"), _connect_dll=False)
@@ -546,7 +505,6 @@ def test_read_all_variables_using_model_variables(self):
for var in simple_alias.get_model_variables():
res[var]
- @testattr(stddist = True)
def test_variable_alias_custom_handler(self):
simple_alias = Dummy_FMUModelME2([("x", "y")], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "NegatedAlias.fmu"), _connect_dll=False)
@@ -558,39 +516,33 @@ def test_variable_alias_custom_handler(self):
# test that res['y'] returns a vector of the same length as the time
# vector
- nose.tools.assert_equal(len(res['y']),len(res['time']),
- "Wrong size of result vector.")
+ assert len(res['y']) ==len(res['time']), "Wrong size of result vector."
x = res["x"]
y = res["y"]
for i in range(len(x)):
- nose.tools.assert_equal(x[i], -y[i])
+ assert x[i] == -y[i]
- @testattr(stddist = True)
def test_binary_options_me1(self):
simple_alias = Dummy_FMUModelME1([40], os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "NegatedAlias.fmu"), _connect_dll=False)
_run_negated_alias(simple_alias, "binary")
- @testattr(stddist = True)
def test_binary_options_me2(self):
simple_alias = Dummy_FMUModelME2([("x", "y")], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "NegatedAlias.fmu"), _connect_dll=False)
_run_negated_alias(simple_alias, "binary")
- @testattr(stddist = True)
def test_binary_options_me1_stream(self):
simple_alias = Dummy_FMUModelME1([40], os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "NegatedAlias.fmu"), _connect_dll=False)
stream = BytesIO()
_run_negated_alias(simple_alias, "binary", stream)
- @testattr(stddist = True)
def test_binary_options_me2_stream(self):
simple_alias = Dummy_FMUModelME2([("x", "y")], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "NegatedAlias.fmu"), _connect_dll=False)
stream = BytesIO()
_run_negated_alias(simple_alias, "binary", stream)
class TestResultFileBinary:
-
def _get_description_unicode(self, result_file_name):
model = Dummy_FMUModelME1([], os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "Description.fmu"), _connect_dll=False)
model.initialize()
@@ -612,16 +564,13 @@ def _get_description_unicode(self, result_file_name):
assert desc == u"Test symbols '' ‘’"
- @testattr(stddist = True)
def test_get_description_unicode_file(self):
self._get_description_unicode('Description_result.mat')
- @testattr(stddist = True)
def test_get_description_unicode_stream(self):
stream = BytesIO()
self._get_description_unicode(stream)
- @testattr(stddist = True)
def test_get_description(self):
model = Dummy_FMUModelME1([], os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "CoupledClutches.fmu"), _connect_dll=False)
model.initialize()
@@ -637,7 +586,6 @@ def test_get_description(self):
assert res.description[res.get_variable_index("J1.phi")] == "Absolute rotation angle of component"
- @testattr(stddist = True)
def test_modified_result_file_data_diagnostics(self):
"""Verify that computed diagnostics can be retrieved from an updated result file"""
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "CoupledClutches.fmu"), _connect_dll=False)
@@ -689,7 +637,6 @@ def test_modified_result_file_data_diagnostics(self):
assert len(res.get_variable_data("@Diagnostics.state_errors.clutch2.w_rel").x) == 4, res.get_variable_data("@Diagnostics.state_errors.clutch2.w_rel").x
- @testattr(stddist = True)
def test_modified_result_file_data_diagnostics_steps(self):
"""Verify that diagnostics can be retrieved from an updated result file"""
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "CoupledClutches.fmu"), _connect_dll=False)
@@ -741,7 +688,6 @@ def test_modified_result_file_data_diagnostics_steps(self):
assert len(res.get_variable_data("@Diagnostics.nbr_steps").x) == 4, res.get_variable_data("@Diagnostics.nbr_steps").x
- @testattr(stddist = True)
def test_modified_result_file_data_2(self):
"""Verify that continuous trajectories are updated when retrieved from a result file"""
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "CoupledClutches.fmu"), _connect_dll=False)
@@ -764,7 +710,6 @@ def test_modified_result_file_data_2(self):
assert len(res.get_variable_data("J1.phi").x) == 2, res.get_variable_data("J1.phi").x
- @testattr(stddist = True)
def test_modified_result_file_data_2_different(self):
"""Verify that (different) continuous trajectories are updated when retrieved from a result file"""
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "CoupledClutches.fmu"), _connect_dll=False)
@@ -787,7 +732,6 @@ def test_modified_result_file_data_2_different(self):
assert len(res.get_variable_data("J2.phi").x) == 2, res.get_variable_data("J2.phi").x
- @testattr(stddist = True)
def test_modified_result_file_data_1(self):
"""Verify that (different) constants/parameters can be retrieved from an updated result file"""
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "CoupledClutches.fmu"), _connect_dll=False)
@@ -812,7 +756,6 @@ def test_modified_result_file_data_1(self):
#Assert that no exception is raised
res.get_variable_data("J2.J")
- @testattr(stddist = True)
def test_modified_result_file_data_1_delayed(self):
"""Verify that constants/parameters can be retrieved from an updated result file"""
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "CoupledClutches.fmu"), _connect_dll=False)
@@ -833,7 +776,6 @@ def test_modified_result_file_data_1_delayed(self):
#Assert that no exception is raised
res.get_variable_data("J2.J")
- @testattr(stddist = True)
def test_modified_result_file_time(self):
"""Verify that 'time' can be retrieved from an updated result file"""
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "CoupledClutches.fmu"), _connect_dll=False)
@@ -855,7 +797,6 @@ def test_modified_result_file_time(self):
res.get_variable_data("time")
- @testattr(stddist = True)
def test_description_not_stored(self):
model = Dummy_FMUModelME1([], os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "CoupledClutches.fmu"), _connect_dll=False)
model.initialize()
@@ -874,7 +815,6 @@ def test_description_not_stored(self):
assert res.description[res.get_variable_index("J1.phi")] == "", "Description is not empty, " + res.description[res.get_variable_index("J1.phi")]
- @testattr(stddist = True)
def test_overwriting_results(self):
model = Dummy_FMUModelME1([], os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "CoupledClutches.fmu"), _connect_dll=False)
model.initialize()
@@ -901,9 +841,9 @@ def test_overwriting_results(self):
result_writer.integration_point()
result_writer.simulation_end()
- nose.tools.assert_raises(JIOError,res.get_variable_data, "J1.phi")
+ with pytest.raises(JIOError):
+ res.get_variable_data("J1.phi")
- @testattr(stddist = True)
def test_read_all_variables(self):
res = ResultDymolaBinary(os.path.join(file_path, "files", "Results", "DoublePendulum.mat"))
@@ -912,7 +852,6 @@ def test_read_all_variables(self):
for var in res.name:
res.get_variable_data(var)
- @testattr(stddist = True)
def test_data_matrix_delayed_loading(self):
res = ResultDymolaBinary(os.path.join(file_path, "files", "Results", "DoublePendulum.mat"), delayed_trajectory_loading=True)
@@ -923,7 +862,6 @@ def test_data_matrix_delayed_loading(self):
assert nbr_continuous_variables == 68, "Number of variables is incorrect, should be 68"
assert nbr_points == 502, "Number of points is incorrect, should be 502"
- @testattr(stddist = True)
def test_data_matrix_loading(self):
res = ResultDymolaBinary(os.path.join(file_path, "files", "Results", "DoublePendulum.mat"), delayed_trajectory_loading=False)
@@ -934,7 +872,6 @@ def test_data_matrix_loading(self):
assert nbr_continuous_variables == 68, "Number of variables is incorrect, should be 68"
assert nbr_points == 502, "Number of points is incorrect, should be 502"
- @testattr(stddist = True)
def test_read_all_variables_from_stream(self):
with open(os.path.join(file_path, "files", "Results", "DoublePendulum.mat"), "rb") as f:
@@ -945,7 +882,6 @@ def test_read_all_variables_from_stream(self):
for var in res.name:
res.get_variable_data(var)
- @testattr(stddist = True)
def test_compare_all_variables_from_stream(self):
res_file = ResultDymolaBinary(os.path.join(file_path, "files", "Results", "DoublePendulum.mat"))
@@ -961,7 +897,6 @@ def test_compare_all_variables_from_stream(self):
np.testing.assert_array_equal(x_file.x, x_stream.x, err_msg="Mismatch in array values for var=%s"%var)
- @testattr(stddist = True)
def test_on_demand_loading_32_bits(self):
res_demand = ResultDymolaBinary(os.path.join(file_path, "files", "Results", "DoublePendulum.mat"))
res_all = ResultDymolaBinary(os.path.join(file_path, "files", "Results", "DoublePendulum.mat"))
@@ -969,7 +904,6 @@ def test_on_demand_loading_32_bits(self):
t_all = res_all.get_variable_data('time').x
np.testing.assert_array_equal(t_demand, t_all, "On demand loaded result and all loaded does not contain equal result.")
- @testattr(stddist = True)
def test_work_flow_me1(self):
model = Dummy_FMUModelME1([], os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "bouncingBall.fmu"), _connect_dll=False)
model.initialize()
@@ -988,10 +922,9 @@ def test_work_flow_me1(self):
derh = res.get_variable_data('der(h)')
g = res.get_variable_data('g')
- nose.tools.assert_almost_equal(h.x, 1.000000, 5)
- nose.tools.assert_almost_equal(derh.x, 0.000000, 5)
+ assert h.x == pytest.approx(1.000000, abs = 1e-5)
+ assert derh.x == pytest.approx(0.000000, abs = 1e-5)
- @testattr(stddist = True)
def test_many_variables_long_descriptions(self):
"""
Tests that large FMUs with lots of variables and huge length of descriptions gives
@@ -1003,9 +936,9 @@ def test_many_variables_long_descriptions(self):
res = ResultHandlerBinaryFile(model)
res.set_options(model.simulate_options())
- nose.tools.assert_raises(FMUException,res.simulation_start)
+ with pytest.raises(FMUException):
+ res.simulation_start()
- @testattr(stddist = True)
def test_work_flow_me2(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "bouncingBall.fmu"), _connect_dll=False)
model.setup_experiment()
@@ -1025,8 +958,8 @@ def test_work_flow_me2(self):
derh = res.get_variable_data('der(h)')
g = res.get_variable_data('g')
- nose.tools.assert_almost_equal(h.x[0], 1.000000, 5)
- nose.tools.assert_almost_equal(derh.x[0], 0.000000, 5)
+ assert h.x[0] == pytest.approx(1.000000, abs = 1e-5)
+ assert derh.x[0] == pytest.approx(0.000000, abs = 1e-5)
def _work_flow_me2_aborted(self, result_file_name):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "bouncingBall.fmu"), _connect_dll=False)
@@ -1053,34 +986,30 @@ def _work_flow_me2_aborted(self, result_file_name):
h = res.get_variable_data('h')
derh = res.get_variable_data('der(h)')
- nose.tools.assert_almost_equal(h.x[0], 1.000000, 5, msg="Incorrect initial value for 'h', should be 1.0")
- nose.tools.assert_almost_equal(derh.x[0], 0.000000, 5, msg="Incorrect value for 'derh', should be 0.0")
- nose.tools.assert_almost_equal(h.x[1], 1.000000, 5, msg="Incorrect value for 'h', should be 1.0")
- nose.tools.assert_almost_equal(derh.x[1], 0.000000, 5, msg="Incorrect value for 'derh', should be 0.0")
- nose.tools.assert_almost_equal(h.x[2], 1.000000, 5, msg="Incorrect value for 'h', should be 1.0")
- nose.tools.assert_almost_equal(derh.x[2], 0.000000, 5, msg="Incorrect value for 'derh', should be 0.0")
+ assert h.x[0] == pytest.approx(1.000000, abs = 1e-5), "Incorrect initial value for 'h', should be 1.0"
+ assert derh.x[0] == pytest.approx(0.000000, abs = 1e-5), "Incorrect value for 'derh', should be 0.0"
+ assert h.x[1] == pytest.approx(1.000000, abs = 1e-5), "Incorrect value for 'h', should be 1.0"
+ assert derh.x[1] == pytest.approx(0.000000, abs = 1e-5), "Incorrect value for 'derh', should be 0.0"
+ assert h.x[2] == pytest.approx(1.000000, abs = 1e-5), "Incorrect value for 'h', should be 1.0"
+ assert derh.x[2] == pytest.approx(0.000000, abs = 1e-5), "Incorrect value for 'derh', should be 0.0"
- @testattr(stddist = True)
def test_work_flow_me2_aborted_file(self):
self._work_flow_me2_aborted('bouncingBall_result.mat')
- @testattr(stddist = True)
def test_work_flow_me2_aborted_stream(self):
""" Verify expected workflow for ME2 aborted simulation using byte stream. """
stream = BytesIO()
self._work_flow_me2_aborted(stream)
- @testattr(stddist = True)
def test_work_flow_me2_aborted_stream2(self):
""" Verify exception when using ResultHandlerBinaryFile with a stream that doesnt support anything. """
class A:
pass
stream = A()
msg = "Failed to write the result file. Option 'result_file_name' needs to be a filename or a class that supports 'write', 'tell' and 'seek'."
- with nose.tools.assert_raises_regex(FMUException, msg):
+ with pytest.raises(FMUException, match = msg):
self._work_flow_me2_aborted(stream)
- @testattr(stddist = True)
def test_work_flow_me2_aborted_stream3(self):
""" Verify exception when using ResultHandlerBinaryFile with a stream that doesnt support 'seek'. """
class A:
@@ -1090,10 +1019,9 @@ def tell(self):
pass
stream = A()
msg = "Failed to write the result file. Option 'result_file_name' needs to be a filename or a class that supports 'write', 'tell' and 'seek'."
- with nose.tools.assert_raises_regex(FMUException, msg):
+ with pytest.raises(FMUException, match = msg):
self._work_flow_me2_aborted(stream)
- @testattr(stddist = True)
def test_work_flow_me2_aborted_stream4(self):
""" Verify exception when using ResultHandlerBinaryFile with a stream that doesnt support 'tell'. """
class A:
@@ -1103,10 +1031,9 @@ def seek(self):
pass
stream = A()
msg = "Failed to write the result file. Option 'result_file_name' needs to be a filename or a class that supports 'write', 'tell' and 'seek'."
- with nose.tools.assert_raises_regex(FMUException, msg):
+ with pytest.raises(FMUException, match = msg):
self._work_flow_me2_aborted(stream)
- @testattr(stddist = True)
def test_work_flow_me2_aborted_stream5(self):
""" Verify exception when using ResultHandlerBinaryFile with a stream that doesnt support 'write'. """
class A:
@@ -1116,10 +1043,9 @@ def tell(self):
pass
stream = A()
msg = "Failed to write the result file. Option 'result_file_name' needs to be a filename or a class that supports 'write', 'tell' and 'seek'."
- with nose.tools.assert_raises_regex(FMUException, msg):
+ with pytest.raises(FMUException, match = msg):
self._work_flow_me2_aborted(stream)
- @testattr(stddist = True)
def test_filter_no_variables(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "bouncingBall.fmu"), _connect_dll=False)
model.setup_experiment()
@@ -1140,14 +1066,12 @@ def test_filter_no_variables(self):
res = ResultDymolaBinary('bouncingBall_result.mat')
t = res.get_variable_data('time')
- nose.tools.assert_almost_equal(t.x[-1], 1.000000, 5)
+ assert t.x[-1] == pytest.approx(1.000000, abs = 1e-5)
- @testattr(stddist = True)
def test_binary_options_cs2(self):
simple_alias = Dummy_FMUModelCS2([("x", "y")], os.path.join(file_path, "files", "FMUs", "XML", "CS2.0", "NegatedAlias.fmu"), _connect_dll=False)
_run_negated_alias(simple_alias, "binary")
- @testattr(stddist = True)
def test_binary_options_cs2_stream(self):
simple_alias = Dummy_FMUModelCS2([("x", "y")], os.path.join(file_path, "files", "FMUs", "XML", "CS2.0", "NegatedAlias.fmu"), _connect_dll=False)
stream = BytesIO()
@@ -1160,7 +1084,6 @@ def _get_bouncing_ball_dummy(self, fmu_type = 'me2'):
elif fmu_type == 'me1':
return Dummy_FMUModelME1([], os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "bouncingBall.fmu"), _connect_dll=False)
- @testattr(stddist = True)
def test_exception_simulation_start(self):
""" Verify exception is raised if simulation_start is invoked without arguments. """
model = self._get_bouncing_ball_dummy()
@@ -1173,7 +1096,7 @@ def test_exception_simulation_start(self):
bouncingBall.set_options(opts)
msg = "Unable to start simulation. The following keyword argument\(s\) are empty:"
msg += " 'diagnostics\_params' and 'diagnostics\_vars'."
- with nose.tools.assert_raises_regex(FMUException, msg):
+ with pytest.raises(FMUException, match = msg):
bouncingBall.simulation_start()
def _get_diagnostics_cancelled_sim(self, result_file_name):
@@ -1244,23 +1167,20 @@ def _get_diagnostics_cancelled_sim(self, result_file_name):
ev_ind = res.get_variable_data(DIAGNOSTICS_PREFIX+'event_info.state_event_info.index_1').x
# Verify
- nose.tools.assert_almost_equal(h.x[0], 1.000000, 5, msg="Incorrect initial value for 'h', should be 1.0")
- nose.tools.assert_almost_equal(derh.x[0], 0.000000, 5, msg="Incorrect value for 'derh', should be 0.0")
+ assert h.x[0] == pytest.approx(1.000000, abs = 1e-5), "Incorrect initial value for 'h', should be 1.0"
+ assert derh.x[0] == pytest.approx(0.000000, abs = 1e-5), "Incorrect value for 'derh', should be 0.0"
np.testing.assert_array_equal(ev_ind, np.array([0., 0., 0., 0., 1., 0.]))
- @testattr(stddist = True)
def test_diagnostics_data_cancelled_simulation_mat_file(self):
""" Verify that we can retrieve data and diagnostics data after cancelled sim using matfile. """
self._get_diagnostics_cancelled_sim("TestCancelledSim.mat")
- @testattr(stddist = True)
def test_diagnostics_data_cancelled_simulation_file_stream(self):
""" Verify that we can retrieve data and diagnostics data after cancelled sim using filestream. """
test_file_stream = open('myfilestream.txt', 'wb')
self._get_diagnostics_cancelled_sim(test_file_stream)
- @testattr(stddist = True)
def test_debug_file_not_generated_when_dynamic_diagnostics_is_true(self):
""" Verify that the debug file is not created when option dynamic_diagnostics is true. """
model = self._get_bouncing_ball_dummy()
@@ -1271,10 +1191,8 @@ def test_debug_file_not_generated_when_dynamic_diagnostics_is_true(self):
os.remove(potential_debug_file)
model.simulate(options = opts)
- nose.tools.assert_false(os.path.isfile(potential_debug_file),
- "Test failed, file {} exists after simulation".format(potential_debug_file))
+ assert not os.path.isfile(potential_debug_file), "Test failed, file {} exists after simulation".format(potential_debug_file)
- @testattr(stddist = True)
def test_exception_dynamic_diagnostics_and_non_binary_result_handling(self):
""" Verify that an exception is raised if dynamic_diagnostics is True and result_handling is not binary. """
model = self._get_bouncing_ball_dummy()
@@ -1284,10 +1202,9 @@ def test_exception_dynamic_diagnostics_and_non_binary_result_handling(self):
err_msg = ("The chosen result_handler does not support dynamic_diagnostics."
" Try using e.g., ResultHandlerBinaryFile.")
- with nose.tools.assert_raises_regex(fmi.InvalidOptionException, err_msg):
+ with pytest.raises(fmi.InvalidOptionException, match = err_msg):
model.simulate(options = opts)
- @testattr(stddist = True)
def test_exception_dynamic_diagnostics_and_non_binary_result_handling1(self):
""" Verify that an exception is raised if dynamic diagnostics is True and result_handling is custom
and does not support dynamic_diagnostics. """
@@ -1303,14 +1220,13 @@ def get_result(self):
foo_inst = Foo(model)
opts["result_handler"] = foo_inst
- nose.tools.assert_false(foo_inst.supports.get('dynamic_diagnostics'))
+ assert not foo_inst.supports.get('dynamic_diagnostics')
err_msg = ("The chosen result_handler does not support dynamic_diagnostics."
" Try using e.g., ResultHandlerBinaryFile.")
- with nose.tools.assert_raises_regex(fmi.InvalidOptionException, err_msg):
+ with pytest.raises(fmi.InvalidOptionException, match = err_msg):
model.simulate(options = opts)
- @testattr(stddist = True)
def test_exception_dynamic_diagnostics_and_non_binary_result_handling2(self):
""" Verify that exception is raised if dynamic diagnostics is True and result_handling is custom and valid class. """
model = self._get_bouncing_ball_dummy()
@@ -1329,9 +1245,8 @@ def test_exception_dynamic_diagnostics_and_non_binary_result_handling2(self):
exception_msg = str(e)
raise e
# In case error did not stop the test run
- nose.tools.assert_true(no_error, "Error occurred: {}".format(exception_msg))
+ assert no_error, "Error occurred: {}".format(exception_msg)
- @testattr(stddist = True)
def test_custom_result_handler_dynamic_diagnostics(self):
""" Test dynamic diagnostics with a custom results handler that supports it. """
model = self._get_bouncing_ball_dummy()
@@ -1356,9 +1271,8 @@ def get_result(self):
opts["result_handler"] = res_handler
model.simulate(options = opts)
- nose.tools.assert_true(res_handler.diagnostics_point_called, msg = "diagnostics_point function was never called.")
+ assert res_handler.diagnostics_point_called, "diagnostics_point function was never called."
- @testattr(stddist = True)
def test_result_handler_supports_dynamic_diagnostics(self):
""" Test dynamic diagnostics with a custom results handler that supports it, but lacks actual implementation. """
model = self._get_bouncing_ball_dummy()
@@ -1379,7 +1293,8 @@ def get_result(self):
res_handler = ResultDynDiag()
opts["result_handler"] = res_handler
- nose.tools.assert_raises(NotImplementedError, model.simulate, options = opts)
+ with pytest.raises(NotImplementedError):
+ model.simulate(options = opts)
def _test_no_debug_file(self, fmu_type):
model = self._get_bouncing_ball_dummy(fmu_type=fmu_type)
@@ -1392,15 +1307,12 @@ def _test_no_debug_file(self, fmu_type):
model.simulate(options = opts)
- nose.tools.assert_false(os.path.isfile(expected_debug_file),
- msg = f"file {expected_debug_file} found.")
+ assert not os.path.isfile(expected_debug_file), f"file {expected_debug_file} found."
- @testattr(stddist = True)
def test_debug_file_not_generated_me1(self):
""" Verify that the debug file is not generated by enabling logging (ME1). """
self._test_no_debug_file(fmu_type = 'me1')
- @testattr(stddist = True)
def test_debug_file_not_generated_me2(self):
""" Verify that the debug file is not generated by enabling logging (ME2). """
self._test_no_debug_file(fmu_type = 'me2')
@@ -1424,19 +1336,16 @@ def _test_debug_file_opening(self, fmu_type):
# Verify
with open(expected_debug_file, 'r') as f:
line = f.readline()
- nose.tools.assert_false(test_str in line, "Test failed, found '{}' in '{}'".format(test_str, line))
+ assert not test_str in line, "Test failed, found '{}' in '{}'".format(test_str, line)
- @testattr(stddist = True)
def test_debug_file_opened_in_write_mode_me1(self):
""" Verify that the debug file is opened in write mode if it already did exist (ME1). """
self._test_debug_file_opening(fmu_type = 'me1')
- @testattr(stddist = True)
def test_debug_file_opened_in_write_mode_me2(self):
""" Verify that the debug file is opened in write mode if it already did exist (ME2). """
self._test_debug_file_opening(fmu_type = 'me1')
- @testattr(stddist = True)
def test_diagnostics_numerical_values(self):
""" Verify that we get the expected values for some diagnostics. """
model = self._get_bouncing_ball_dummy()
@@ -1451,40 +1360,34 @@ def test_diagnostics_numerical_values(self):
expected_solver_order[0] = 0.0
np.testing.assert_array_equal(res[f'{DIAGNOSTICS_PREFIX}solver.solver_order'], expected_solver_order)
- @testattr(stddist = True)
def test_get_last_result_file0(self):
""" Verify get_last_result_file seems to point at the correct file. """
test_model = self._get_bouncing_ball_dummy()
file_name = "testname.mat"
test_model._result_file = file_name
- nose.tools.assert_equal(test_model.get_last_result_file().split(os.sep)[-1], file_name,
- "Unable to find {} in string {}".format(file_name, test_model.get_last_result_file()))
+ assert test_model.get_last_result_file().split(os.sep)[-1] == file_name, "Unable to find {} in string {}".format(file_name, test_model.get_last_result_file())
- @testattr(stddist = True)
def test_get_last_result_file1(self):
""" Verify get_last_result_file returns an absolute path. """
test_model = self._get_bouncing_ball_dummy()
file_name = "testname.mat"
test_model._result_file = file_name
- nose.tools.assert_true(os.path.isabs(test_model.get_last_result_file()), "Expected abspath but got {}".format(test_model.get_last_result_file()))
+ assert os.path.isabs(test_model.get_last_result_file()), "Expected abspath but got {}".format(test_model.get_last_result_file())
- @testattr(stddist = True)
def test_get_last_result_file2(self):
""" Verify get_last_result_file doesnt cause exception if the result file is not yet set. """
test_model = self._get_bouncing_ball_dummy()
test_model._result_file = None
- nose.tools.assert_true(test_model.get_last_result_file() is None, "Expected None but got {}".format(test_model.get_last_result_file()))
+ assert test_model.get_last_result_file() is None, "Expected None but got {}".format(test_model.get_last_result_file())
- @testattr(stddist = True)
def test_get_last_result_file3(self):
""" Verify get_last_result_file doesnt cause exception if the result file is not set correctly. """
test_model = self._get_bouncing_ball_dummy()
test_model._result_file = 123 # arbitrary number, just verify get_last_result_file works
- nose.tools.assert_true(test_model.get_last_result_file() is None, "Expected None but got {}".format(test_model.get_last_result_file()))
+ assert test_model.get_last_result_file() is None, "Expected None but got {}".format(test_model.get_last_result_file())
if assimulo_installed:
class TestResultCSVTextual_Simulation:
- @testattr(stddist = True)
def test_only_parameters(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "ParameterAlias.fmu"), _connect_dll=False)
@@ -1495,9 +1398,8 @@ def test_only_parameters(self):
res = model.simulate(options=opts)
- nose.tools.assert_almost_equal(3.0, res["p2"][0])
+ assert 3.0 == pytest.approx(res["p2"][0])
- @testattr(stddist = True)
def test_no_variables(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "ParameterAlias.fmu"), _connect_dll=False)
@@ -1509,11 +1411,9 @@ def test_no_variables(self):
res = model.simulate(options=opts)
- nose.tools.assert_almost_equal(1.0, res["time"][-1])
+ assert 1.0 == pytest.approx(res["time"][-1])
- @testattr(stddist = True)
def test_variable_alias_custom_handler(self):
-
simple_alias = Dummy_FMUModelME1([40], os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "NegatedAlias.fmu"), _connect_dll=False)
opts = simple_alias.simulate_options()
@@ -1524,38 +1424,32 @@ def test_variable_alias_custom_handler(self):
# test that res['y'] returns a vector of the same length as the time
# vector
- nose.tools.assert_equal(len(res['y']),len(res['time']),
- "Wrong size of result vector.")
+ assert len(res['y']) ==len(res['time']), "Wrong size of result vector."
x = res["x"]
y = res["y"]
for i in range(len(x)):
- nose.tools.assert_equal(x[i], -y[i])
+ assert x[i] == -y[i]
- @testattr(stddist = True)
def test_csv_options_me1(self):
simple_alias = Dummy_FMUModelME1([40], os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "NegatedAlias.fmu"), _connect_dll=False)
_run_negated_alias(simple_alias, "csv")
- @testattr(stddist = True)
def test_csv_options_me2(self):
simple_alias = Dummy_FMUModelME2([("x", "y")], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "NegatedAlias.fmu"), _connect_dll=False)
_run_negated_alias(simple_alias, "csv")
- @testattr(stddist = True)
def test_csv_options_me1_stream(self):
simple_alias = Dummy_FMUModelME1([40], os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "NegatedAlias.fmu"), _connect_dll=False)
stream = StringIO()
_run_negated_alias(simple_alias, "csv", stream)
- @testattr(stddist = True)
def test_csv_options_me2(self):
simple_alias = Dummy_FMUModelME2([("x", "y")], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "NegatedAlias.fmu"), _connect_dll=False)
stream = StringIO()
_run_negated_alias(simple_alias, "csv", stream)
- @testattr(stddist = True)
def test_enumeration_csv(self):
model = Dummy_FMUModelME2([], os.path.join(file_path, "files", "FMUs", "XML", "ME2.0", "Friction2.fmu"), _connect_dll=False)
@@ -1572,7 +1466,6 @@ def test_enumeration_csv(self):
class TestResultCSVTextual:
- @testattr(stddist = True)
def test_constructor_invalid_stream1(self):
""" Verify exception is raised for ResultCSVTextual if filename argument is a stream not supporting 'readline'. """
class A:
@@ -1580,10 +1473,9 @@ def seek(self):
pass
stream = A()
msg = "Given stream needs to support 'readline' and 'seek' in order to retrieve the results."
- with nose.tools.assert_raises_regex(JIOError, msg):
+ with pytest.raises(JIOError, match = msg):
res = ResultCSVTextual(stream)
- @testattr(stddist = True)
def test_constructor_invalid_stream2(self):
""" Verify exception is raised for ResultCSVTextual if filename argument is a stream not supporting 'seek'. """
class A:
@@ -1591,10 +1483,9 @@ def readline(self):
pass
stream = A()
msg = "Given stream needs to support 'readline' and 'seek' in order to retrieve the results."
- with nose.tools.assert_raises_regex(JIOError, msg):
+ with pytest.raises(JIOError, match = msg):
res = ResultCSVTextual(stream)
- @testattr(stddist = True)
def test_delimiter(self):
res = ResultCSVTextual(os.path.join(file_path, 'files', 'Results', 'TestCSV.csv'), delimiter=",")
@@ -1603,7 +1494,6 @@ def test_delimiter(self):
assert x.x[-1] == 1
- @testattr(stddist = True)
def _work_flow_me1(self, result_file_name):
model = Dummy_FMUModelME1([], os.path.join(file_path, "files", "FMUs", "XML", "ME1.0", "bouncingBall.fmu"), _connect_dll=False)
model.initialize()
@@ -1624,14 +1514,12 @@ def _work_flow_me1(self, result_file_name):
derh = res.get_variable_data('der(h)')
g = res.get_variable_data('g')
- nose.tools.assert_almost_equal(h.x, 1.000000, 5)
- nose.tools.assert_almost_equal(derh.x, 0.000000, 5)
+ assert h.x == pytest.approx(1.000000, abs = 1e-5)
+ assert derh.x == pytest.approx(0.000000, abs = 1e-5)
- @testattr(stddist = True)
def test_work_flow_me1_file(self):
self._work_flow_me1('bouncingBall_result.csv')
- @testattr(stddist = True)
def test_work_flow_me1_stream(self):
stream = StringIO()
self._work_flow_me1(stream)
@@ -1656,37 +1544,30 @@ def _work_flow_me2(self, result_file_name):
derh = res.get_variable_data('der(h)')
g = res.get_variable_data('g')
- nose.tools.assert_almost_equal(h.x, 1.000000, 5)
- nose.tools.assert_almost_equal(derh.x, 0.000000, 5)
+ assert h.x == pytest.approx(1.000000, abs = 1e-5)
+ assert derh.x == pytest.approx(0.000000, abs = 1e-5)
- @testattr(stddist = True)
def test_work_flow_me2_file(self):
self._work_flow_me2('bouncingBall_result.csv')
- @testattr(stddist = True)
def test_work_flow_me2_stream(self):
stream = StringIO()
self._work_flow_me2(stream)
- @testattr(stddist = True)
def test_work_flow_me2_stream2(self):
""" Verify exception when using ResultHandlerCSV with a stream that doesnt support 'write'. """
class A:
pass
stream = A() # send in something that is not a string
msg = "Failed to write the result file. Option 'result_file_name' needs to be a filename or a class that supports writing to through the 'write' method."
- with nose.tools.assert_raises_regex(FMUException, msg):
+ with pytest.raises(FMUException, match = msg):
self._work_flow_me2(stream)
- """
- @testattr(stddist = True)
def test_csv_options_cs1(self):
simple_alias = Dummy_FMUModelCS1([40], os.path.join(file_path, "files", "FMUs", "XML", "CS1.0", "NegatedAlias.fmu"), _connect_dll=False)
- self._run_negated_alias(self, simple_alias)
+ _run_negated_alias(simple_alias, "csv")
- @testattr(stddist = True)
def test_csv_options_cs2(self):
simple_alias = Dummy_FMUModelCS2([("x", "y")], os.path.join(file_path, "files", "FMUs", "XML", "CS2.0", "NegatedAlias.fmu"), _connect_dll=False)
- self._run_negated_alias(self, simple_alias)
- """
+ _run_negated_alias(simple_alias, "csv")
diff --git a/tests/test_log.py b/tests/test_log.py
index 35f112c4..38f26d7d 100644
--- a/tests/test_log.py
+++ b/tests/test_log.py
@@ -17,7 +17,6 @@
import os
-from pyfmi import testattr
from pyfmi.common.log import extract_xml_log, parse_xml_log
from pyfmi.common.diagnostics import DIAGNOSTICS_PREFIX
from pyfmi.tests.test_util import Dummy_FMUModelME2
@@ -28,8 +27,6 @@
logs = os.path.join(file_path, "files", "Logs")
class Test_Log:
-
- @testattr(stddist = True)
def test_decode_bytes(self):
"""
Verifies that malformed strings are still accepted and don't cause exceptions
@@ -41,7 +38,6 @@ def test_decode_bytes(self):
assert s_string == '[WARNING][FMU status:Warning] "�\x15"', s_string
- @testattr(stddist = True)
def test_extract_log(self):
extract_xml_log("Tmp1.xml", os.path.join(logs, "CoupledClutches_log.txt"), modulename = 'Model')
@@ -51,14 +47,12 @@ def test_extract_log(self):
assert "" == str(log.nodes[1]), "Got: " + str(log.nodes[1])
- @testattr(stddist = True)
def test_extract_log_exception(self):
try:
extract_xml_log("Tmp2", os.path.join(logs, "CoupledClutches_log_.txt"), modulename = 'Model')
except FileNotFoundError:
pass
- @testattr(stddist = True)
def test_extract_log_cs(self):
extract_xml_log("Tmp3.xml", os.path.join(logs, "CoupledClutches_CS_log.txt"), modulename = 'Slave')
@@ -68,7 +62,6 @@ def test_extract_log_cs(self):
assert "" == str(log.nodes[1]), "Got: " + str(log.nodes[1])
- @testattr(stddist = True)
def test_extract_log_wrong_modulename(self):
extract_xml_log("Tmp4.xml", os.path.join(logs, "CoupledClutches_CS_log.txt"), modulename = 'Test')
@@ -100,7 +93,6 @@ def _test_logging_different_solver(self, solver_name):
np.testing.assert_equal(len(res['time']), len(res['h']), "Expected time and h to be of equal length but they weren't!")
return res
- @testattr(stddist = True)
def test_logging_option_CVode(self):
res = self._test_logging_different_solver("CVode")
t = res['time']
@@ -110,30 +102,25 @@ def test_logging_option_CVode(self):
assert (f'{DIAGNOSTICS_PREFIX}state_errors.h' in res.keys()), f"'{DIAGNOSTICS_PREFIX}state_errors.h' should be part of result variables!"
- @testattr(stddist = True)
def test_logging_option_Radau5ODE(self):
res = self._test_logging_different_solver("Radau5ODE")
event_type = list(res[f'{DIAGNOSTICS_PREFIX}event_data.event_info.event_type'])
assert event_type.count(-1) == len(event_type), "Expected no events to have happened!"
assert (f'{DIAGNOSTICS_PREFIX}state_errors.h' in res.keys()), f"'{DIAGNOSTICS_PREFIX}state_errors.h' should be part of result variables!"
- @testattr(stddist = True)
def test_logging_option_ImplicitEuler(self):
res = self._test_logging_different_solver("ImplicitEuler")
- assert not (f'{DIAGNOSTICS_PREFIX}state_errors.h' in res.keys()), f"'{DIAGNOSTICS_PREFIX}state_errors.h' should not be part of result variables!"
+ assert f'{DIAGNOSTICS_PREFIX}state_errors.h' not in res.keys(), f"'{DIAGNOSTICS_PREFIX}state_errors.h' should not be part of result variables!"
- @testattr(stddist = True)
def test_logging_option_ExplicitEuler(self):
res = self._test_logging_different_solver("ExplicitEuler")
- assert not (f'{DIAGNOSTICS_PREFIX}state_errors.h' in res.keys()), f"'{DIAGNOSTICS_PREFIX}state_errors.h' should not be part of result variables!"
+ assert f'{DIAGNOSTICS_PREFIX}state_errors.h' not in res.keys(), f"'{DIAGNOSTICS_PREFIX}state_errors.h' should not be part of result variables!"
- @testattr(stddist = True)
def test_logging_option_LSODAR(self):
res = self._test_logging_different_solver("LSODAR")
event_type = list(res[f'{DIAGNOSTICS_PREFIX}event_data.event_info.event_type'])
assert event_type.count(-1) == len(event_type), "Expected no events to have happened, but event_type contains: {}!".format(event_type)
- @testattr(stddist = True)
def test_calculated_diagnostic(self):
res = self._test_logging_different_solver("CVode")
np.testing.assert_equal(len(res['time']), len(res[f'{DIAGNOSTICS_PREFIX}nbr_steps']),
@@ -148,14 +135,12 @@ def test_calculated_diagnostic(self):
"Expected time and Diagnostics.nbr_state_limits_step.h to be of equal length but they weren't!")
- @testattr(stddist = True)
def test_extract_boolean_value(self):
log = parse_xml_log(os.path.join(logs, "boolean_log.xml"))
eis = log.find("EventInfo")
for ei in eis:
assert isinstance(ei.time_event_info, bool), "Expected ei.time_event_info to be bool"
- @testattr(stddist = True)
def test_hasattr_works(self):
"""
Tests that 'hasattr' works on the log nodes.
diff --git a/tests/test_stream.py b/tests/test_stream.py
index 758c7af1..fd8be522 100644
--- a/tests/test_stream.py
+++ b/tests/test_stream.py
@@ -15,14 +15,13 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-import nose
+import pytest
import os
from io import StringIO
import tempfile
from shutil import rmtree
from filecmp import cmp as compare_files
-from pyfmi import testattr
from pyfmi.fmi import FMUException, load_fmu, FMUModelCS2, FMUModelME2
from pyfmi.tests.test_util import get_examples_folder
@@ -74,31 +73,29 @@ def simulate_and_verify_stream_contents(compiled_fmu, fmu_loader, stream, open_t
]
for i, line in enumerate(expected):
err_msg = "Unable to find substring {} in list {}".format(line, "".join(contents))
- nose.tools.assert_in(line, contents[i], err_msg)
+ assert line in contents[i], err_msg
class Test_FMUModelME2:
""" Test stream functionality for FMI class FMUModelME2. """
+ @pytest.fixture(autouse=True)
@classmethod
def setup_class(cls):
cls.example_fmu = os.path.join(get_examples_folder(), 'files', 'FMUs', 'ME2.0', 'bouncingBall.fmu')
cls.test_class = FMUModelME2
# Verify the installation is not corrupt while setting up the class.
- nose.tools.assert_true(os.path.isfile(cls.example_fmu))
+ assert os.path.isfile(cls.example_fmu)
- @testattr(stddist = True)
def test_testio(self):
""" FMUModelME2 and custom IO class. """
stream = TestIO("")
simulate_and_verify_stream_contents(self.example_fmu, self.test_class, stream)
- @testattr(stddist = True)
def test_stringio(self):
""" FMUModelME2 and StringIO. """
stream = StringIO()
simulate_and_verify_stream_contents(self.example_fmu, self.test_class, stream)
- @testattr(stddist = True)
def test_textiowrapper(self):
""" FMUModelME2 and TextIOWrapper. """
p = tempfile.mkdtemp()
@@ -111,27 +108,25 @@ def test_textiowrapper(self):
class Test_FMUModelCS2:
""" Test stream functionality for FMI class FMUModelCS2. """
+ @pytest.fixture(autouse=True)
@classmethod
def setup_class(cls):
cls.example_fmu = os.path.join(get_examples_folder(), 'files', 'FMUs', 'CS2.0', 'bouncingBall.fmu')
cls.test_class = FMUModelCS2
# Verify the installation is not corrupt while setting up the class.
- nose.tools.assert_true(os.path.isfile(cls.example_fmu))
+ assert os.path.isfile(cls.example_fmu)
- @testattr(stddist = True)
def test_testio(self):
""" FMUModelCS2 and custom IO class. """
stream = TestIO("")
simulate_and_verify_stream_contents(self.example_fmu, self.test_class, stream)
- @testattr(stddist = True)
def test_stringio(self):
""" FMUModelCS2 and StringIO. """
stream = StringIO()
simulate_and_verify_stream_contents(self.example_fmu, self.test_class, stream)
- @testattr(stddist = True)
def test_textiowrapper(self):
""" FMUModelCS2 and TextIOWrapper. """
p = tempfile.mkdtemp()
@@ -144,27 +139,25 @@ def test_textiowrapper(self):
class Test_LoadFMU:
""" Test stream functionality with load_fmu. """
+ @pytest.fixture(autouse=True)
@classmethod
def setup_class(cls):
cls.example_fmu = os.path.join(get_examples_folder(), 'files', 'FMUs', 'ME2.0', 'bouncingBall.fmu')
cls.test_class = load_fmu
# Verify the installation is not corrupt while setting up the class.
- nose.tools.assert_true(os.path.isfile(cls.example_fmu))
+ assert os.path.isfile(cls.example_fmu)
- @testattr(stddist = True)
def test_testio(self):
""" load_fmu and custom IO class. """
stream = TestIO("")
simulate_and_verify_stream_contents(Test_LoadFMU.example_fmu, Test_LoadFMU.test_class, stream)
- @testattr(stddist = True)
def test_stringio(self):
""" load_fmu and StringIO. """
stream = StringIO()
simulate_and_verify_stream_contents(Test_LoadFMU.example_fmu, Test_LoadFMU.test_class, stream)
- @testattr(stddist = True)
def test_textiowrapper(self):
""" load_fmu and TextIOWrapper. """
p = tempfile.mkdtemp()
@@ -177,14 +170,14 @@ def test_textiowrapper(self):
class TestXML:
""" Test other log related functions together with streams. """
+ @pytest.fixture(autouse=True)
@classmethod
def setup_class(cls):
cls.example_fmu = os.path.join(get_examples_folder(), 'files', 'FMUs', 'ME2.0', 'bouncingBall.fmu')
# Verify the installation is not corrupt while setting up the class.
- nose.tools.assert_true(os.path.isfile(cls.example_fmu))
+ assert os.path.isfile(cls.example_fmu)
- @testattr(stddist = True)
def test_extract_xml_log(self):
""" Compare contents of XML log when using stream and normal logfile. """
stream = TestIO("")
@@ -206,9 +199,8 @@ def test_extract_xml_log(self):
xml_log = fmu.extract_xml_log()
err_msg = "Unequal xml files, please compare the contents of:\n{}\nand\n{}".format(xml_log_s, xml_log)
- nose.tools.assert_true(compare_files(xml_log_s, xml_log), err_msg)
+ assert compare_files(xml_log_s, xml_log), err_msg
- @testattr(stddist = True)
def test_get_log(self):
""" Test get_log throws exception if stream doesnt support getvalue. """
stream = StringIO("")
@@ -221,10 +213,9 @@ def test_get_log(self):
'FMIL: module = FMI2XML, log level = 3: fmi2_xml_get_default_experiment_tolerance'
]
for i, line in enumerate(expected_substr):
- nose.tools.assert_in(line, log[i])
+ assert line in log[i]
- @testattr(stddist = True)
def test_get_log_exception1(self):
""" Test get_log throws exception if stream doesnt allow reading (it is set for writing). """
try:
@@ -234,7 +225,7 @@ def test_get_log_exception1(self):
fmu_s = load_fmu(self.example_fmu, log_file_name = stream, log_level = 3)
res_s = fmu_s.simulate()
err_msg = "Unable to read from given stream, make sure the stream is readable."
- with nose.tools.assert_raises_regex(FMUException, err_msg):
+ with pytest.raises(FMUException, match = err_msg):
log = fmu_s.get_log()
finally:
if not stream.closed:
@@ -242,16 +233,14 @@ def test_get_log_exception1(self):
rmtree(p)
- @testattr(stddist = True)
def test_get_nbr_of_lines_in_log(self):
""" Test get_number_of_lines_log when using a stream. """
stream = StringIO("")
fmu = load_fmu(self.example_fmu, log_file_name = stream, log_level = 3)
- nose.tools.assert_equal(fmu.get_number_of_lines_log(), 0)
+ assert fmu.get_number_of_lines_log() == 0
res = fmu.simulate()
- nose.tools.assert_equal(fmu.get_number_of_lines_log(), 0)
+ assert fmu.get_number_of_lines_log() == 0
- @testattr(stddist = True)
def test_extract_xml_log_into_stream(self):
""" Compare contents of XML log when extract XML into a stream. """
stream = TestIO("")
@@ -277,4 +266,4 @@ def test_extract_xml_log_into_stream(self):
xml_log = fmu.extract_xml_log()
err_msg = "Unequal xml files, please compare the contents of:\n{}\nand\n{}".format(xml_file1, xml_log)
- nose.tools.assert_true(compare_files(xml_file1, xml_log), err_msg)
+ assert compare_files(xml_file1, xml_log), err_msg