diff --git a/README.md b/README.md index da66993c..1ca2abad 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,366 @@ Please follow the instructions in [python_testing_exercise.md](https://github.co ## Test logs (for submission) ### pytest log +#### Changing self.nx = int(w / dx) to self.nx = int(h / dx) + + pytest tests/unit/test_diffusion2d_functions.py +>> +================================================== test session starts ================================================== +platform win32 -- Python 3.12.8, pytest-8.3.4, pluggy-1.5.0 +rootdir: C:\Projects\testing-python-exercise-wt2425 +collected 3 items + +tests\unit\test_diffusion2d_functions.py F.. [100%] + +======================================================= FAILURES ======================================================== +________________________________________________ test_initialize_domain _________________________________________________ + + def test_initialize_domain(): + """ + Check function SolveDiffusion2D.initialize_domain + """ + solver = SolveDiffusion2D() + # Arrange + w, h, dx, dy = 10.0, 20.0, 0.5, 0.5 + expected_nx, expected_ny = int(w / dx), int(h / dy) + + # Act + solver.initialize_domain(w, h, dx, dy) + + # Assert +> assert solver.nx == expected_nx +E assert 40 == 20 +E + where 40 = .nx + +tests\unit\test_diffusion2d_functions.py:21: AssertionError +================================================ short test summary info ================================================ +FAILED tests/unit/test_diffusion2d_functions.py::test_initialize_domain - assert 40 == 20 +============================================== 1 failed, 2 passed in 0.71s ============================================== + + +#### Changing self.dt = dx2 * dy2 / (2 * self.D * (dx2 + dy2)) to self.dt = dx2 * dy2 / (self.D * (dx2 + dy2)) + + +platform win32 -- Python 3.12.8, pytest-8.3.4, pluggy-1.5.0 +rootdir: C:\Projects\testing-python-exercise-wt2425 +collected 3 items + +tests\unit\test_diffusion2d_functions.py .F. [100%] + +======================================================= FAILURES ======================================================== +__________________________________________ test_initialize_physical_parameters __________________________________________ + + def test_initialize_physical_parameters(): + """ + Checks function SolveDiffusion2D.initialize_domain + """ + solver = SolveDiffusion2D() + d = 4.0 # Diffusivity, analogous to alpha + dx = 0.1 # Grid spacing in the x-direction + dy = 0.1 # Grid spacing in the y-direction + + # Calculate expected dt manually using the formula + dx2, dy2 = dx * dx, dy * dy + dt_expected = dx2 * dy2 / (2 * d * (dx2 + dy2)) + + # Set the dx and dy values manually in the solver (since we're testing only initialize_physical_parameters) + solver.dx = dx + solver.dy = dy + + # Call the function to test + solver.initialize_physical_parameters(d) + + # Assert that the actual dt matches the expected value +> assert solver.dt == pytest.approx(dt_expected, rel=1e-9), f"Expected dt = {dt_expected}, but got {solver.dt}" +E AssertionError: Expected dt = 0.0006250000000000001, but got 0.0012500000000000002 +E assert 0.0012500000000000002 == 0.00062500000...0001 ± 1.0e-12 +E +E comparison failed +E Obtained: 0.0012500000000000002 +E Expected: 0.0006250000000000001 ± 1.0e-12 + +tests\unit\test_diffusion2d_functions.py:47: AssertionError +------------------------------------------------- Captured stdout call -------------------------------------------------- +dt = 0.0012500000000000002 +================================================ short test summary info ================================================ +FAILED tests/unit/test_diffusion2d_functions.py::test_initialize_physical_parameters - AssertionError: Expected dt = 0.0006250000000000001, but got 0.0012500000000000002 +============================================== 1 failed, 2 passed in 0.81s ============================================== + + +#### Changing if p2 < r2 to if p2 <= r2 + +platform win32 -- Python 3.12.8, pytest-8.3.4, pluggy-1.5.0 +rootdir: C:\Projects\testing-python-exercise-wt2425 +collected 3 items + +tests\unit\test_diffusion2d_functions.py ..F [100%] + +======================================================= FAILURES ======================================================== +______________________________________________ test_set_initial_condition _______________________________________________ + + def test_set_initial_condition(): + """ + Checks function SolveDiffusion2D.get_initial_function + """ + solver = SolveDiffusion2D() + T_hot = 100.0 # Hot temperature + T_cold = 0.0 # Cold temperature + dx = 1.0 # Spacing in the x-direction + dy = 1.0 # Spacing in the y-direction + nx = 10 # Number of points in x-direction + ny = 10 + + + solver.nx = nx + solver.ny = ny + solver.dx = dx + solver.dy = dy + solver.T_hot = T_hot + solver.T_cold = T_cold + + # Step 3: Call the function to set initial conditions + u = solver.set_initial_condition() + + # Step 4: Manually compute the expected u array + # Expected u array should have a circle of T_hot with radius r=2 at center (cx, cy) = (5, 5) + expected_u = T_cold * np.ones((ny, nx)) # Start with all values as T_cold + r = 2 + cx, cy = 5, 5 + r2 = r ** 2 # r^2 for comparison + for i in range(nx): + for j in range(ny): + p2 = (i * dx - cx) ** 2 + (j * dy - cy) ** 2 # Compute distance squared + if p2 < r2: + expected_u[j, i] = T_hot # Set the circle region to T_hot + + # Step 5: Assert that the generated u array matches the expected u array +> np.testing.assert_array_equal(u, expected_u, err_msg="Initial condition field is not correct.") + +tests\unit\test_diffusion2d_functions.py:86: +_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + +args = (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.]])) +kwargs = {'err_msg': 'Initial condition field is not correct.'}, 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 Initial condition field is not correct. +E Mismatched elements: 4 / 100 (4%) +E Max absolute difference among violations: 100. +E Max relative difference among violations: inf +E ACTUAL: array([[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], +E [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], +E [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],... +E DESIRED: array([[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], +E [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], +E [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],... + +venv\Lib\site-packages\numpy\_utils\__init__.py:85: AssertionError +================================================ short test summary info ================================================ +FAILED tests/unit/test_diffusion2d_functions.py::test_set_initial_condition - AssertionError: +============================================== 1 failed, 2 passed in 0.74s ============================================== ### unittest log +#### Changing self.nx = int(w / dx) to self.nx = int(h / dx) + + +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:\Projects\testing-python-exercise-wt2425\tests\unit\test_diffusion2d_functions.py", line 23, in test_initialize_domain + self.assertEqual(self.solver.nx, expected_nx, f"Expected nx = {expected_nx}, but got {self.solver.nx}") +AssertionError: 40 != 20 : Expected nx = 20, but got 40 + +---------------------------------------------------------------------- +Ran 3 tests in 0.109s + +FAILED (failures=1) + + +#### Changing self.dt = dx2 * dy2 / (2 * self.D * (dx2 + dy2)) to self.dt = dx2 * dy2 / (self.D * (dx2 + dy2)) + +FAIL: test_initialize_physical_parameters (tests.unit.test_diffusion2d_functions.TestDiffusion2D.test_initialize_physical_parameters) +Checks function SolveDiffusion2D.initialize_domain +---------------------------------------------------------------------- +Traceback (most recent call last): + File "C:\Projects\testing-python-exercise-wt2425\tests\unit\test_diffusion2d_functions.py", line 47, in test_initialize_physical_parameters + self.assertAlmostEqual(self.solver.dt, dt_expected, delta=1e-9, msg=f"Expected dt = {dt_expected}, but got {self.solver.dt}") +AssertionError: 0.0012500000000000002 != 0.0006250000000000001 within 1e-09 delta (0.0006250000000000001 difference) : Expected dt = 0.0006250000000000001, but got 0.0012500000000000002 + +---------------------------------------------------------------------- +Ran 3 tests in 0.103s + +FAILED (failures=1) + + +#### Changing (i * self.dx - cx) in p2 to (i * self.dx) + +FAIL: test_set_initial_condition (tests.unit.test_diffusion2d_functions.TestDiffusion2D.test_set_initial_condition) +Checks function SolveDiffusion2D.get_initial_function +---------------------------------------------------------------------- +Traceback (most recent call last): + File "C:\Projects\testing-python-exercise-wt2425\tests\unit\test_diffusion2d_functions.py", line 84, in test_set_initial_condition + np.testing.assert_array_equal(u, expected_u, err_msg="Initial condition field is not correct.") + File "C:\Projects\testing-python-exercise-wt2425\venv\Lib\site-packages\numpy\_utils\__init__.py", line 85, in wrapper + return fun(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^ + File "C:\Projects\testing-python-exercise-wt2425\venv\Lib\site-packages\numpy\testing\_private\utils.py", line 1021, in assert_array_equal + assert_array_compare(operator.__eq__, actual, desired, err_msg=err_msg, + File "C:\Projects\testing-python-exercise-wt2425\venv\Lib\site-packages\numpy\testing\_private\utils.py", line 885, in assert_array_compare + raise AssertionError(msg) +AssertionError: +Arrays are not equal +Initial condition field is not correct. +Mismatched elements: 15 / 100 (15%) +Max absolute difference among violations: 400. +Max relative difference among violations: 1.33333333 + ACTUAL: array([[300., 300., 300., 300., 300., 300., 300., 300., 300., 300.], + [300., 300., 300., 300., 300., 300., 300., 300., 300., 300.], + [300., 300., 300., 300., 300., 300., 300., 300., 300., 300.],... + DESIRED: array([[300., 300., 300., 300., 700., 700., 700., 300., 300., 300.], + [300., 300., 300., 300., 700., 700., 700., 300., 300., 300.], + [300., 300., 300., 300., 300., 300., 300., 300., 300., 300.],... + +---------------------------------------------------------------------- +Ran 3 tests in 0.078s + +FAILED (failures=1) + + +### Integrationtest log + +#### Changing self.dt = dx2 * dy2 / (2 * self.D * (dx2 + dy2)) to self.dt = dx2 * dy2 / (self.D * (dx2 + dy2)) + +tests\integration\test_diffusion2d.py F. [100%] + +======================================================= FAILURES ======================================================== +__________________________________________ test_initialize_physical_parameters __________________________________________ + + def test_initialize_physical_parameters(): + """ + Checks function SolveDiffusion2D.initialize_domain + """ + solver = SolveDiffusion2D() + + # Initialize domain + solver.initialize_domain(w=10.0, h=10.0, dx=0.5, dy=0.5) + + # Initialize physical parameters + solver.initialize_physical_parameters(d=2.0, T_cold=300.0, T_hot=700.0) + + # Expected dt calculation + dx2, dy2 = solver.dx ** 2, solver.dy ** 2 + expected_dt = dx2 * dy2 / (solver.D * (dx2 + dy2)) + +> assert solver.dt == expected_dt, f"Expected {expected_dt}, got {solver.dt}" +E AssertionError: Expected 0.0625, got 0.03125 +E assert 0.03125 == 0.0625 +E + where 0.03125 = .dt + +tests\integration\test_diffusion2d.py:25: AssertionError + + +#### Changing (i * self.dx - cx) in p2 to (i * self.dx) + +tests\integration\test_diffusion2d.py . F [100%] + +======================================================= FAILURES ======================================================== +______________________________________________ test_set_initial_condition _______________________________________________ + + def test_set_initial_condition(): + """ + Checks function SolveDiffusion2D.get_initial_function + """ + solver = SolveDiffusion2D() + + # Step 1: Initialize domain with valid dimensions and grid spacing + solver.initialize_domain(w=10.0, h=10.0, dx=0.5, dy=0.5) + + # Initialize physical parameters + solver.initialize_physical_parameters(d=4.0, T_cold=300.0, T_hot=700.0) + + # Set initial conditions + u = solver.set_initial_condition() + + # Step 3: Expected u calculation + nx, ny = solver.nx, solver.ny + T_cold, T_hot = solver.T_cold, solver.T_hot + r, cx, cy = 2.0, 5.0, 5.0 + + expected_u = T_cold * np.ones((nx, ny)) + for i in range(nx): + for j in range(ny): + p2 = (i * solver.dx) ** 2 + (j * solver.dy - cy) ** 2 + if p2 < r ** 2: + expected_u[i, j] = T_hot + + # Step 4: Assert the result +> np.testing.assert_array_equal(u, expected_u, "Initial condition array mismatch") + +tests\integration\test_diffusion2d.py:56: +_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + +args = (array([[300., 300., 300., 300., 300., 300., 300., 300., 300., 300., 300., + 300., 300., 300., 300., 300., 300.,... 300., 300., 300., + 300., 300., 300., 300., 300., 300., 300., 300., 300.]]), 'Initial condition array mismatch') +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 Initial condition array mismatch +E Mismatched elements: 71 / 400 (17.8%) +E Max absolute difference among violations: 400. +E Max relative difference among violations: 1.33333333 +E ACTUAL: array([[300., 300., 300., 300., 300., 300., 300., 300., 300., 300., 300., +E 300., 300., 300., 300., 300., 300., 300., 300., 300.], +E [300., 300., 300., 300., 300., 300., 300., 300., 300., 300., 300.,... +E DESIRED: array([[300., 300., 300., 300., 300., 300., 300., 700., 700., 700., 700., +E 700., 700., 700., 300., 300., 300., 300., 300., 300.], +E [300., 300., 300., 300., 300., 300., 300., 700., 700., 700., 700.,... + +venv\Lib\site-packages\numpy\_utils\__init__.py:85: AssertionError + ## Citing diff --git a/coverage-report.pdf b/coverage-report.pdf new file mode 100644 index 00000000..42e255e6 Binary files /dev/null and b/coverage-report.pdf differ diff --git a/diffusion2d.py b/diffusion2d.py index 51a07f2d..64181edc 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), "w must be float" + assert isinstance(h, float), "h must be float" + assert isinstance(dx, float), "dx must be float" + assert isinstance(dy, float), "dy must be 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), "d must be float" + assert isinstance(T_cold, float), "T_cold must be float" + assert isinstance(T_hot, float), "T_hot must be 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..070be7e6 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +numpy>=1.26.1 +matplotlib>=3.8.4 \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 00000000..40b4dcc1 --- /dev/null +++ b/setup.py @@ -0,0 +1,7 @@ +from setuptools import setup + +setup( + name="diffusion2d", + version="1.0", + py_modules=["diffusion2d"], +) \ 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..d15c215a 100644 --- a/tests/integration/test_diffusion2d.py +++ b/tests/integration/test_diffusion2d.py @@ -2,6 +2,7 @@ Tests for functionality checks in class SolveDiffusion2D """ +import numpy as np from diffusion2d import SolveDiffusion2D @@ -11,9 +12,52 @@ def test_initialize_physical_parameters(): """ solver = SolveDiffusion2D() + # Initialize domain + solver.initialize_domain(w=10.0, h=10.0, dx=0.5, dy=0.5) + + # Initialize physical parameters + solver.initialize_physical_parameters(d=2.0, T_cold=300.0, T_hot=700.0) + + assert solver.D == 2.0, f"Expected D to be 2.0, but got {solver.D}" + + # Expected dt calculation + dx2, dy2 = solver.dx ** 2, solver.dy ** 2 + expected_dt = dx2 * dy2 / (2 * solver.D * (dx2 + dy2)) + + assert solver.dt == expected_dt, f"Expected {expected_dt}, got {solver.dt}" + def test_set_initial_condition(): """ Checks function SolveDiffusion2D.get_initial_function """ solver = SolveDiffusion2D() + + # Step 1: Initialize domain with valid dimensions and grid spacing + solver.initialize_domain(w=10.0, h=10.0, dx=0.5, dy=0.5) + + # Initialize physical parameters + solver.initialize_physical_parameters(d=4.0, T_cold=300.0, T_hot=700.0) + + # Set initial conditions + u = solver.set_initial_condition() + + # Step 3: Expected u calculation + nx, ny = solver.nx, solver.ny + T_cold, T_hot = solver.T_cold, solver.T_hot + r, cx, cy = 2.0, 5.0, 5.0 + + expected_u = T_cold * np.ones((nx, ny)) + + + for i in range(nx): + for j in range(ny): + p2 = (i * solver.dx - cx) ** 2 + (j * solver.dy - cy) ** 2 + if p2 < r ** 2: + expected_u[i, j] = T_hot + + # Step 4: Assert the result + np.testing.assert_array_equal(u, expected_u, err_msg="Initial condition array mismatch") + + # Optional debug prints (can be removed in production) + print("Test passed: set_initial_condition produces expected results.") \ No newline at end of file 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..5708ff8b 100644 --- a/tests/unit/test_diffusion2d_functions.py +++ b/tests/unit/test_diffusion2d_functions.py @@ -1,26 +1,85 @@ """ Tests for functions in class SolveDiffusion2D """ - +import unittest +import numpy as np from diffusion2d import SolveDiffusion2D +class TestDiffusion2D(unittest.TestCase): + + def setUp(self): + self.solver = SolveDiffusion2D() + + def test_initialize_domain(self): + """ + Check function SolveDiffusion2D.initialize_domain + """ + w, h, dx, dy = 10.0, 20.0, 0.5, 0.5 + expected_nx, expected_ny = int(w / dx), int(h / dy) + + # Act + self.solver.initialize_domain(w, h, dx, dy) + + self.assertEqual(self.solver.nx, expected_nx, f"Expected nx = {expected_nx}, but got {self.solver.nx}") + self.assertEqual(self.solver.ny, expected_ny, f"Expected ny = {expected_ny}, but got {self.solver.ny}") + + + def test_initialize_physical_parameters(self): + """ + Checks function SolveDiffusion2D.initialize_domain + """ + d = 4.0 # Diffusivity, analogous to alpha + dx = 0.1 # Grid spacing in the x-direction + dy = 0.1 # Grid spacing in the y-direction + + # Calculate expected dt manually using the formula + dx2, dy2 = dx * dx, dy * dy + dt_expected = dx2 * dy2 / (2 * d * (dx2 + dy2)) + + # Set the dx and dy values manually in the solver (since we're testing only initialize_physical_parameters) + self.solver.dx = dx + self.solver.dy = dy + + # Act + self.solver.initialize_physical_parameters(d) + + # Assert + self.assertAlmostEqual(self.solver.dt, dt_expected, delta=1e-9, msg=f"Expected dt = {dt_expected}, but got {self.solver.dt}") + + def test_set_initial_condition(self): + """ + Checks function SolveDiffusion2D.get_initial_function + """ + T_hot = 700.0 # Hot temperature + T_cold = 300.0 # Cold temperature + dx = 1.0 # Spacing in the x-direction + dy = 1.0 # Spacing in the y-direction + nx = 10 # Number of points in x-direction + ny = 10 # Number of points in y-direction + + self.solver.nx = nx + self.solver.ny = ny + self.solver.dx = dx + self.solver.dy = dy + self.solver.T_hot = T_hot + self.solver.T_cold = T_cold -def test_initialize_domain(): - """ - Check function SolveDiffusion2D.initialize_domain - """ - solver = SolveDiffusion2D() + # Step 4: Manually compute the expected u array + expected_u = T_cold * np.ones((nx, ny)) # Start with all values as T_cold + r = 2 # Radius of the circle + cx, cy = 5, 5 # Center of the circle + + for i in range(nx): + for j in range(ny): + p2 = (i * self.solver.dx - cx) ** 2 + (j * self.solver.dy - cy) ** 2 + if p2 < r ** 2: + expected_u[i, j] = T_hot + -def test_initialize_physical_parameters(): - """ - Checks function SolveDiffusion2D.initialize_domain - """ - solver = SolveDiffusion2D() + # Act + u = self.solver.set_initial_condition() + # Step 5: Assert that the generated u array matches the expected u array + np.testing.assert_array_equal(u, expected_u, err_msg="Initial condition field is not correct.") -def test_set_initial_condition(): - """ - Checks function SolveDiffusion2D.get_initial_function - """ - solver = SolveDiffusion2D() diff --git a/tox.toml b/tox.toml new file mode 100644 index 00000000..9b033fa0 --- /dev/null +++ b/tox.toml @@ -0,0 +1,12 @@ +requires = ["tox>=4"] +env_list = ["pytest", "unittest"] + +[env.pytest] +description = "pytest" +deps = ["pytest", "-r requirements.txt"] +commands = [["python", "-m", "pytest", "tests/integration/test_diffusion2d.py"]] + +[env.unittest] +description = "unittest" +deps = ["-r requirements.txt"] +commands = [["python", "-m", "unittest", "tests/unit/test_diffusion2d_functions.py"]] \ No newline at end of file