diff --git a/README.md b/README.md index da66993c..2213eeac 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,269 @@ Please follow the instructions in [python_testing_exercise.md](https://github.co ### pytest log +```bash +python -m pytest +========================================== test session starts =========================================== +platform win32 -- Python 3.13.1, pytest-8.3.4, pluggy-1.5.0 +rootdir: C:\Users\marce\Desktop\Uni\SSE\Repos\testing-python-exercise-wt2425 +collected 5 items + +tests\integration\test_diffusion2d.py .. [ 40%] +tests\unit\test_diffusion2d_functions.py FFF [100%] + +================================================ FAILURES ================================================ +_________________________________________ test_initialize_domain _________________________________________ + + def test_initialize_domain(): + """ + Check function SolveDiffusion2D.initialize_domain + """ + solver = SolveDiffusion2D() + w, h, dx, dy = 2.0, 3.0, 0.5, 0.5 + expected_nx = 4 # int(2.0 / 0.5) + expected_ny = 6 # int(3.0 / 0.5) + + solver.initialize_domain(w, h, dx, dy) + +> assert solver.nx == expected_nx +E assert 6 == 4 +E + where 6 = .nx + +tests\unit\test_diffusion2d_functions.py:19: AssertionError +__________________________________ test_initialize_physical_parameters ___________________________________ + + def test_initialize_physical_parameters(): + """ + Checks function SolveDiffusion2D.initialize_physical_parameters + """ + solver = SolveDiffusion2D() + d, T_cold, T_hot = 1.0, 250.0, 300.0 + solver.dx = 0.5 + solver.dy = 0.25 + expected_dt = 0.025 #(0.5**2 * 0.25**2) / (2 * 1.0 * (0.5**2 + 0.25**2)) + + solver.initialize_physical_parameters(d, T_cold, T_hot) + + assert solver.D == d + assert solver.T_cold == T_cold + assert solver.T_hot == T_hot +> assert solver.dt == expected_dt +E assert 0.0625 == 0.025 +E + where 0.0625 = .dt + +tests\unit\test_diffusion2d_functions.py:37: AssertionError +------------------------------------------ Captured stdout call ------------------------------------------ +dt = 0.0625 +_______________________________________ test_set_initial_condition _______________________________________ + + def test_set_initial_condition(): + """ + Checks function SolveDiffusion2D.set_initial_condition + """ + solver = SolveDiffusion2D() + solver.nx, solver.ny = 4, 4 + solver.dx, solver.dy = 1.0, 2.0 + solver.T_cold = 25.0 + solver.T_hot = 30.0 + expected_u = np.array([ + [25.0, 25.0, 25.0, 25.0], + [25.0, 25.0, 25.0, 25.0], + [25.0, 25.0, 25.0, 25.0], + [25.0, 25.0, 25.0, 25.0] + ]) + + u = solver.set_initial_condition() + +> assert np.array_equal(u, expected_u) +E assert False +E + where False = (array([[30., 30., 30., 30.],\n [30., 30., 30., 30.],\n [30., 30., 30., 30.],\n [30., 30., 30., 30.]]), array([[25., 25., 25., 25.],\n [25., 25., 25., 25.],\n [25., 25., 25., 25.],\n [25., 25., 25., 25.]])) +E + where = np.array_equal + +tests\unit\test_diffusion2d_functions.py:57: AssertionError +======================================== short test summary info ========================================= +FAILED tests/unit/test_diffusion2d_functions.py::test_initialize_domain - assert 6 == 4 +FAILED tests/unit/test_diffusion2d_functions.py::test_initialize_physical_parameters - assert 0.0625 == 0.025 +FAILED tests/unit/test_diffusion2d_functions.py::test_set_initial_condition - assert False +====================================== 3 failed, 2 passed in 0.56s ======================================= +``` + ### unittest log + +```bash +python -m unittest tests/unit/test_diffusion2d_functions.py +Fdt = 0.0625 +FF +====================================================================== +FAIL: test_initialize_domain (tests.unit.test_diffusion2d_functions.TestDiffusion2D.test_initialize_domain) +Check function SolveDiffusion2D.initialize_domain +---------------------------------------------------------------------- +Traceback (most recent call last): + File "C:\Users\marce\Desktop\Uni\SSE\Repos\testing-python-exercise-wt2425\tests\unit\test_diffusion2d_functions.py", line 25, in test_initialize_domain + self.assertEqual(self.solver.nx, expected_nx) + ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +AssertionError: 6 != 4 + +====================================================================== +FAIL: test_initialize_physical_parameters (tests.unit.test_diffusion2d_functions.TestDiffusion2D.test_initialize_physical_parameters) +Checks function SolveDiffusion2D.initialize_physical_parameters +---------------------------------------------------------------------- +Traceback (most recent call last): + File "C:\Users\marce\Desktop\Uni\SSE\Repos\testing-python-exercise-wt2425\tests\unit\test_diffusion2d_functions.py", line 42, in test_initialize_physical_parameters + self.assertEqual(self.solver.dt, expected_dt) + ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +AssertionError: 0.0625 != 0.025 + +====================================================================== +FAIL: test_set_initial_condition (tests.unit.test_diffusion2d_functions.TestDiffusion2D.test_set_initial_condition) +Checks function SolveDiffusion2D.set_initial_condition +---------------------------------------------------------------------- +Traceback (most recent call last): + File "C:\Users\marce\Desktop\Uni\SSE\Repos\testing-python-exercise-wt2425\tests\unit\test_diffusion2d_functions.py", line 61, in test_set_initial_condition + np.testing.assert_array_equal(u, expected_u) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^ + File "C:\Users\marce\Desktop\Uni\SSE\Repos\testing-python-exercise-wt2425\venv\Lib\site-packages\numpy\_utils\__init__.py", line 85, in wrapper + return fun(*args, **kwargs) + File "C:\Users\marce\Desktop\Uni\SSE\Repos\testing-python-exercise-wt2425\venv\Lib\site-packages\numpy\testing\_private\utils.py", line 1020, in assert_array_equal + assert_array_compare(operator.__eq__, actual, desired, err_msg=err_msg, + ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + verbose=verbose, header='Arrays are not equal', + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + strict=strict) + ^^^^^^^^^^^^^^ + File "C:\Users\marce\Desktop\Uni\SSE\Repos\testing-python-exercise-wt2425\venv\Lib\site-packages\numpy\testing\_private\utils.py", line 884, in assert_array_compare + raise AssertionError(msg) +AssertionError: +Arrays are not equal + +Mismatched elements: 16 / 16 (100%) +Max absolute difference among violations: 5. +Max relative difference among violations: 0.2 + ACTUAL: array([[30., 30., 30., 30.], + [30., 30., 30., 30.], + [30., 30., 30., 30.], + [30., 30., 30., 30.]]) + DESIRED: array([[25., 25., 25., 25.], + [25., 25., 25., 25.], + [25., 25., 25., 25.], + [25., 25., 25., 25.]]) + +---------------------------------------------------------------------- +Ran 3 tests in 0.064s + +FAILED (failures=3) +``` + +### integration test log + +```bash +pytest tests/integration/test_diffusion2d.py +============================================================ test session starts ============================================================ +platform win32 -- Python 3.13.1, pytest-8.3.4, pluggy-1.5.0 +rootdir: C:\Users\marce\Desktop\Uni\SSE\Repos\testing-python-exercise-wt2425 +collected 2 items + +tests\integration\test_diffusion2d.py FF [100%] + +================================================================= FAILURES ================================================================== +____________________________________________________ test_initialize_physical_parameters ____________________________________________________ + + def test_initialize_physical_parameters(): + """ + Checks function SolveDiffusion2D.initialize_physical_parameters + """ + solver = SolveDiffusion2D() + w, h, dx, dy = 2.0, 3.0, 0.5, 0.25 + d, T_cold, T_hot = 1.0, 250.0, 300.0 + expected_dt = 0.025 # (0.5**2 * 0.25**2) / (2 * 1.0 * (0.5**2 + 0.25**2)) + + solver.initialize_domain(w, h, dx, dy) + solver.initialize_physical_parameters(d, T_cold, T_hot) + +> assert solver.dt == expected_dt +E assert 0.0625 == 0.025 +E + where 0.0625 = .dt + +tests\integration\test_diffusion2d.py:24: AssertionError +----------------------------------------------------------- Captured stdout call ------------------------------------------------------------ +dt = 0.0625 +________________________________________________________ test_set_initial_condition _________________________________________________________ + + def test_set_initial_condition(): + """ + Checks function SolveDiffusion2D.set_initial_condition + """ + solver = SolveDiffusion2D() + w, h, dx, dy = 4.0, 4.0, 1.0, 1.0 + d, T_cold, T_hot = 1.0, 25.0, 30.0 + expected_u = np.array([ + [25.0, 25.0, 25.0, 25.0], + [25.0, 25.0, 25.0, 25.0], + [25.0, 25.0, 25.0, 25.0], + [25.0, 25.0, 25.0, 25.0] + ]) + + solver.initialize_domain(w, h, dx, dy) + solver.initialize_physical_parameters(d, T_cold, T_hot) + u = solver.set_initial_condition() + +> np.testing.assert_array_equal(u, expected_u) + +tests\integration\test_diffusion2d.py:44: +_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + +args = (array([[30., 30., 30., 30.], + [30., 30., 30., 30.], + [30., 30., 30., 30.], + [30., 30., 30., 30.]]), array([[25., 25., 25., 25.], + [25., 25., 25., 25.], + [25., 25., 25., 25.], + [25., 25., 25., 25.]])) +kwargs = {}, old_name = 'y', new_name = 'desired' + + @functools.wraps(fun) + def wrapper(*args, **kwargs): + for old_name, new_name in zip(old_names, new_names): + if old_name in kwargs: + if dep_version: + end_version = dep_version.split('.') + end_version[1] = str(int(end_version[1]) + 2) + end_version = '.'.join(end_version) + msg = (f"Use of keyword argument `{old_name}` is " + f"deprecated and replaced by `{new_name}`. " + f"Support for `{old_name}` will be removed " + f"in NumPy {end_version}.") + warnings.warn(msg, DeprecationWarning, stacklevel=2) + if new_name in kwargs: + msg = (f"{fun.__name__}() got multiple values for " + f"argument now known as `{new_name}`") + raise TypeError(msg) + kwargs[new_name] = kwargs.pop(old_name) +> return fun(*args, **kwargs) +E AssertionError: +E Arrays are not equal +E +E Mismatched elements: 16 / 16 (100%) +E Max absolute difference among violations: 5. +E Max relative difference among violations: 0.2 +E ACTUAL: array([[30., 30., 30., 30.], +E [30., 30., 30., 30.], +E [30., 30., 30., 30.], +E [30., 30., 30., 30.]]) +E DESIRED: array([[25., 25., 25., 25.], +E [25., 25., 25., 25.], +E [25., 25., 25., 25.], +E [25., 25., 25., 25.]]) + +venv\Lib\site-packages\numpy\_utils\__init__.py:85: AssertionError +----------------------------------------------------------- Captured stdout call ------------------------------------------------------------ +dt = 0.25 +========================================================== short test summary info ========================================================== +FAILED tests/integration/test_diffusion2d.py::test_initialize_physical_parameters - assert 0.0625 == 0.025 +FAILED tests/integration/test_diffusion2d.py::test_set_initial_condition - AssertionError: +============================================================= 2 failed in 0.57s ============================================================= +``` + ## Citing The code used in this exercise is based on [Chapter 7 of the book "Learning Scientific Programming with Python"](https://scipython.com/book/chapter-7-matplotlib/examples/the-two-dimensional-diffusion-equation/). diff --git a/coverage-report.pdf b/coverage-report.pdf new file mode 100644 index 00000000..87a401ec Binary files /dev/null and b/coverage-report.pdf differ diff --git a/diffusion2d.py b/diffusion2d.py index 51a07f2d..21e12433 100644 --- a/diffusion2d.py +++ b/diffusion2d.py @@ -37,7 +37,11 @@ def __init__(self): # Timestep self.dt = None - def initialize_domain(self, w=10., h=10., dx=0.1, dy=0.1): + def initialize_domain(self, w=10.0, h=10.0, dx=0.1, dy=0.1): + assert isinstance(w, float), "Width must be a float" + assert isinstance(h, float), "Height must be a float" + assert isinstance(dx, float), "dx must be a float" + assert isinstance(dy, float), "dy must be a float" self.w = w self.h = h self.dx = dx @@ -45,7 +49,10 @@ def initialize_domain(self, w=10., h=10., dx=0.1, dy=0.1): self.nx = int(w / dx) self.ny = int(h / dy) - def initialize_physical_parameters(self, d=4., T_cold=300, T_hot=700): + def initialize_physical_parameters(self, d=4.0, T_cold=300.0, T_hot=700.0): + assert isinstance(d, float), "Diffusion coefficient must be a float" + assert isinstance(T_cold, float), "Cold temperature must be a float" + assert isinstance(T_hot, float), "Hot temperature must be a float" self.D = d self.T_cold = T_cold self.T_hot = T_hot diff --git a/tests/integration/test_diffusion2d.py b/tests/integration/test_diffusion2d.py index fd026b40..63995694 100644 --- a/tests/integration/test_diffusion2d.py +++ b/tests/integration/test_diffusion2d.py @@ -1,19 +1,44 @@ """ -Tests for functionality checks in class SolveDiffusion2D +Integration tests for functions in class SolveDiffusion2D """ -from diffusion2d import SolveDiffusion2D +import sys +import os +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../../'))) #With out this my test will not be found +from diffusion2d import SolveDiffusion2D +import numpy as np def test_initialize_physical_parameters(): """ - Checks function SolveDiffusion2D.initialize_domain + Checks function SolveDiffusion2D.initialize_physical_parameters """ solver = SolveDiffusion2D() - + w, h, dx, dy = 2.0, 3.0, 0.5, 0.25 + d, T_cold, T_hot = 1.0, 250.0, 300.0 + expected_dt = 0.025 # (0.5**2 * 0.25**2) / (2 * 1.0 * (0.5**2 + 0.25**2)) + + solver.initialize_domain(w, h, dx, dy) + solver.initialize_physical_parameters(d, T_cold, T_hot) + + assert solver.dt == expected_dt def test_set_initial_condition(): """ - Checks function SolveDiffusion2D.get_initial_function + Checks function SolveDiffusion2D.set_initial_condition """ solver = SolveDiffusion2D() + w, h, dx, dy = 4.0, 4.0, 1.0, 1.0 + d, T_cold, T_hot = 1.0, 25.0, 30.0 + expected_u = np.array([ + [25.0, 25.0, 25.0, 25.0], + [25.0, 25.0, 25.0, 25.0], + [25.0, 25.0, 25.0, 25.0], + [25.0, 25.0, 25.0, 25.0] + ]) + + solver.initialize_domain(w, h, dx, dy) + solver.initialize_physical_parameters(d, T_cold, T_hot) + u = solver.set_initial_condition() + + np.testing.assert_array_equal(u, expected_u) diff --git a/tests/unit/test_diffusion2d_functions.py b/tests/unit/test_diffusion2d_functions.py index c4277ffd..41332017 100644 --- a/tests/unit/test_diffusion2d_functions.py +++ b/tests/unit/test_diffusion2d_functions.py @@ -2,25 +2,63 @@ Tests for functions in class SolveDiffusion2D """ +import unittest +from unittest import TestCase from diffusion2d import SolveDiffusion2D +import numpy as np +class TestDiffusion2D(TestCase): -def test_initialize_domain(): - """ - Check function SolveDiffusion2D.initialize_domain - """ - solver = SolveDiffusion2D() + def setUp(self): + self.solver = SolveDiffusion2D() + def test_initialize_domain(self): + """ + Check function SolveDiffusion2D.initialize_domain + """ + w, h, dx, dy = 2.0, 3.0, 0.5, 0.5 + expected_nx = 4 # int(2.0 / 0.5) + expected_ny = 6 # int(3.0 / 0.5) + + self.solver.initialize_domain(w, h, dx, dy) + + self.assertEqual(self.solver.nx, expected_nx) + self.assertEqual(self.solver.ny, expected_ny) -def test_initialize_physical_parameters(): - """ - Checks function SolveDiffusion2D.initialize_domain - """ - solver = SolveDiffusion2D() + def test_initialize_physical_parameters(self): + """ + Checks function SolveDiffusion2D.initialize_physical_parameters + """ + d, T_cold, T_hot = 1.0, 250.0, 300.0 + self.solver.dx = 0.5 + self.solver.dy = 0.25 + expected_dt = 0.025 # (0.5**2 * 0.25**2) / (2 * 1.0 * (0.5**2 + 0.25**2)) + + self.solver.initialize_physical_parameters(d, T_cold, T_hot) + + self.assertEqual(self.solver.D, d) + self.assertEqual(self.solver.T_cold, T_cold) + self.assertEqual(self.solver.T_hot, T_hot) + self.assertEqual(self.solver.dt, expected_dt) + def test_set_initial_condition(self): + """ + Checks function SolveDiffusion2D.set_initial_condition + """ + self.solver.nx, self.solver.ny = 4, 4 + self.solver.dx, self.solver.dy = 1.0, 1.0 + self.solver.T_cold = 25.0 + self.solver.T_hot = 30.0 + expected_u = np.array([ + [25.0, 25.0, 25.0, 25.0], + [25.0, 25.0, 25.0, 25.0], + [25.0, 25.0, 25.0, 25.0], + [25.0, 25.0, 25.0, 25.0] + ]) + + u = self.solver.set_initial_condition() + + np.testing.assert_array_equal(u, expected_u) -def test_set_initial_condition(): - """ - Checks function SolveDiffusion2D.get_initial_function - """ - solver = SolveDiffusion2D() +if __name__ == '__main__': + unittest.main() diff --git a/tox.toml b/tox.toml new file mode 100644 index 00000000..3bc6d8bf --- /dev/null +++ b/tox.toml @@ -0,0 +1,14 @@ +requires = ["tox>=4"] +env_list = ["testing"] + +[env.testing] +description = "Run pytest and unittest" +deps = [ + "pytest>=8", + "numpy>=1.15.0", + "matplotlib>=3.0.0" +] +commands = [ + ["pytest"], + ["python", "-m", "unittest", "discover", "-s", "tests/unit"] +] \ No newline at end of file