diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..9237a10f --- /dev/null +++ b/.gitignore @@ -0,0 +1,103 @@ +# Created by https://www.toptal.com/developers/gitignore/api/python +# Edit at https://www.toptal.com/developers/gitignore?templates=python + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is \ No newline at end of file diff --git a/README.md b/README.md index da66993c..12e8616a 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,315 @@ Please follow the instructions in [python_testing_exercise.md](https://github.co ### pytest log +``` +======================= test session starts ======================= +platform linux -- Python 3.12.8, pytest-8.3.3, pluggy-1.5.0 +rootdir: /home/julian/Documents/git/testing-python-exercise-wt2425 +collected 3 items + +tests/unit/test_diffusion2d_functions.py F.. [100%] + +============================ FAILURES ============================= +_____________________ test_initialize_domain ______________________ + +solver = + + def test_initialize_domain(solver): + """ + Check function SolveDiffusion2D.initialize_domain + """ + w = 20. + h = 30. + dx = 0.5 + dy = 0.5 + solver.initialize_domain(w, h, dx, dy) +> assert solver.nx == pytest.approx(40, abs=0.01) +E assert 60 == 40 ± 1.0e-02 +E +E comparison failed +E Obtained: 60 +E Expected: 40 ± 1.0e-02 + +tests/unit/test_diffusion2d_functions.py:25: AssertionError +===================== short test summary info ===================== +FAILED tests/unit/test_diffusion2d_functions.py::test_initialize_domain - assert 60 == 40 ± 1.0e-02 +=================== 1 failed, 2 passed in 0.41s =================== +``` + +Changed factor `2` to `4` in formula: `self.dt = dx2 * dy2 / (4 * self.D * (dx2 + dy2))`: + +``` +============================= test session starts ============================== +platform linux -- Python 3.12.8, pytest-8.3.3, pluggy-1.5.0 +rootdir: /home/julian/Documents/git/testing-python-exercise-wt2425 +collected 3 items + +tests/unit/test_diffusion2d_functions.py .F. [100%] + +=================================== FAILURES =================================== +_____________________ test_initialize_physical_parameters ______________________ + +solver = + + def test_initialize_physical_parameters(solver): + """ + Checks function SolveDiffusion2D.initialize_domain + """ + d = 4. + T_cold = 300. + T_hot = 700. + solver.w = 20. + solver.h = 30. + solver.dx = 0.5 + solver.dy = 0.5 + solver.nx = 40. + solver.ny = 60. + solver.initialize_physical_parameters(d, T_cold, T_hot) + assert solver.D == pytest.approx(d, abs=0.01) + assert solver.T_cold == pytest.approx(T_cold, abs=0.01) + assert solver.T_hot == pytest.approx(T_hot, abs=0.01) +> assert solver.dt == pytest.approx(0.015, abs=0.001) +E assert 0.0078125 == 0.015 ± 1.0e-03 +E +E comparison failed +E Obtained: 0.0078125 +E Expected: 0.015 ± 1.0e-03 + +tests/unit/test_diffusion2d_functions.py:48: AssertionError +----------------------------- Captured stdout call ----------------------------- +dt = 0.0078125 +=========================== short test summary info ============================ +FAILED tests/unit/test_diffusion2d_functions.py::test_initialize_physical_parameters - assert 0.0078125 == 0.015 ± 1.0e-03 +========================= 1 failed, 2 passed in 0.41s ========================== +``` + +Initialization with T_hot instead of T_cold: + +``` +=================== test session starts =================== +platform linux -- Python 3.12.8, pytest-8.3.3, pluggy-1.5.0 +rootdir: /home/julian/Documents/git/testing-python-exercise-wt2425 +collected 3 items + +tests/unit/test_diffusion2d_functions.py ..F [100%] + +======================== FAILURES ========================= +_______________ test_set_initial_condition ________________ + +solver = + + def test_set_initial_condition(solver): + """ + Checks function SolveDiffusion2D.get_initial_function + """ + solver.D = 4. + solver.T_cold = 300. + solver.T_hot = 700. + solver.w = 2. + solver.h = 3. + solver.dx = 0.5 + solver.dy = 0.5 + solver.nx = 4 + solver.ny = 6 + solver.dt = 0.015625 + u = solver.set_initial_condition() + print(u) + assert u.shape == (4, 6) +> assert numpy.allclose(a=u, + b=numpy.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.] + ] + ), + atol=1e-3, + rtol=0, + ) +E assert False +E + where False = (a=array([[700., 700., 700., 700., 700., 700.],\n [700., 700., 700., 700., 700., 700.],\n [700., 700., 700., 700., 700., 700.],\n [700., 700., 700., 700., 700., 700.]]), b=array([[300., 300., 300., 300., 300., 300.],\n [300., 300., 300., 300., 300., 300.],\n [300., 300., 300., 300., 300., 300.],\n [300., 300., 300., 300., 300., 300.]]), atol=0.001, rtol=0) +E + where = numpy.allclose +E + and array([[300., 300., 300., 300., 300., 300.],\n [300., 300., 300., 300., 300., 300.],\n [300., 300., 300., 300., 300., 300.],\n [300., 300., 300., 300., 300., 300.]]) = ([[300.0, 300.0, 300.0, 300.0, 300.0, 300.0], [300.0, 300.0, 300.0, 300.0, 300.0, 300.0], [300.0, 300.0, 300.0, 300.0, 300.0, 300.0], [300.0, 300.0, 300.0, 300.0, 300.0, 300.0]]) +E + where = numpy.array + +tests/unit/test_diffusion2d_functions.py:70: AssertionError +------------------ Captured stdout call ------------------- +[[700. 700. 700. 700. 700. 700.] + [700. 700. 700. 700. 700. 700.] + [700. 700. 700. 700. 700. 700.] + [700. 700. 700. 700. 700. 700.]] +================= short test summary info ================= +FAILED tests/unit/test_diffusion2d_functions.py::test_set_initial_condition - assert False +=============== 1 failed, 2 passed in 0.41s =============== +``` + +#### Integration tests + +Changed factor `2` to `4` in formula: `self.dt = dx2 * dy2 / (4 * self.D * (dx2 + dy2))` + +``` +======================= test session starts ======================= +platform linux -- Python 3.12.8, pytest-8.3.3, pluggy-1.5.0 +rootdir: /home/julian/Documents/git/testing-python-exercise-wt2425 +collected 2 items + +tests/integration/test_diffusion2d.py F. [100%] + +============================ FAILURES ============================= +_______________ test_initialize_physical_parameters _______________ + +solver = + + def test_initialize_physical_parameters(solver): + """ + Checks function SolveDiffusion2D.initialize_domain + """ + d = 4.0 + T_cold = 300.0 + T_hot = 700.0 + w = 20.0 + h = 30.0 + dx = 0.5 + dy = 0.5 + solver.initialize_domain(w, h, dx, dy) + solver.initialize_physical_parameters(d, T_cold, T_hot) + assert solver.D == pytest.approx(d, abs=0.001) + assert solver.T_cold == pytest.approx(T_cold, abs=0.001) + assert solver.T_hot == pytest.approx(T_hot, abs=0.001) +> assert solver.dt == pytest.approx(0.015, abs=0.001) +E assert 0.0078125 == 0.015 ± 1.0e-03 +E +E comparison failed +E Obtained: 0.0078125 +E Expected: 0.015 ± 1.0e-03 + +tests/integration/test_diffusion2d.py:31: AssertionError +---------------------- Captured stdout call ----------------------- +dt = 0.0078125 +===================== short test summary info ===================== +FAILED tests/integration/test_diffusion2d.py::test_initialize_physical_parameters - assert 0.0078125 == 0.015 ± 1.0e-03 +=================== 1 failed, 1 passed in 0.42s =================== +``` + +Initialization with T_hot instead of T_cold: + +``` +======================= test session starts ======================= +platform linux -- Python 3.12.8, pytest-8.3.3, pluggy-1.5.0 +rootdir: /home/julian/Documents/git/testing-python-exercise-wt2425 +collected 2 items + +tests/integration/test_diffusion2d.py .F [100%] + +============================ FAILURES ============================= +___________________ test_set_initial_condition ____________________ + +solver = + + def test_set_initial_condition(solver): + """ + Checks function SolveDiffusion2D.get_initial_function + """ + d = 4.0 + T_cold = 300.0 + T_hot = 700.0 + w = 2.0 + h = 3.0 + dx = 0.5 + dy = 0.5 + solver.initialize_domain(w, h, dx, dy) + solver.initialize_physical_parameters(d, T_cold, T_hot) + u = solver.set_initial_condition() + assert u.shape == (4, 6) + # numpy.allclose allows an absolute tolerance of 1e-03, 3 places in this configuration. +> assert numpy.allclose( + a=u, + b=numpy.array( + [ + [300.0, 300.0, 300.0, 300.0, 300.0, 300.0], + [300.0, 300.0, 300.0, 300.0, 300.0, 300.0], + [300.0, 300.0, 300.0, 300.0, 300.0, 300.0], + [300.0, 300.0, 300.0, 300.0, 300.0, 300.0], + ] + ), + atol=1e-03, + rtol=0, + ) +E assert False +E + where False = (a=array([[700., 700., 700., 700., 700., 700.],\n [700., 700., 700., 700., 700., 700.],\n [700., 700., 700., 700., 700., 700.],\n [700., 700., 700., 700., 700., 700.]]), b=array([[300., 300., 300., 300., 300., 300.],\n [300., 300., 300., 300., 300., 300.],\n [300., 300., 300., 300., 300., 300.],\n [300., 300., 300., 300., 300., 300.]]), atol=0.001, rtol=0) +E + where = numpy.allclose +E + and array([[300., 300., 300., 300., 300., 300.],\n [300., 300., 300., 300., 300., 300.],\n [300., 300., 300., 300., 300., 300.],\n [300., 300., 300., 300., 300., 300.]]) = ([[300.0, 300.0, 300.0, 300.0, 300.0, 300.0], [300.0, 300.0, 300.0, 300.0, 300.0, 300.0], [300.0, 300.0, 300.0, 300.0, 300.0, 300.0], [300.0, 300.0, 300.0, 300.0, 300.0, 300.0]]) +E + where = numpy.array + +tests/integration/test_diffusion2d.py:52: AssertionError +---------------------- Captured stdout call ----------------------- +dt = 0.015625 +===================== short test summary info ===================== +FAILED tests/integration/test_diffusion2d.py::test_set_initial_condition - assert False +=================== 1 failed, 1 passed in 0.41s =================== +``` + ### unittest log +Modifications similar to pytest logs. + +``` +====================================================================== +FAIL: test_initialize_domain (tests.unit.test_diffusion2d_functions.TestDiffusion2D.test_initialize_domain) +Check function SolveDiffusion2D.initialize_domain +---------------------------------------------------------------------- +Traceback (most recent call last): + File "/home/julian/Documents/git/testing-python-exercise-wt2425/tests/unit/test_diffusion2d_functions.py", line 29, in test_initialize_domain + self.assertAlmostEqual(self.solver.nx, 40, places=3) +AssertionError: 60 != 40 within 3 places (20 difference) + +---------------------------------------------------------------------- +Ran 3 tests in 0.001s + +FAILED (failures=1) +``` + +``` +====================================================================== +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 "/home/julian/Documents/git/testing-python-exercise-wt2425/tests/unit/test_diffusion2d_functions.py", line 51, in test_initialize_physical_parameters + self.assertAlmostEqual(self.solver.dt, 0.016, places=3) +AssertionError: 0.0078125 != 0.016 within 3 places (0.0081875 difference) + +---------------------------------------------------------------------- +Ran 3 tests in 0.001s + +FAILED (failures=1) +``` + +``` +====================================================================== +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 "/home/julian/Documents/git/testing-python-exercise-wt2425/tests/unit/test_diffusion2d_functions.py", line 70, in test_set_initial_condition + self.assertTrue(numpy.allclose(a=u, +AssertionError: False is not true + +---------------------------------------------------------------------- +Ran 3 tests in 0.001s + +FAILED (failures=1) +``` + +## Coverage + +I have used the flag: `coverage run --omit="*/site-packages/*"` to exclude dependencies like numpy in the coverage report. + ## 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/__init__.py b/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/coverage-report.pdf b/coverage-report.pdf new file mode 100644 index 00000000..745d4315 Binary files /dev/null and b/coverage-report.pdf differ diff --git a/diffusion2d.py b/diffusion2d.py index 51a07f2d..814e0f4d 100644 --- a/diffusion2d.py +++ b/diffusion2d.py @@ -37,7 +37,12 @@ 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 type(w) == float, "Width must be a float" + assert type(h) == float, "Height must be a float" + assert type(dx) == float, "dx must be a float" + assert type(dy) == float, "dy must be a float" + self.w = w self.h = h self.dx = dx @@ -45,7 +50,11 @@ 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 type(d) == float, "Thermal diffusivity must be a float" + assert type(T_cold) == float, "Cold temperature must be a float" + assert type(T_hot) == float, "Hot temperature must be a float" + self.D = d self.T_cold = T_cold self.T_hot = T_hot @@ -61,7 +70,7 @@ 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 + 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 @@ -78,17 +87,20 @@ def do_timestep(self, u_nm1): # Propagate with forward-difference in time, central-difference in space u[1:-1, 1:-1] = u_nm1[1:-1, 1:-1] + self.D * self.dt * ( - (u_nm1[2:, 1:-1] - 2 * u_nm1[1:-1, 1:-1] + u_nm1[:-2, 1:-1]) / dx2 - + (u_nm1[1:-1, 2:] - 2 * u_nm1[1:-1, 1:-1] + u_nm1[1:-1, :-2]) / dy2) + (u_nm1[2:, 1:-1] - 2 * u_nm1[1:-1, 1:-1] + u_nm1[:-2, 1:-1]) / dx2 + + (u_nm1[1:-1, 2:] - 2 * u_nm1[1:-1, 1:-1] + u_nm1[1:-1, :-2]) / dy2 + ) return u.copy() def create_figure(self, fig, u, n, fignum): fignum += 1 ax = fig.add_subplot(220 + fignum) - im = ax.imshow(u.copy(), cmap=plt.get_cmap('hot'), vmin=self.T_cold, vmax=self.T_hot) + im = ax.imshow( + u.copy(), cmap=plt.get_cmap("hot"), vmin=self.T_cold, vmax=self.T_hot + ) ax.set_axis_off() - ax.set_title('{:.1f} ms'.format(n * self.dt * 1000)) + ax.set_title("{:.1f} ms".format(n * self.dt * 1000)) return fignum, im @@ -96,7 +108,7 @@ def create_figure(self, fig, u, n, fignum): def output_figure(fig, im): fig.subplots_adjust(right=0.85) cbar_ax = fig.add_axes([0.9, 0.15, 0.03, 0.7]) - cbar_ax.set_xlabel('$T$ / K', labelpad=20) + cbar_ax.set_xlabel("$T$ / K", labelpad=20) fig.colorbar(im, cax=cbar_ax) plt.show() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..806f2211 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +numpy +matplotlib \ 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/test_diffusion2d.py b/tests/integration/test_diffusion2d.py index fd026b40..e6933812 100644 --- a/tests/integration/test_diffusion2d.py +++ b/tests/integration/test_diffusion2d.py @@ -3,17 +3,62 @@ """ from diffusion2d import SolveDiffusion2D +import numpy +import pytest -def test_initialize_physical_parameters(): +@pytest.fixture +def solver(): + return SolveDiffusion2D() + + +def test_initialize_physical_parameters(solver): """ Checks function SolveDiffusion2D.initialize_domain """ + d = 4.0 + T_cold = 300.0 + T_hot = 700.0 + w = 20.0 + h = 30.0 + dx = 0.5 + dy = 0.5 + solver.initialize_domain(w, h, dx, dy) + solver.initialize_physical_parameters(d, T_cold, T_hot) + assert solver.D == pytest.approx(d, abs=0.001) + assert solver.T_cold == pytest.approx(T_cold, abs=0.001) + assert solver.T_hot == pytest.approx(T_hot, abs=0.001) + assert solver.dt == pytest.approx(0.015, abs=0.001) + solver.dx * solver.dy / (4 * solver.D) solver = SolveDiffusion2D() -def test_set_initial_condition(): +def test_set_initial_condition(solver): """ Checks function SolveDiffusion2D.get_initial_function """ - solver = SolveDiffusion2D() + d = 4.0 + T_cold = 300.0 + T_hot = 700.0 + w = 2.0 + h = 3.0 + dx = 0.5 + dy = 0.5 + solver.initialize_domain(w, h, dx, dy) + solver.initialize_physical_parameters(d, T_cold, T_hot) + u = solver.set_initial_condition() + assert u.shape == (4, 6) + # numpy.allclose allows an absolute tolerance of 1e-03, 3 places in this configuration. + assert numpy.allclose( + a=u, + b=numpy.array( + [ + [300.0, 300.0, 300.0, 300.0, 300.0, 300.0], + [300.0, 300.0, 300.0, 300.0, 300.0, 300.0], + [300.0, 300.0, 300.0, 300.0, 300.0, 300.0], + [300.0, 300.0, 300.0, 300.0, 300.0, 300.0], + ] + ), + atol=1e-03, + rtol=0, + ) 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..8e1ee62e 100644 --- a/tests/unit/test_diffusion2d_functions.py +++ b/tests/unit/test_diffusion2d_functions.py @@ -1,26 +1,89 @@ """ -Tests for functions in class SolveDiffusion2D +Tests for functions in class SolveDiffusion2D using unittest """ +import unittest from diffusion2d import SolveDiffusion2D +import numpy +import sys +# Append parent directory path to system paths to allow SolveDiffusion2D import. +sys.path.append("../..") -def test_initialize_domain(): - """ - Check function SolveDiffusion2D.initialize_domain - """ - solver = SolveDiffusion2D() +numpy.set_printoptions(threshold=sys.maxsize) -def test_initialize_physical_parameters(): - """ - Checks function SolveDiffusion2D.initialize_domain - """ - solver = SolveDiffusion2D() +class TestDiffusion2D(unittest.TestCase): + def setUp(self): + self.solver = SolveDiffusion2D() -def test_set_initial_condition(): - """ - Checks function SolveDiffusion2D.get_initial_function - """ - solver = SolveDiffusion2D() + def test_initialize_domain(self): + """ + Check function SolveDiffusion2D.initialize_domain + """ + w = 20.0 + h = 30.0 + dx = 0.5 + dy = 0.5 + self.solver.initialize_domain(w, h, dx, dy) + self.assertAlmostEqual(self.solver.nx, 40, places=3) + self.assertAlmostEqual(self.solver.ny, 60, places=3) + self.assertEqual(self.solver.dx, dx) + self.assertEqual(self.solver.dy, dy) + + def test_initialize_physical_parameters(self): + """ + Checks function SolveDiffusion2D.initialize_physical_parameters + """ + d = 4.0 + T_cold = 300.0 + T_hot = 700.0 + self.solver.w = 20.0 + self.solver.h = 30.0 + self.solver.dx = 0.5 + self.solver.dy = 0.5 + self.solver.nx = 40.0 + self.solver.ny = 60.0 + self.solver.initialize_physical_parameters(d, T_cold, T_hot) + self.assertAlmostEqual(self.solver.D, d, places=3) + self.assertAlmostEqual(self.solver.T_cold, T_cold, places=3) + self.assertAlmostEqual(self.solver.T_hot, T_hot, places=3) + self.assertAlmostEqual(self.solver.dt, 0.016, places=3) + + def test_set_initial_condition(self): + """ + Checks function SolveDiffusion2D.set_initial_condition + """ + self.solver.D = 4.0 + self.solver.T_cold = 300.0 + self.solver.T_hot = 700.0 + self.solver.w = 2.0 + self.solver.h = 3.0 + self.solver.dx = 0.5 + self.solver.dy = 0.5 + self.solver.nx = 4 + self.solver.ny = 6 + self.solver.dt = 0.015625 + u = self.solver.set_initial_condition() + self.assertEqual(u.shape, (4, 6)) + # numpy.allclose allows an absolute tolerance of 1e-03, 3 places in this configuration. + self.assertTrue( + numpy.allclose( + a=u, + b=numpy.array( + [ + [300.0, 300.0, 300.0, 300.0, 300.0, 300.0], + [300.0, 300.0, 300.0, 300.0, 300.0, 300.0], + [300.0, 300.0, 300.0, 300.0, 300.0, 300.0], + [300.0, 300.0, 300.0, 300.0, 300.0, 300.0], + ] + ), + atol=1e-03, + rtol=0, + ) + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/tox.toml b/tox.toml new file mode 100644 index 00000000..3ecf3a13 --- /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/unit/test_diffusion2d_functions.py"]] + +[env.unittest] +description = "unittest" +deps = ["-r requirements.txt"] +commands = [["python", "-m", "unittest", "tests/integration/test_diffusion2d.py"]] \ No newline at end of file