diff --git a/README.md b/README.md index da66993c..b2fb9c6d 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,152 @@ Please follow the instructions in [python_testing_exercise.md](https://github.co ## Test logs (for submission) ### pytest log +``` +tests\integration\test_diffusion2d.py .. [ 40%] +tests\unit\test_diffusion2d_functions.py F.. [100%] + +============================================================= FAILURES ============================================================= +______________________________________________________ test_initialize_domain ______________________________________________________ + + def test_initialize_domain(): + """ + Check function SolveDiffusion2D.initialize_domain + """ + solver = SolveDiffusion2D() + # fixture + w = 25. + h = 40. + dx = 0.25 + dy = 0.5 + + # test + solver.initialize_domain(w, h, dx, dy) + assert solver.w == w + assert solver.h == h + assert solver.dx == dx + assert solver.dy == dy +> assert (solver.nx == 100) and (isinstance(solver.nx, int)) +E assert (160 == 100) +E + where 160 = .nx + +tests\unit\test_diffusion2d_functions.py:26: AssertionError +===================================================== short test summary info ====================================================== +FAILED tests/unit/test_diffusion2d_functions.py::test_initialize_domain - assert (160 == 100) +=================================================== 1 failed, 4 passed in 0.40s ==================================================== + +``` ### unittest log +``` +Fdt = 192.30769230769232 +FF +====================================================================== +FAIL: test_initialize_domain (tests.unit.test_diffusion2d_functions.TestDiffusion2D) +Check function SolveDiffusion2D.initialize_domain +---------------------------------------------------------------------- +Traceback (most recent call last): + File "D:\SSM\exercise\testing-python-exercise-wt2425\tests\unit\test_diffusion2d_functions.py", line 32, in test_initialize_domain + self.assertEqual(solver.ny, 80) +AssertionError: 50 != 80 + +====================================================================== +FAIL: test_initialize_physical_parameters (tests.unit.test_diffusion2d_functions.TestDiffusion2D) +Checks function SolveDiffusion2D.initialize_physical_parameters +---------------------------------------------------------------------- +Traceback (most recent call last): + File "D:\SSM\exercise\testing-python-exercise-wt2425\tests\unit\test_diffusion2d_functions.py", line 47, in test_initialize_physical_parameters + self.assertAlmostEqual(solver.dt, expected_dt, 6) +AssertionError: 192.30769230769232 != 0.192308 within 6 places (192.11538430769232 difference) + +====================================================================== +FAIL: test_set_initial_condition (tests.unit.test_diffusion2d_functions.TestDiffusion2D) +Check function SolveDiffusion2D.set_initial_condition +---------------------------------------------------------------------- +Traceback (most recent call last): + File "D:\SSM\exercise\testing-python-exercise-wt2425\tests\unit\test_diffusion2d_functions.py", line 75, in test_set_initial_condition + self.assertTrue(np.allclose(computed_u, expected_u)) +AssertionError: False is not true + +---------------------------------------------------------------------- +Ran 3 tests in 0.002s + +FAILED (failures=3) +``` + +## integration test log + +``` +======================================================= test session starts ======================================================== +platform win32 -- Python 3.10.11, pytest-8.3.4, pluggy-1.5.0 +rootdir: D:\SSM\exercise\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_domain + """ + solver = SolveDiffusion2D() + + # fixture + w, h, dx, dy = [25., 40., 10., 2.] + solver.initialize_domain(w, h, dx, dy) + d, T_cold, T_hot = [10., 20., 1200.] + solver.initialize_physical_parameters(d, T_cold, T_hot) + expected_dt = pytest.approx(0.192308,abs=1e-6) +> assert expected_dt == solver.dt +E assert 0.192308 ± 1.0e-06 == 1.1923076923076923 +E +E comparison failed +E Obtained: 1.1923076923076923 +E Expected: 0.192308 ± 1.0e-06 + +tests\integration\test_diffusion2d.py:20: AssertionError +------------------------------------------------------- Captured stdout call ------------------------------------------------------- +dt = 1.1923076923076923 +____________________________________________________ test_set_initial_condition ____________________________________________________ + + def test_set_initial_condition(): + """ + Check function SolveDiffusion2D.set_initial_condition + """ + solver = SolveDiffusion2D() + import numpy as np + + # Directly set necessary attributes + solver.dx, solver.dy, solver.nx, solver.ny, solver.T_cold, solver.T_hot = [0.1,0.3,100,130,30.,897] + + # Parameters for the hot circle + r, cx, cy = 2, 5, 5 # Radius and center of the hot circle + r2 = r ** 2 + + # Call the method to generate the computed grid + computed_u = solver.set_initial_condition() + + # Generate the ground truth + expected_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: + expected_u[i, j] = solver.T_hot + + # Assert that the computed and expected grids are the same +> assert np.allclose(computed_u, expected_u) +E AssertionError: assert False +E + where False = (array([[30., 30., 30., ..., 30., 30., 30.],\n [30., 30., 30., ..., 30., 30., 30.],\n [30., 30., 30., ..., 30..., 30., 30.],\n [30., 30., 30., ..., 30., 30., 30.],\n [30., 30., 30., ..., 30., 30., 30.]], shape=(100, 130)), array([[30., 30., 30., ..., 30., 30., 30.],\n [30., 30., 30., ..., 30., 30., 30.],\n [30., 30., 30., ..., 30..., 30., 30.],\n [30., 30., 30., ..., 30., 30., 30.],\n [30., 30., 30., ..., 30., 30., 30.]], shape=(100, 130))) +E + where = .allclose + +tests\integration\test_diffusion2d.py:49: AssertionError +===================================================== short test summary info ====================================================== +FAILED tests/integration/test_diffusion2d.py::test_initialize_physical_parameters - assert 0.192308 ± 1.0e-06 == 1.1923076923076923 +FAILED tests/integration/test_diffusion2d.py::test_set_initial_condition - AssertionError: assert False +======================================================== 2 failed in 0.43s ========================================================= +``` ## Citing diff --git a/coverage-report.pdf b/coverage-report.pdf new file mode 100644 index 00000000..09d04006 Binary files /dev/null and b/coverage-report.pdf differ diff --git a/diffusion2d.py b/diffusion2d.py index 51a07f2d..e4f90345 100644 --- a/diffusion2d.py +++ b/diffusion2d.py @@ -38,6 +38,8 @@ def __init__(self): self.dt = None def initialize_domain(self, w=10., h=10., dx=0.1, dy=0.1): + for input in [w, h, dx, dy]: + assert isinstance(input,float) self.w = w self.h = h self.dx = dx @@ -45,7 +47,9 @@ 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.): + for input in [d, T_cold, T_hot]: + assert isinstance(input, 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..6cdf7cde --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +numpy +matplotlib +pytest \ No newline at end of file diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/integration/test_diffusion2d.py b/tests/integration/test_diffusion2d.py index fd026b40..62968273 100644 --- a/tests/integration/test_diffusion2d.py +++ b/tests/integration/test_diffusion2d.py @@ -3,17 +3,48 @@ """ from diffusion2d import SolveDiffusion2D - +import pytest def test_initialize_physical_parameters(): """ Checks function SolveDiffusion2D.initialize_domain """ solver = SolveDiffusion2D() + + # fixture + w, h, dx, dy = [25., 40., 10., 2.] + solver.initialize_domain(w, h, dx, dy) + d, T_cold, T_hot = [10., 20., 1200.] + solver.initialize_physical_parameters(d, T_cold, T_hot) + expected_dt = pytest.approx(0.192308,abs=1e-6) + assert expected_dt == solver.dt def test_set_initial_condition(): """ - Checks function SolveDiffusion2D.get_initial_function + Check function SolveDiffusion2D.set_initial_condition """ solver = SolveDiffusion2D() + import numpy as np + + # Directly set necessary attributes + solver.dx, solver.dy, solver.nx, solver.ny, solver.T_cold, solver.T_hot = [0.1,0.3,100,130,30.,897] + + # Parameters for the hot circle + r, cx, cy = 2, 5, 5 # Radius and center of the hot circle + r2 = r ** 2 + + # Call the method to generate the computed grid + computed_u = solver.set_initial_condition() + + # Generate the ground truth + expected_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: + expected_u[i, j] = solver.T_hot + + # Assert that the computed and expected grids are the same + assert np.allclose(computed_u, expected_u) + diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/unit/test_diffusion2d_functions.py b/tests/unit/test_diffusion2d_functions.py index c4277ffd..c9b10073 100644 --- a/tests/unit/test_diffusion2d_functions.py +++ b/tests/unit/test_diffusion2d_functions.py @@ -3,24 +3,78 @@ """ from diffusion2d import SolveDiffusion2D +import unittest +from unittest import TestCase +class TestDiffusion2D(TestCase): + def setUp(self): + # fixture + self.data_domain = [25., 40., 0.25, 0.5] + self.data_params = [10., 20., 1200., 10., 2.] + self.data_condition = [1., 1., 10, 10, 300., 700.] -def test_initialize_domain(): - """ - Check function SolveDiffusion2D.initialize_domain - """ - solver = SolveDiffusion2D() + def test_initialize_domain(self): + """ + Check function SolveDiffusion2D.initialize_domain + """ + solver = SolveDiffusion2D() + w, h, dx, dy = self.data_domain + # test + solver.initialize_domain(w, h, dx, dy) + self.assertEqual(solver.w, w) + self.assertEqual(solver.h, h) + self.assertEqual(solver.dx, dx) + self.assertEqual(solver.dy, dy) + self.assertIsInstance(solver.nx, int) + self.assertEqual(solver.nx, 100) + self.assertIsInstance(solver.ny, int) + self.assertEqual(solver.ny, 80) -def test_initialize_physical_parameters(): - """ - Checks function SolveDiffusion2D.initialize_domain - """ - solver = SolveDiffusion2D() + def test_initialize_physical_parameters(self): + """ + Checks function SolveDiffusion2D.initialize_physical_parameters + """ + solver = SolveDiffusion2D() + d, T_cold, T_hot, solver.dx, solver.dy = self.data_params + solver.initialize_physical_parameters(d, T_cold, T_hot) + expected_dt = 0.192308 + # test + self.assertEqual(solver.D, d) + self.assertEqual(solver.T_cold, T_cold) + self.assertEqual(solver.T_hot, T_hot) + self.assertAlmostEqual(solver.dt, expected_dt, 6) -def test_set_initial_condition(): - """ - Checks function SolveDiffusion2D.get_initial_function - """ - solver = SolveDiffusion2D() + def test_set_initial_condition(self): + """ + Check function SolveDiffusion2D.set_initial_condition + """ + solver = SolveDiffusion2D() + import numpy as np + + # Directly set necessary attributes + solver.dx, solver.dy, solver.nx, solver.ny, solver.T_cold, solver.T_hot = self.data_condition + + # Parameters for the hot circle + r, cx, cy = 2, 5, 5 # Radius and center of the hot circle + r2 = r ** 2 + + # Call the method to generate the computed grid + computed_u = solver.set_initial_condition() + + # Generate the ground truth + expected_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: + expected_u[i, j] = solver.T_hot + + # Assert that the computed and expected grids are the same + self.assertTrue(np.allclose(computed_u, expected_u)) + + +if __name__ == "__main__": + # Run the tests + unittest.main() diff --git a/tox.toml b/tox.toml new file mode 100644 index 00000000..44dccb8f --- /dev/null +++ b/tox.toml @@ -0,0 +1,10 @@ +requires = ["tox>=4"] +env_list = ["testing"] + +[env.testing] +description = "Run pytest and unittest" +deps = "-rrequirements.txt" +commands = [ + ["pytest"], + ["python", "-m", "unittest", "discover"] + ] \ No newline at end of file