From 6e07e446afe22503c4a271b6c02fc1ebb8fbf7e3 Mon Sep 17 00:00:00 2001 From: ombahiwal Date: Thu, 16 Jan 2025 03:38:40 +0100 Subject: [PATCH 1/5] Step 2 pytest --- README.md | 99 ++++++++++++++++++ diffusion2d.py | 7 +- ...n2d_functions.cpython-311-pytest-8.3.3.pyc | Bin 0 -> 20641 bytes tests/unit/test_diffusion2d_functions.py | 88 +++++++++++++++- 4 files changed, 191 insertions(+), 3 deletions(-) create mode 100644 tests/unit/__pycache__/test_diffusion2d_functions.cpython-311-pytest-8.3.3.pyc diff --git a/README.md b/README.md index da66993c..f56c022c 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,105 @@ Please follow the instructions in [python_testing_exercise.md](https://github.co ### pytest log +#### Step 2, initial test +``` +============================= test session starts ============================== +collecting ... collected 4 items + +test_diffusion2d_functions.py::test_initialize_domain PASSED [ 25%] +test_diffusion2d_functions.py::test_initialize_domain_test_2 PASSED [ 50%] +test_diffusion2d_functions.py::test_initialize_physical_parameters PASSED [ 75%]dt = 0.0011428571428571432 + +test_diffusion2d_functions.py::test_set_initial_condition PASSED [100%] + +============================== 4 passed in 0.22s =============================== +``` +#### Step 2, fail on purpose +``` +============================= test session starts ============================== +collecting ... collected 4 items + +test_diffusion2d_functions.py::test_initialize_domain FAILED [ 25%] +test_diffusion2d_functions.py:7 (test_initialize_domain) +5 != 10 + +Expected :10 +Actual :5 + + +def test_initialize_domain(): +""" +Check function SolveDiffusion2D.initialize_domain +""" +solver = SolveDiffusion2D() +# test values +w = 20. +h = 10. +dx = 2. +dy = 0.2 + + # call function + solver.initialize_domain(w, h, dx, dy) + + # assertions + assert solver.w == w + assert solver.h == h + assert solver.dx == dx + assert solver.dy == dy + + # expected op +> assert solver.nx == 10 +E assert 5 == 10 +E + where 5 = .nx + +test_diffusion2d_functions.py:29: AssertionError + +test_diffusion2d_functions.py::test_initialize_domain_test_2 FAILED [ 50%] +test_diffusion2d_functions.py:31 (test_initialize_domain_test_2) +6 != 5 + +Expected :5 +Actual :6 + + +def test_initialize_domain_test_2(): +""" +Second testcase for function SolveDiffusion2D.initialize_domain +""" +solver = SolveDiffusion2D() +# Arrange test values +# bad values + + w = 15.2 + h = 17.1 + dx = 2.7 + dy = 0.29 + + # Act (= Perform test action) + solver.initialize_domain(w, h, dx, dy) + + # assersions + assert solver.w == w + assert solver.h == h + assert solver.dx == dx + assert solver.dy == dy + + # expected op +> assert solver.nx == 5 +E assert 6 == 5 +E + where 6 = .nx + +test_diffusion2d_functions.py:54: AssertionError + +test_diffusion2d_functions.py::test_initialize_physical_parameters PASSED [ 75%]dt = 0.0011428571428571432 + +test_diffusion2d_functions.py::test_set_initial_condition PASSED [100%] + +========================= 2 failed, 2 passed in 0.30s ========================== + +Process finished with exit code 1 +``` + ### unittest log ## Citing diff --git a/diffusion2d.py b/diffusion2d.py index 51a07f2d..734f3c17 100644 --- a/diffusion2d.py +++ b/diffusion2d.py @@ -38,14 +38,19 @@ def __init__(self): self.dt = None def initialize_domain(self, w=10., h=10., dx=0.1, dy=0.1): + assert all(map(lambda v: type(v) == float, [w, h, dx, dy])), "All inputs nums must be floats" self.w = w self.h = h self.dx = dx self.dy = dy - self.nx = int(w / dx) + # modified to fail test + self.nx = int(h / dx) self.ny = int(h / dy) def initialize_physical_parameters(self, d=4., T_cold=300, T_hot=700): + assert type(d) == float, "d must be a float" + assert type(T_cold) == float, "T_cold must be a float" + assert type(T_hot) == float, "T_cold must be a float" self.D = d self.T_cold = T_cold self.T_hot = T_hot diff --git a/tests/unit/__pycache__/test_diffusion2d_functions.cpython-311-pytest-8.3.3.pyc b/tests/unit/__pycache__/test_diffusion2d_functions.cpython-311-pytest-8.3.3.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c5a22ff1832c30901631d623d7ea0e4289e82ad GIT binary patch literal 20641 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 literal 0 HcmV?d00001 diff --git a/tests/unit/test_diffusion2d_functions.py b/tests/unit/test_diffusion2d_functions.py index c4277ffd..445d3368 100644 --- a/tests/unit/test_diffusion2d_functions.py +++ b/tests/unit/test_diffusion2d_functions.py @@ -1,22 +1,79 @@ """ Tests for functions in class SolveDiffusion2D """ - +import pytest +import numpy as np from diffusion2d import SolveDiffusion2D - def test_initialize_domain(): """ Check function SolveDiffusion2D.initialize_domain """ solver = SolveDiffusion2D() + # test values + w = 20. + h = 10. + dx = 2. + dy = 0.2 + + # call function + solver.initialize_domain(w, h, dx, dy) + + # assertions + assert solver.w == w + assert solver.h == h + assert solver.dx == dx + assert solver.dy == dy + + # expected op + assert solver.nx == 10 + assert solver.ny == 50 + +def test_initialize_domain_test_2(): + """ + Second testcase for function SolveDiffusion2D.initialize_domain + """ + solver = SolveDiffusion2D() + # Arrange test values + # bad values + w = 15.2 + h = 17.1 + dx = 2.7 + dy = 0.29 + # Act (= Perform test action) + solver.initialize_domain(w, h, dx, dy) + + # assersions + assert solver.w == w + assert solver.h == h + assert solver.dx == dx + assert solver.dy == dy + + # expected op + assert solver.nx == 5 + assert solver.ny == 58 def test_initialize_physical_parameters(): """ Checks function SolveDiffusion2D.initialize_domain """ solver = SolveDiffusion2D() + # Arrange + d = 3.5 + T_cold = 342.4 + T_hot = 723.15 + solver.dx = 0.1 + solver.dy = 0.2 + + # Act + solver.initialize_physical_parameters(d, T_cold, T_hot) + + # Assert + assert solver.D == d + assert solver.T_cold == T_cold + assert solver.T_hot == T_hot + assert solver.dt == pytest.approx(0.001142, abs=1e-6) def test_set_initial_condition(): @@ -24,3 +81,30 @@ def test_set_initial_condition(): Checks function SolveDiffusion2D.get_initial_function """ solver = SolveDiffusion2D() + # arranve values + solver.nx = 100 + solver.ny = 50 + solver.dx = 0.1 + solver.dy = 0.2 + solver.T_cold = 100. + solver.T_hot = 600. + + # call + u: np.ndarray = solver.set_initial_condition() + + # assersion + + # Domain has expected dimensions + assert u.shape[0] == solver.nx + assert u.shape[1] == solver.ny + + # center is hot and border is cold + assert u[0][0] == 100. + assert u[99][0] == 100. + assert u[0][49] == 100. + assert u[99][49] == 100. + + assert u[49][24] == 600. + assert u[50][24] == 600. + assert u[49][25] == 600. + assert u[50][25] == 600. \ No newline at end of file From 39ce77e393c364582e10b4c83516d17ac21b6097 Mon Sep 17 00:00:00 2001 From: ombahiwal Date: Thu, 16 Jan 2025 03:48:27 +0100 Subject: [PATCH 2/5] Step 4: unittests --- diffusion2d.py | 9 +- tests/unit/test_diffusion2d_functions.py | 214 ++++++++++++----------- 2 files changed, 116 insertions(+), 107 deletions(-) diff --git a/diffusion2d.py b/diffusion2d.py index 734f3c17..e6f8fc7a 100644 --- a/diffusion2d.py +++ b/diffusion2d.py @@ -43,7 +43,7 @@ def initialize_domain(self, w=10., h=10., dx=0.1, dy=0.1): self.h = h self.dx = dx self.dy = dy - # modified to fail test + # Purposely break self.nx = int(h / dx) self.ny = int(h / dy) @@ -51,7 +51,8 @@ def initialize_physical_parameters(self, d=4., T_cold=300, T_hot=700): assert type(d) == float, "d must be a float" assert type(T_cold) == float, "T_cold must be a float" assert type(T_hot) == float, "T_cold must be a float" - self.D = d + # Purposely break + # self.D = d self.T_cold = T_cold self.T_hot = T_hot @@ -66,7 +67,9 @@ def set_initial_condition(self): # Initial conditions - circle of radius r centred at (cx,cy) (mm) r, cx, cy = 2, 5, 5 - r2 = r ** 2 + # purposely break + r2 = 0 + # r2 = r ** 2 for i in range(self.nx): for j in range(self.ny): p2 = (i * self.dx - cx) ** 2 + (j * self.dy - cy) ** 2 diff --git a/tests/unit/test_diffusion2d_functions.py b/tests/unit/test_diffusion2d_functions.py index 445d3368..daad16de 100644 --- a/tests/unit/test_diffusion2d_functions.py +++ b/tests/unit/test_diffusion2d_functions.py @@ -4,107 +4,113 @@ import pytest import numpy as np from diffusion2d import SolveDiffusion2D - -def test_initialize_domain(): - """ - Check function SolveDiffusion2D.initialize_domain - """ - solver = SolveDiffusion2D() - # test values - w = 20. - h = 10. - dx = 2. - dy = 0.2 - - # call function - solver.initialize_domain(w, h, dx, dy) - - # assertions - assert solver.w == w - assert solver.h == h - assert solver.dx == dx - assert solver.dy == dy - - # expected op - assert solver.nx == 10 - assert solver.ny == 50 - -def test_initialize_domain_test_2(): - """ - Second testcase for function SolveDiffusion2D.initialize_domain - """ - solver = SolveDiffusion2D() - # Arrange test values - # bad values - w = 15.2 - h = 17.1 - dx = 2.7 - dy = 0.29 - - # Act (= Perform test action) - solver.initialize_domain(w, h, dx, dy) - - # assersions - assert solver.w == w - assert solver.h == h - assert solver.dx == dx - assert solver.dy == dy - - # expected op - assert solver.nx == 5 - assert solver.ny == 58 - -def test_initialize_physical_parameters(): - """ - Checks function SolveDiffusion2D.initialize_domain - """ - solver = SolveDiffusion2D() - # Arrange - d = 3.5 - T_cold = 342.4 - T_hot = 723.15 - solver.dx = 0.1 - solver.dy = 0.2 - - # Act - solver.initialize_physical_parameters(d, T_cold, T_hot) - - # Assert - assert solver.D == d - assert solver.T_cold == T_cold - assert solver.T_hot == T_hot - assert solver.dt == pytest.approx(0.001142, abs=1e-6) - - -def test_set_initial_condition(): - """ - Checks function SolveDiffusion2D.get_initial_function - """ - solver = SolveDiffusion2D() - # arranve values - solver.nx = 100 - solver.ny = 50 - solver.dx = 0.1 - solver.dy = 0.2 - solver.T_cold = 100. - solver.T_hot = 600. - - # call - u: np.ndarray = solver.set_initial_condition() - - # assersion - - # Domain has expected dimensions - assert u.shape[0] == solver.nx - assert u.shape[1] == solver.ny - - # center is hot and border is cold - assert u[0][0] == 100. - assert u[99][0] == 100. - assert u[0][49] == 100. - assert u[99][49] == 100. - - assert u[49][24] == 600. - assert u[50][24] == 600. - assert u[49][25] == 600. - assert u[50][25] == 600. \ No newline at end of file +from unittest import TestCase +import unittest + +class TestDiffusion2D(unittest.TestCase): + + def setUp(self): + self.solver = SolveDiffusion2D() + def test_initialize_domain(self): + """ + Check function SolveDiffusion2D.initialize_domain + """ + solver = SolveDiffusion2D() + # test values + w = 20. + h = 10. + dx = 2. + dy = 0.2 + + # call function + solver.initialize_domain(w, h, dx, dy) + + # assertions + assert solver.w == w + assert solver.h == h + assert solver.dx == dx + assert solver.dy == dy + + # expected op + assert solver.nx == 10 + assert solver.ny == 50 + + def test_initialize_domain_test_2(self): + """ + Second testcase for function SolveDiffusion2D.initialize_domain + """ + solver = SolveDiffusion2D() + # Arrange test values + # bad values + w = 15.2 + h = 17.1 + dx = 2.7 + dy = 0.29 + + # Act (= Perform test action) + solver.initialize_domain(w, h, dx, dy) + + # assersions + assert solver.w == w + assert solver.h == h + assert solver.dx == dx + assert solver.dy == dy + + # expected op + assert solver.nx == 5 + assert solver.ny == 58 + + def test_initialize_physical_parameters(self): + """ + Checks function SolveDiffusion2D.initialize_domain + """ + solver = SolveDiffusion2D() + # Arrange + d = 3.5 + T_cold = 342.4 + T_hot = 723.15 + solver.dx = 0.1 + solver.dy = 0.2 + + # Act + solver.initialize_physical_parameters(d, T_cold, T_hot) + + # Assert + assert solver.D == d + assert solver.T_cold == T_cold + assert solver.T_hot == T_hot + assert solver.dt == pytest.approx(0.001142, abs=1e-6) + + + def test_set_initial_condition(self): + """ + Checks function SolveDiffusion2D.get_initial_function + """ + solver = SolveDiffusion2D() + # arranve values + solver.nx = 100 + solver.ny = 50 + solver.dx = 0.1 + solver.dy = 0.2 + solver.T_cold = 100. + solver.T_hot = 600. + + # call + u: np.ndarray = solver.set_initial_condition() + + # assersion + + # Domain has expected dimensions + assert u.shape[0] == solver.nx + assert u.shape[1] == solver.ny + + # center is hot and border is cold + assert u[0][0] == 100. + assert u[99][0] == 100. + assert u[0][49] == 100. + assert u[99][49] == 100. + + assert u[49][24] == 600. + assert u[50][24] == 600. + assert u[49][25] == 600. + assert u[50][25] == 600. \ No newline at end of file From 868589ae654611bab1a4c3d5d82eaf51af2a2ff3 Mon Sep 17 00:00:00 2001 From: ombahiwal Date: Thu, 16 Jan 2025 03:57:21 +0100 Subject: [PATCH 3/5] step 5 --- README.md | 266 +++++++++++++++++++++++++- diffusion2d.py | 4 +- tests/integration/test_diffusion2d.py | 29 ++- 3 files changed, 292 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f56c022c..fdf0d4fd 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Please follow the instructions in [python_testing_exercise.md](https://github.co ### pytest log -#### Step 2, initial test +#### Step 3, initial test ``` ============================= test session starts ============================== collecting ... collected 4 items @@ -19,11 +19,11 @@ test_diffusion2d_functions.py::test_set_initial_condition PASSED [100%] ============================== 4 passed in 0.22s =============================== ``` -#### Step 2, fail on purpose +#### Step 3, fail on purpose ``` ============================= test session starts ============================== collecting ... collected 4 items - +# test_diffusion2d_functions.py::test_initialize_domain FAILED [ 25%] test_diffusion2d_functions.py:7 (test_initialize_domain) 5 != 10 @@ -106,7 +106,267 @@ Process finished with exit code 1 ``` ### unittest log +#### Step 4: purposely break all unit tests +``` +Launching pytest with arguments /Users/ombahiwal/Desktop/WS24/Courses_WS24/Simulation Software Engineering/Exercises/05_testing_ci/testing-python-exercise-wt2425/tests/unit/test_diffusion2d_functions.py --no-header --no-summary -q in /Users/ombahiwal/Desktop/WS24/Courses_WS24/Simulation Software Engineering/Exercises/05_testing_ci/testing-python-exercise-wt2425/tests/unit + +============================= test session starts ============================== +collecting ... collected 4 items + +test_diffusion2d_functions.py::TestDiffusion2D::test_initialize_domain +test_diffusion2d_functions.py::TestDiffusion2D::test_initialize_domain_test_2 +test_diffusion2d_functions.py::TestDiffusion2D::test_initialize_physical_parameters +test_diffusion2d_functions.py::TestDiffusion2D::test_set_initial_condition + +============================== 4 failed in 0.28s =============================== +FAILED [ 25%] +test_diffusion2d_functions.py:13 (TestDiffusion2D.test_initialize_domain) +5 != 10 + +Expected :10 +Actual :5 + + +self = + + def test_initialize_domain(self): + """ + Check function SolveDiffusion2D.initialize_domain + """ + solver = SolveDiffusion2D() + # test values + w = 20. + h = 10. + dx = 2. + dy = 0.2 + + # call function + solver.initialize_domain(w, h, dx, dy) + + # assertions + assert solver.w == w + assert solver.h == h + assert solver.dx == dx + assert solver.dy == dy + + # expected op +> assert solver.nx == 10 +E assert 5 == 10 +E + where 5 = .nx + +test_diffusion2d_functions.py:35: AssertionError +FAILED [ 50%] +test_diffusion2d_functions.py:37 (TestDiffusion2D.test_initialize_domain_test_2) +6 != 5 + +Expected :5 +Actual :6 + + +self = + + def test_initialize_domain_test_2(self): + """ + Second testcase for function SolveDiffusion2D.initialize_domain + """ + solver = SolveDiffusion2D() + # Arrange test values + # bad values + w = 15.2 + h = 17.1 + dx = 2.7 + dy = 0.29 + + # Act (= Perform test action) + solver.initialize_domain(w, h, dx, dy) + + # assersions + assert solver.w == w + assert solver.h == h + assert solver.dx == dx + assert solver.dy == dy + + # expected op +> assert solver.nx == 5 +E assert 6 == 5 +E + where 6 = .nx + +test_diffusion2d_functions.py:60: AssertionError +FAILED [ 75%] +test_diffusion2d_functions.py:62 (TestDiffusion2D.test_initialize_physical_parameters) +self = + + def test_initialize_physical_parameters(self): + """ + Checks function SolveDiffusion2D.initialize_domain + """ + solver = SolveDiffusion2D() + # Arrange + d = 3.5 + T_cold = 342.4 + T_hot = 723.15 + solver.dx = 0.1 + solver.dy = 0.2 + + # Act +> solver.initialize_physical_parameters(d, T_cold, T_hot) + +test_diffusion2d_functions.py:76: +_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + +self = , d = 3.5 +T_cold = 342.4, T_hot = 723.15 + + def initialize_physical_parameters(self, d=4., T_cold=300, T_hot=700): + assert type(d) == float, "d must be a float" + assert type(T_cold) == float, "T_cold must be a float" + assert type(T_hot) == float, "T_cold must be a float" + # Purposely break + # self.D = d + self.T_cold = T_cold + self.T_hot = T_hot + + # Computing a stable time step + dx2, dy2 = self.dx * self.dx, self.dy * self.dy +> self.dt = dx2 * dy2 / (2 * self.D * (dx2 + dy2)) +E TypeError: unsupported operand type(s) for *: 'int' and 'NoneType' + +../../diffusion2d.py:61: TypeError +FAILED [100%] +test_diffusion2d_functions.py:84 (TestDiffusion2D.test_set_initial_condition) +np.float64(100.0) != 600.0 + +Expected :600.0 +Actual :np.float64(100.0) + + +self = + + def test_set_initial_condition(self): + """ + Checks function SolveDiffusion2D.get_initial_function + """ + solver = SolveDiffusion2D() + # arranve values + solver.nx = 100 + solver.ny = 50 + solver.dx = 0.1 + solver.dy = 0.2 + solver.T_cold = 100. + solver.T_hot = 600. + + # call + u: np.ndarray = solver.set_initial_condition() + + # assersion + + # Domain has expected dimensions + assert u.shape[0] == solver.nx + assert u.shape[1] == solver.ny + + # center is hot and border is cold + assert u[0][0] == 100. + assert u[99][0] == 100. + assert u[0][49] == 100. + assert u[99][49] == 100. + +> assert u[49][24] == 600. +E assert np.float64(100.0) == 600.0 + +test_diffusion2d_functions.py:113: AssertionError + +Process finished with exit code 1 + +``` + +### Step 5: Integration pytest +``` +============================= test session starts ============================== +collecting ... collected 2 items + +test_diffusion2d.py::test_initialize_physical_parameters PASSED [ 50%]dt = 0.0016666666666666672 + +test_diffusion2d.py::test_set_initial_condition PASSED [100%]dt = 0.09259259259259259 + + +============================== 2 passed in 0.24s =============================== + + +============================= test session starts ============================== +collecting ... collected 2 items + +test_diffusion2d.py::test_initialize_physical_parameters FAILED [ 50%] +test_diffusion2d.py:7 (test_initialize_physical_parameters) +def test_initialize_physical_parameters(): + """ + Checks function SolveDiffusion2D.initialize_domain + """ + solver = SolveDiffusion2D() + solver.initialize_domain(10., 20., 0.2, 0.1) +> solver.initialize_physical_parameters(2.4, 0., 1.) + +test_diffusion2d.py:14: +_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + +self = , d = 2.4 +T_cold = 0.0, T_hot = 1.0 + + def initialize_physical_parameters(self, d=4., T_cold=300, T_hot=700): + assert type(d) == float, "d must be a float" + assert type(T_cold) == float, "T_cold must be a float" + assert type(T_hot) == float, "T_cold must be a float" + # Purposely break + # self.D = d + self.T_cold = T_cold + self.T_hot = T_hot + + # Computing a stable time step + dx2, dy2 = self.dx * self.dx, self.dy * self.dy +> self.dt = dx2 * dy2 / (2 * self.D * (dx2 + dy2)) +E TypeError: unsupported operand type(s) for *: 'int' and 'NoneType' + +../../diffusion2d.py:61: TypeError + +test_diffusion2d.py::test_set_initial_condition FAILED [100%] +test_diffusion2d.py:19 (test_set_initial_condition) +def test_set_initial_condition(): + """ + Checks function SolveDiffusion2D.get_initial_function + """ + solver = SolveDiffusion2D() + solver.initialize_domain(10., 10., 1., 1.) +> solver.initialize_physical_parameters(2.7, 0., 1.) + +test_diffusion2d.py:26: +_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + +self = , d = 2.7 +T_cold = 0.0, T_hot = 1.0 + + def initialize_physical_parameters(self, d=4., T_cold=300, T_hot=700): + assert type(d) == float, "d must be a float" + assert type(T_cold) == float, "T_cold must be a float" + assert type(T_hot) == float, "T_cold must be a float" + # Purposely break + # self.D = d + self.T_cold = T_cold + self.T_hot = T_hot + + # Computing a stable time step + dx2, dy2 = self.dx * self.dx, self.dy * self.dy +> self.dt = dx2 * dy2 / (2 * self.D * (dx2 + dy2)) +E TypeError: unsupported operand type(s) for *: 'int' and 'NoneType' + +../../diffusion2d.py:61: TypeError + + +============================== 2 failed in 0.27s =============================== + +Process finished with exit code 1 + +``` +#### Step 6 : Coverage ## 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/diffusion2d.py b/diffusion2d.py index e6f8fc7a..65c7cf74 100644 --- a/diffusion2d.py +++ b/diffusion2d.py @@ -43,8 +43,8 @@ def initialize_domain(self, w=10., h=10., dx=0.1, dy=0.1): self.h = h self.dx = dx self.dy = dy - # Purposely break - self.nx = int(h / dx) + # Purposely break (h) + self.nx = int(w / dx) self.ny = int(h / dy) def initialize_physical_parameters(self, d=4., T_cold=300, T_hot=700): diff --git a/tests/integration/test_diffusion2d.py b/tests/integration/test_diffusion2d.py index fd026b40..d3bfdcab 100644 --- a/tests/integration/test_diffusion2d.py +++ b/tests/integration/test_diffusion2d.py @@ -3,17 +3,42 @@ """ from diffusion2d import SolveDiffusion2D - +import pytest def test_initialize_physical_parameters(): """ Checks function SolveDiffusion2D.initialize_domain """ solver = SolveDiffusion2D() - + solver.initialize_domain(10., 20., 0.2, 0.1) + solver.initialize_physical_parameters(2.4, 0., 1.) + dx2 = 0.04 + dy2 = 0.01 + # dt = 0.0004 / (2*2.4*0.05) = 1/600 = 0.0016666 + assert solver.dt == pytest.approx(0.001666, abs=1e-6) def test_set_initial_condition(): """ Checks function SolveDiffusion2D.get_initial_function """ solver = SolveDiffusion2D() + solver.initialize_domain(10., 10., 1., 1.) + solver.initialize_physical_parameters(2.7, 0., 1.) + u = solver.set_initial_condition() + + expected_array = [ + [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], + [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], + [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], + [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], + [0., 0., 0., 0., 1., 1., 1., 0., 0., 0.], + [0., 0., 0., 0., 1., 1., 1., 0., 0., 0.], + [0., 0., 0., 0., 1., 1., 1., 0., 0., 0.], + [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], + [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], + [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], + ] + + for x in range(u.shape[0]): + for y in range(u.shape[1]): + assert expected_array[x][y] == u[x, y], f"Values at {x}, {y} do not match" From 67aaf3546837269560d54e260a78d26ff29d0039 Mon Sep 17 00:00:00 2001 From: ombahiwal Date: Thu, 16 Jan 2025 04:17:41 +0100 Subject: [PATCH 4/5] step 5, 6, 7, 8 --- .coverage | Bin 0 -> 53248 bytes README.md | 1 + Test Results - .html | 661 +++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 4 + requirements.txt | 2 + tox.toml | 12 + 6 files changed, 680 insertions(+) create mode 100644 .coverage create mode 100644 Test Results - .html create mode 100644 pyproject.toml create mode 100644 requirements.txt create mode 100644 tox.toml diff --git a/.coverage b/.coverage new file mode 100644 index 0000000000000000000000000000000000000000..238d1cbb4052ade29bcebcdb1e869a9f19430359 GIT binary patch literal 53248 zcmeI)O>Y}T7zglOyY8Mf!d1v#$>J z4-drQ{-=)*ggz&BD}uJYJ+UvM@Jx(UBnIA42`}h-u1vh(NF>L~q#nnr&kG%$qos}$ zw$uE)*Y*08D^W*O#3=H78C{4U)I}>zklig&=ZQW+g(&YR;1psv%ia``8mLGGu8MUn zcD;VH(tPn##i?&>*q178lZ;&YTAgbRoyeQ=Xg~$IVbtf^_aYg%$0}|KIc=dEQa#TT z-P$Ph?^#%E(i^4o{?`&nbSH4W4}k_-;ezfcMj#yH%`JuITz(k!mP2c-8VP%W!~Po?lk1w zqdM0(@J_~R+W9S!=WM0T2*Q@&MoQ=yb}Z`oYek(3yrnw=>#gjYGZ#XpCvTWW%_U#S zcpRCDZYSGWnK-wc`sSuR(IbNAC4SwWYXqOk zhrpGE;PtCNlF6~SUUxoC6>r=w)j!%?RB^6Cx5MwH7vC1rDqn7;`aVti{3^~>na|`^ z{z6^soysB2CL`%ZG-PQG)+>PEgndbgWiK2jY5ekG8lJrN`$G`znI zlz4Wmt`(uckkMhaW)wBJkyP7QTL^(c6L~p3z91r^LTke6E1z)nT->+o8jO?eFvW0 zbPx8lf=QKq)~Pi42YkEsuSH+jAOHafKmY;|fB*y_009U<00IzLK7pcLupR#Szfk+j zs{KuG*dPD_2tWV=5P$##AOHafKmY;|cq;{}h2ou>`3sNx>vnN_EBhOO_uCKKo%82- z*Qd#_0|5v?00Izz00bZa0SG_<0uX?}5(@D1fBH}Vut5L<5P$##AOHafKmY;|fB*y_ zu*3p*{=dYXi>5&U0uX=z1Rwwb2tWV=5P$##G66jQM<_r50uX=z1Rwwb2tWV=5P$## zmR|tR|Chgy(LxA700Izz00bZa0SG_<0uX=zp8q2TAOHafKmY;|fB*y_009U<00PS| zfam|q-^XYn1Rwwb2tWV=5P$##AOHafKmgDG5d#o_00bZa0SG_<0uX=z1Rwx` + + + + Test Results — + + + + + + + + + +
+ +
+
    +
  • + +
    17 ms
    +
    test_diffusion2d_functions
    +
      +
    • + +
      17 ms
      +
      TestDiffusion2D
      +
        +
      • + +
        0 ms
        +
        passedtest_initialize_domain
        +
          +
        • + PASSED [ 25%]
          +
        • +
        +
      • +
      • + +
        0 ms
        +
        passedtest_initialize_domain_test_2
        +
          +
        • + PASSED [ 50%]
          +
        • +
        +
      • +
      • + +
        0 ms
        +
        failedtest_initialize_physical_parameters
        +
          +
        • + FAILED [ 75%]
          +
        • +
        • + test_diffusion2d_functions.py:62 (TestDiffusion2D.test_initialize_physical_parameters)self =
          def test_initialize_physical_parameters(self):
          """
          Checks function SolveDiffusion2D.initialize_domain
          """
          solver = SolveDiffusion2D()
          # Arrange
          d = 3.5
          T_cold = 342.4
          T_hot = 723.15
          solver.dx = 0.1
          solver.dy = 0.2

          # Act
          > solver.initialize_physical_parameters(d, T_cold, T_hot)
          test_diffusion2d_functions.py:76:
          _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
          self = , d = 3.5
          T_cold = 342.4, T_hot = 723.15
          def initialize_physical_parameters(self, d=4., T_cold=300, T_hot=700):
          assert type(d) == float, "d must be a float"
          assert type(T_cold) == float, "T_cold must be a float"
          assert type(T_hot) == float, "T_cold must be a float"
          # Purposely break
          # self.D = d
          self.T_cold = T_cold
          self.T_hot = T_hot

          # Computing a stable time step
          dx2, dy2 = self.dx * self.dx, self.dy * self.dy
          > self.dt = dx2 * dy2 / (2 * self.D * (dx2 + dy2))
          E TypeError: unsupported operand type(s) for *: 'int' and 'NoneType'
          ../../diffusion2d.py:61: TypeError
          +
        • +
        +
      • +
      • + +
        17 ms
        +
        failedtest_set_initial_condition
        +
          +
        • + FAILED [100%]
          +
        • +
        • + test_diffusion2d_functions.py:84 (TestDiffusion2D.test_set_initial_condition)
          np.float64(100.0) != 600.0
          self =
          def test_set_initial_condition(self):
          """
          Checks function SolveDiffusion2D.get_initial_function
          """
          solver = SolveDiffusion2D()
          # arranve values
          solver.nx = 100
          solver.ny = 50
          solver.dx = 0.1
          solver.dy = 0.2
          solver.T_cold = 100.
          solver.T_hot = 600.

          # call
          u: np.ndarray = solver.set_initial_condition()

          # assersion

          # Domain has expected dimensions
          assert u.shape[0] == solver.nx
          assert u.shape[1] == solver.ny

          # center is hot and border is cold
          assert u[0][0] == 100.
          assert u[99][0] == 100.
          assert u[0][49] == 100.
          assert u[99][49] == 100.

          > assert u[49][24] == 600.
          E assert np.float64(100.0) == 600.0
          test_diffusion2d_functions.py:113: AssertionError
          +
        • +
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..b529b41d --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,4 @@ +[ pyproject.toml] + +[tool.pytest.ini_options] +pythonpath = "." \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..ac3f2889 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +numpy>=1.15.0 +matplotlib>=3.0.0 \ No newline at end of file diff --git a/tox.toml b/tox.toml new file mode 100644 index 00000000..874a35bd --- /dev/null +++ b/tox.toml @@ -0,0 +1,12 @@ +requires = ["tox>=4"] +env_list = ["pytest", "unittest"] + +[env.pytest] +description = "Run pytest" +deps = ["pytest>=8", "-r requirements.txt"] +commands = [["pytest", "tests/integration/test_diffusion2d.py"]] + +[env.unittest] +description = "Run unittest" +deps = ["-r requirements.txt"] +commands = [["python3", "-m", "unittest", "tests/unit/test_diffusion2d_functions.py"]] \ No newline at end of file From 27a177d6dee80c0c8a437633d2cac78e580e5d96 Mon Sep 17 00:00:00 2001 From: ombahiwal Date: Mon, 3 Feb 2025 04:35:18 +0100 Subject: [PATCH 5/5] feedback changes --- .coverage | Bin 53248 -> 53248 bytes README.md | 14 ++++++++++++++ diffusion2d.py | 8 ++++---- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/.coverage b/.coverage index 238d1cbb4052ade29bcebcdb1e869a9f19430359..7aa54736e17c8e05bdde5c0920952787ed2f3c87 100644 GIT binary patch delta 898 zcmZozz}&Ead4e<}*F+g-My`zsOYFIr`BpOUxAUv=t=udqFq^NwikXF>u~I*@IJKx) zKR-7qF(b1)F-PAewK%&Zzd%1c*vLdTCqEe|RFqn*Tb!AzTb!z2l3HAnnU}6xP+5|Z zpQoEzky@0TS)8g{USecoWD1rp)-TP=ECDm)Q!>-iN{ch|^NdpB(@OJ_OMuK`y@JXF zCYE}JMpx=uj$|3oigHGv_lj}bkWRk;GV@AO(~A;8p26@Y&}J?M1_oxnRSf)U{2hF& zfPp=SufCe4v62zDW5{<4;jm^-WNEB-rLyIyVa-&|(pb!i$9oZErzHYmy-DCNKQA)_ zFDT3z`TsER|Jf|)@Sa~36a~z@oV*~K{|E#B7yeuPM}SeWjo(XznT3&4i}_ROmnV@= zPHuiNS^XF1XE_Nbpr{d3lVqBj=l;E$m+fbAU|?hfYG>hMWZ~qLNct%H{=W=3YWd$X g@c#yy_!em1eSTp!phiY!W-!IX!~#^zxyZo)0Jh^Wo&W#< delta 33 lcmZozz}&Ead4e<}=R_H2M$U~1OYAqZEcm0pXoCU-0RY7v48i~a diff --git a/README.md b/README.md index 898d1595..a97093e1 100644 --- a/README.md +++ b/README.md @@ -366,6 +366,20 @@ Process finished with exit code 1 ``` +#### New Output +``` +./venv/bin/python3 -m pytest +========================================================================== test session starts ========================================================================== +platform darwin -- Python 3.9.6, pytest-8.3.4, pluggy-1.5.0 +rootdir: /Users/ombahiwal/Desktop/WS24-local/res-sim-se/testing-python-exercise-wt2425 +configfile: pyproject.toml +collected 6 items + +tests/integration/test_diffusion2d.py .. [ 33%] +tests/unit/test_diffusion2d_functions.py .... [100%] + +=========================================================================== 6 passed in 0.31s =========================================================================== +``` #### Step 6 : Coverage ## Citing diff --git a/diffusion2d.py b/diffusion2d.py index 65c7cf74..e72a0640 100644 --- a/diffusion2d.py +++ b/diffusion2d.py @@ -47,13 +47,13 @@ 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.0, T_hot=700.0): assert type(d) == float, "d must be a float" assert type(T_cold) == float, "T_cold must be a float" assert type(T_hot) == float, "T_cold must be a float" # Purposely break - # self.D = d - self.T_cold = T_cold + self.D = d + self.T_cold = float(T_cold) self.T_hot = T_hot # Computing a stable time step @@ -69,7 +69,7 @@ def set_initial_condition(self): r, cx, cy = 2, 5, 5 # purposely break r2 = 0 - # r2 = r ** 2 + r2 = r ** 2 for i in range(self.nx): for j in range(self.ny): p2 = (i * self.dx - cx) ** 2 + (j * self.dy - cy) ** 2