diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml new file mode 100644 index 0000000..e8935bf --- /dev/null +++ b/.github/workflows/testing.yaml @@ -0,0 +1,36 @@ +name: Run Tests + +on: + push: + branches: [ main ] + + # Triggers the workflow on pushes to open pull requests with code changes + pull_request: + branches: [ main ] + paths: + - '**.py' + +jobs: + test: + runs-on: ubuntu-latest + + strategy: + matrix: + python-version: ['3.10', '3.11', '3.12'] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install uv + uv sync --dev + + - name: Run tests + run: uv run pytest diff --git a/.gitignore b/.gitignore index be2c700..6a58192 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ # vscode workspace .vscode/ +# Python module bytecode +__pycache__ # Jupyter Notebook */.ipynb_checkpoints @@ -16,4 +18,4 @@ output/ documentation/DEMENTpy_Documentation.* # DEMENTpy_notebooks -DEMENTpy_notebooks/ \ No newline at end of file +DEMENTpy_notebooks/ diff --git a/pyproject.toml b/pyproject.toml index 5c5957f..3c8646a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,4 +13,10 @@ dependencies = [ dev = [ "pre-commit>=4.2.0", "ruff>=0.11.4", + "pytest>=7.0", ] + +[tool.pytest.ini_options] +testpaths = ["tests"] +python_files = "test_*.py" +addopts = "-v" diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..5c86ec6 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,5 @@ +import sys +import os + +# Add the src/ directory to the pythonpath +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'src'))) diff --git a/tests/test_grid.py b/tests/test_grid.py new file mode 100644 index 0000000..ae0b128 --- /dev/null +++ b/tests/test_grid.py @@ -0,0 +1,47 @@ +"""Tests for the Grid class.""" + +import pandas as pd +import pytest + +from initialization import initialize_data +from grid import Grid + + +@pytest.fixture +def grid(): + """Initialize a Grid object using the initialize_data function.""" + input_dir = 'grassland' + runtime = pd.read_csv(input_dir+'/runtime.txt', header=None, index_col=0, sep='\t') + data = initialize_data(runtime, input_dir) + return Grid(runtime, data) + + +def test_initialization_runs(grid): + """Test that the initialization of Grid works without an error.""" + pass + + +def test_degradation_runs(grid): + """Test that Grid.degradation works without an error.""" + grid.degradation(0) + + +def test_uptake_runs(grid): + """Test that Grid.uptake works without an error.""" + grid.degradation(0) # degradation needs to run to initialize some DataFrames + grid.uptake(0) + + +def test_metabolism_runs(grid): + """Test that Grid.metabolism works without an error.""" + grid.metabolism(0) + + +def test_mortality_runs(grid): + """Test that Grid.mortality works without an error.""" + grid.mortality(0) + + +def test_reproduction_runs(grid): + """Test that Grid.reproduction works without an error.""" + grid.reproduction(0) diff --git a/tests/test_initialization.py b/tests/test_initialization.py new file mode 100644 index 0000000..b05d95e --- /dev/null +++ b/tests/test_initialization.py @@ -0,0 +1,14 @@ +"""Tests for the initialization of the data.""" + +import pandas as pd +import pytest + +from initialization import initialize_data + + +def test_initialize_data(): + """Test that initialize_data works without an error.""" + input_dir = 'grassland' + runtime = pd.read_csv(input_dir+'/runtime.txt', header=None, index_col=0, sep='\t') + data = initialize_data(runtime, input_dir) + assert isinstance(data, dict) diff --git a/tests/test_placeholder.py b/tests/test_placeholder.py new file mode 100644 index 0000000..9f1e034 --- /dev/null +++ b/tests/test_placeholder.py @@ -0,0 +1,21 @@ +"""Tests to show how to use pytest.""" + +import numpy as np +import pytest + + +def test_basic(): + """Illustrates how to write a simple test.""" + assert 1 + 1 == 2 + + +def test_raises_exception(): + """Illustrates how to write a test that checks for an exception.""" + with pytest.raises(ZeroDivisionError): + 1 / 0 + + +@pytest.mark.parametrize("x,y,r", [(3, 4, 5), (-5, -12, 13)]) +def test_multiple_parameters(x, y, r): + """Illustrates how to write a test to run with multiple input arguments.""" + assert np.sqrt(x**2 + y**2) == r