From 9522d6e3c9d9a4479cd9593dfa4b60050fed657c Mon Sep 17 00:00:00 2001 From: lVentus Date: Tue, 21 Jan 2025 20:22:26 +0100 Subject: [PATCH] Tests --- README.md | 192 +++++++++++++++++++++++ coverage report.pdf | Bin 0 -> 61419 bytes diffusion2d.py | 9 +- requirements.txt | 3 + tests/integration/test_diffusion2d.py | 35 ++++- tests/unit/test_diffusion2d_functions.py | 68 ++++++-- tox.toml | 10 ++ 7 files changed, 299 insertions(+), 18 deletions(-) create mode 100644 coverage report.pdf create mode 100644 requirements.txt create mode 100644 tox.toml diff --git a/README.md b/README.md index da66993c..c8d3ecb2 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,200 @@ Please follow the instructions in [python_testing_exercise.md](https://github.co ### pytest log +#### unit + +================================================= test session starts ================================================= +platform win32 -- Python 3.12.8, pytest-8.3.4, pluggy-1.5.0 +rootdir: C:\Users\sora\Documents\Lecture\SSE\Exercise\ex6\testing-python-exercise-wt2425 +collected 3 items + +tests\unit\test_diffusion2d_functions.py FFF [100%] + +====================================================== FAILURES ======================================================= +_______________________________________________ test_initialize_domain ________________________________________________ + + def test_initialize_domain(): + """ + Check function SolveDiffusion2D.initialize_domain + """ + solver = SolveDiffusion2D() + solver.initialize_domain(w=30.,h=40.,dx=0.2,dy=0.1) + +> assert solver.nx == 150, f"Expected nx=150, but is {solver.nx}" +E AssertionError: Expected nx=150, but is 300 +E assert 300 == 150 +E + where 300 = .nx + +tests\unit\test_diffusion2d_functions.py:18: AssertionError +_________________________________________ test_initialize_physical_parameters _________________________________________ + + def test_initialize_physical_parameters(): + """ + Checks function SolveDiffusion2D.initialize_domain + """ + solver = SolveDiffusion2D() + solver.w = 30. + solver.h = 40. + solver.dx = 0.2 + solver.dy = 0.2 + solver.initialize_physical_parameters(d=4., T_cold=100., T_hot=300.) + + expected_dt = 0.0025 +> assert abs(solver.dt - expected_dt) < 1e-4, f"Expected dt={expected_dt}, but is {solver.dt}" +E AssertionError: Expected dt=0.0025, but is 0.0075000000000000015 +E assert 0.005000000000000001 < 0.0001 +E + where 0.005000000000000001 = abs((0.0075000000000000015 - 0.0025)) +E + where 0.0075000000000000015 = .dt + +tests\unit\test_diffusion2d_functions.py:34: AssertionError +------------------------------------------------ Captured stdout call ------------------------------------------------- +dt = 0.0075000000000000015 +_____________________________________________ test_set_initial_condition ______________________________________________ + + def test_set_initial_condition(): + """ + Checks function SolveDiffusion2D.get_initial_function + """ + solver = SolveDiffusion2D() + solver.nx = 100 + solver.ny = 150 + solver.dx = 0.2 + solver.dy = 0.4 + solver.T_cold = 100. + solver.T_hot = 400. + + u = solver.set_initial_condition() + +> assert u[0, 0] == solver.T_cold, "Top-left corner should be cold." +E AssertionError: Top-left corner should be cold. +E assert np.float64(400.0) == 100.0 +E + where 100.0 = .T_cold + +tests\unit\test_diffusion2d_functions.py:50: AssertionError +=============================================== short test summary info =============================================== +FAILED tests/unit/test_diffusion2d_functions.py::test_initialize_domain - AssertionError: Expected nx=150, but is 300 +FAILED tests/unit/test_diffusion2d_functions.py::test_initialize_physical_parameters - AssertionError: Expected dt=0.0025, but is 0.0075000000000000015 +FAILED tests/unit/test_diffusion2d_functions.py::test_set_initial_condition - AssertionError: Top-left corner should be cold. +================================================== 3 failed in 0.55s ================================================== + +#### intergration + +================================================= test session starts ================================================= +platform win32 -- Python 3.12.8, pytest-8.3.4, pluggy-1.5.0 +rootdir: C:\Users\sora\Documents\Lecture\SSE\Exercise\ex6\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 = 30., 40., 0.2, 0.2 + d, T_cold, T_hot = 4., 100., 300. + expected_dt = 0.0025 + + solver.initialize_domain(w, h, dx, dy) + solver.initialize_physical_parameters(d, T_cold, T_hot) + +> assert np.allclose(expected_dt, solver.dt), f"Expected dt={expected_dt}, but is {solver.dt}" +E AssertionError: Expected dt=0.0025, but is 0.0075000000000000015 +E assert False +E + where False = (0.0025, 0.0075000000000000015) +E + where = np.allclose +E + and 0.0075000000000000015 = .dt + +tests\integration\test_diffusion2d.py:24: AssertionError +------------------------------------------------ Captured stdout call ------------------------------------------------- +dt = 0.0075000000000000015 +_____________________________________________ test_set_initial_condition ______________________________________________ + + def test_set_initial_condition(): + """ + Checks function SolveDiffusion2D.set_initial_condition + """ + solver = SolveDiffusion2D() + + solver.initialize_domain(30., 40., 0.2, 0.2) + solver.initialize_physical_parameters(4., 100., 300.) + solver_u = solver.set_initial_condition() + + dx,dy,T_cold,T_hot = 0.2, 0.2, 100., 300. + r, cx, cy, nx, ny = 2, 5, 5, 150, 200 + r2 = r ** 2 + + u = T_cold * np.ones((nx, ny)) + + for i in range(nx): + for j in range(ny): + p2 = (i * dx - cx) ** 2 + (j * dy - cy) ** 2 + if p2 < r2: + u[i, j] = T_hot + +> assert np.allclose(solver_u, u), f"u should be {u},but got{solver_u}" +E AssertionError: u should be [[100. 100. 100. ... 100. 100. 100.] +E [100. 100. 100. ... 100. 100. 100.] +E [100. 100. 100. ... 100. 100. 100.] +E ... +E [100. 100. 100. ... 100. 100. 100.] +E [100. 100. 100. ... 100. 100. 100.] +E [100. 100. 100. ... 100. 100. 100.]],but got[[300. 300. 300. ... 300. 300. 300.] +E [300. 300. 300. ... 300. 300. 300.] +E [300. 300. 300. ... 300. 300. 300.] +E ... +E [300. 300. 300. ... 300. 300. 300.] +E [300. 300. 300. ... 300. 300. 300.] +E [300. 300. 300. ... 300. 300. 300.]] +E assert False +E + where False = (array([[300., 300., 300., ..., 300., 300., 300.],\n [300., 300., 300., ..., 300., 300., 300.],\n [300., 300....\n [300., 300., 300., ..., 300., 300., 300.],\n [300., 300., 300., ..., 300., 300., 300.]], shape=(150, 200)), array([[100., 100., 100., ..., 100., 100., 100.],\n [100., 100., 100., ..., 100., 100., 100.],\n [100., 100....\n [100., 100., 100., ..., 100., 100., 100.],\n [100., 100., 100., ..., 100., 100., 100.]], shape=(150, 200))) +E + where = np.allclose + +tests\integration\test_diffusion2d.py:49: AssertionError +------------------------------------------------ Captured stdout call ------------------------------------------------- +dt = 0.0075000000000000015 +=============================================== short test summary info =============================================== +FAILED tests/integration/test_diffusion2d.py::test_initialize_physical_parameters - AssertionError: Expected dt=0.0025, but is 0.0075000000000000015 +FAILED tests/integration/test_diffusion2d.py::test_set_initial_condition - AssertionError: u should be [[100. 100. 100. ... 100. 100. 100.] +================================================== 2 failed in 0.60s ================================================== + ### unittest log +====================================================================== +FAIL: test_initialize_domain (test_diffusion2d_functions.TestDiffusion2D.test_initialize_domain) +Check function SolveDiffusion2D.initialize_domain +---------------------------------------------------------------------- +Traceback (most recent call last): + File "C:\Users\sora\Documents\Lecture\SSE\Exercise\ex6\testing-python-exercise-wt2425\tests\unit\test_diffusion2d_functions.py", line 20, in test_initialize_domain + self.assertEqual(solver.nx, 150, f"Expected nx=150, but got {solver.nx}") +AssertionError: 300 != 150 : Expected nx=150, but got 300 + +====================================================================== +FAIL: test_initialize_physical_parameters (test_diffusion2d_functions.TestDiffusion2D.test_initialize_physical_parameters) +Checks function SolveDiffusion2D.initialize_domain +---------------------------------------------------------------------- +Traceback (most recent call last): + File "C:\Users\sora\Documents\Lecture\SSE\Exercise\ex6\testing-python-exercise-wt2425\tests\unit\test_diffusion2d_functions.py", line 35, in test_initialize_physical_parameters + self.assertAlmostEqual(solver.dt, expected_dt, places=4,msg = f"Expected dt={expected_dt}, but is {solver.dt}") +AssertionError: 0.0075000000000000015 != 0.0025 within 4 places (0.005000000000000001 difference) : Expected dt=0.0025, but is 0.0075000000000000015 + +====================================================================== +FAIL: test_set_initial_condition (test_diffusion2d_functions.TestDiffusion2D.test_set_initial_condition) +Checks function SolveDiffusion2D.get_initial_function +---------------------------------------------------------------------- +Traceback (most recent call last): + File "C:\Users\sora\Documents\Lecture\SSE\Exercise\ex6\testing-python-exercise-wt2425\tests\unit\test_diffusion2d_functions.py", line 63, in test_set_initial_condition + self.assertAlmostEqual(solver_u[i, j], u[i, j], places=4, +AssertionError: np.float64(600.0) != np.float64(200.0) within 4 places (np.float64(400.0) difference) : u[0,0] should be 200.0,but got600.0 + +---------------------------------------------------------------------- +Ran 3 tests in 0.004s + +FAILED (failures=3) + ## 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 0000000000000000000000000000000000000000..85476d0d1fb4c7b6ba4e3e15119c61d5ef7c4c6d GIT binary patch literal 61419 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 literal 0 HcmV?d00001 diff --git a/diffusion2d.py b/diffusion2d.py index 51a07f2d..45110076 100644 --- a/diffusion2d.py +++ b/diffusion2d.py @@ -38,6 +38,10 @@ def __init__(self): self.dt = None def initialize_domain(self, w=10., h=10., 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., T_cold=300., T_hot=700.): + assert isinstance(d, float), "Thermal diffusivity must be a float" + assert isinstance(T_cold, float), "T_cold must be a float" + assert isinstance(T_hot, float), "T_hot must be a float" self.D = d self.T_cold = T_cold self.T_hot = T_hot diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..7851745b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +pytest +numpy +matplotlib \ No newline at end of file diff --git a/tests/integration/test_diffusion2d.py b/tests/integration/test_diffusion2d.py index fd026b40..5912bd19 100644 --- a/tests/integration/test_diffusion2d.py +++ b/tests/integration/test_diffusion2d.py @@ -1,19 +1,50 @@ """ Tests for functionality checks in class SolveDiffusion2D """ +import numpy as np +import sys +import os +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../../'))) from diffusion2d import SolveDiffusion2D def test_initialize_physical_parameters(): """ - Checks function SolveDiffusion2D.initialize_domain + Checks function SolveDiffusion2D.initialize_physical_parameters """ solver = SolveDiffusion2D() + w, h, dx, dy = 30., 40., 0.2, 0.2 + d, T_cold, T_hot = 4., 100., 300. + expected_dt = 0.0025 + + solver.initialize_domain(w, h, dx, dy) + solver.initialize_physical_parameters(d, T_cold, T_hot) + + assert np.allclose(expected_dt, solver.dt), f"Expected dt={expected_dt}, but is {solver.dt}" def test_set_initial_condition(): """ - Checks function SolveDiffusion2D.get_initial_function + Checks function SolveDiffusion2D.set_initial_condition """ solver = SolveDiffusion2D() + + solver.initialize_domain(30., 40., 0.2, 0.2) + solver.initialize_physical_parameters(4., 100., 300.) + solver_u = solver.set_initial_condition() + + dx,dy,T_cold,T_hot = 0.2, 0.2, 100., 300. + r, cx, cy, nx, ny = 2, 5, 5, 150, 200 + r2 = r ** 2 + + u = T_cold * np.ones((nx, ny)) + + for i in range(nx): + for j in range(ny): + p2 = (i * dx - cx) ** 2 + (j * dy - cy) ** 2 + if p2 < r2: + u[i, j] = T_hot + + assert np.allclose(solver_u, u), f"u should be {u},but got{solver_u}" + diff --git a/tests/unit/test_diffusion2d_functions.py b/tests/unit/test_diffusion2d_functions.py index c4277ffd..307a5603 100644 --- a/tests/unit/test_diffusion2d_functions.py +++ b/tests/unit/test_diffusion2d_functions.py @@ -1,26 +1,64 @@ """ Tests for functions in class SolveDiffusion2D """ +import numpy as np +import sys +import os +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../../'))) from diffusion2d import SolveDiffusion2D +import unittest +class TestDiffusion2D(unittest.TestCase): + def test_initialize_domain(self): + """ + Check function SolveDiffusion2D.initialize_domain + """ + solver = SolveDiffusion2D() + solver.initialize_domain(w=30.,h=40.,dx=0.2,dy=0.1) + + self.assertEqual(solver.nx, 150, f"Expected nx=150, but got {solver.nx}") + self.assertEqual(solver.ny, 400, f"Expected ny=400, but got {solver.ny}") -def test_initialize_domain(): - """ - Check function SolveDiffusion2D.initialize_domain - """ - solver = SolveDiffusion2D() + def test_initialize_physical_parameters(self): + """ + Checks function SolveDiffusion2D.initialize_domain + """ + solver = SolveDiffusion2D() + solver.w = 30. + solver.h = 40. + solver.dx = 0.2 + solver.dy = 0.2 + solver.initialize_physical_parameters(d=4., T_cold=100., T_hot=300.) + expected_dt = 0.0025 + self.assertAlmostEqual(solver.dt, expected_dt, places=4,msg = f"Expected dt={expected_dt}, but is {solver.dt}") -def test_initialize_physical_parameters(): - """ - Checks function SolveDiffusion2D.initialize_domain - """ - solver = SolveDiffusion2D() + def test_set_initial_condition(self): + """ + Checks function SolveDiffusion2D.get_initial_function + """ + solver = SolveDiffusion2D() + solver.dx = solver.dy = 0.2 + solver.nx = solver.ny = 50 + solver.T_cold, solver.T_hot = 200., 600. -def test_set_initial_condition(): - """ - Checks function SolveDiffusion2D.get_initial_function - """ - solver = SolveDiffusion2D() + solver_u = solver.set_initial_condition() + + r, cx, cy = 2, 5, 5 + r2 = r ** 2 + + u = solver.T_cold * np.ones((solver.nx, solver.ny)) + + for i in range(solver.nx): + for j in range(solver.ny): + p2 = (i * solver.dx - cx) ** 2 + (j * solver.dy - cy) ** 2 + if p2 < r2: + u[i, j] = solver.T_hot + + + for i in range(solver.nx): + for j in range(solver.ny): + self.assertAlmostEqual(solver_u[i, j], u[i, j], places=4, + msg=f"u[{i},{j}] should be {u[i, j]},but got{solver_u[i, j]}") \ No newline at end of file diff --git a/tox.toml b/tox.toml new file mode 100644 index 00000000..3839311b --- /dev/null +++ b/tox.toml @@ -0,0 +1,10 @@ +requires = ["tox>=4"] +env_list = ["testing"] + +[env.testing] +desciption = "Run pytest and unittest" +deps = ["-r requirements.txt"] +commands = [ + ["python", "-m", "pytest"], + ["python", "-m", "unittest", "discover", "-s", "tests/unit"] +] \ No newline at end of file