Skip to content

Commit 90cccc5

Browse files
committed
Migrate from nose2 to pytest for tests
1 parent b642020 commit 90cccc5

11 files changed

Lines changed: 1392 additions & 1179 deletions

.github/workflows/tests.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,8 @@ jobs:
3030
- name: Check lockfile
3131
run: uv lock --check
3232

33-
- name: Test with nose2
34-
run: |
35-
uv run coverage run -m nose2
36-
uv run coverage lcov -o cover/coverage.lcov
33+
- name: Test with pytest
34+
run: uv run pytest --cov --cov-report=term-missing --cov-report=lcov:cover/coverage.lcov
3735

3836
- name: Coveralls
3937
uses: coverallsapp/github-action@master

CONTRIBUTING.md

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ uv sync
2727

2828
### Running unit tests
2929

30-
The project's unit tests are written using and managed under the [nose2][nose2]
31-
Python package. You can run all unit tests via the `nose2` command.
30+
The project's unit tests are written using [pytest](https://docs.pytest.org/).
31+
You can run all unit tests via the `pytest` command.
3232

3333
```bash
34-
nose2
34+
uv run pytest
3535
```
3636

3737
## Code coverage
@@ -41,16 +41,13 @@ Contributions are expected to maintain this high standard. You can view the
4141
current coverage report via the `coverage` command:
4242

4343
```bash
44-
coverage run -m nose2
45-
coverage report
44+
uv run pytest --cov --cov-report=term-missing
4645
```
4746

4847
If you want to examine which lines are/aren't covered, you can generate and view
4948
a detailed HTML view of the coverage report like so:
5049

5150
```bash
52-
coverage html
51+
uv run pytest --cov --cov-report=html
5352
open htmlcov/index.html
5453
```
55-
56-
[nose2]: https://docs.nose2.io/en/latest/

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ dependencies = []
1616
[dependency-groups]
1717
dev = [
1818
"alfred-workflow-packager==3.1.1",
19-
"coverage==7.2.5",
2019
"freezegun==1.5.2",
2120
"mypy==1.4.1",
22-
"nose2==0.13.0",
21+
"pytest>=8.4.2",
22+
"pytest-cov>=7.0.0",
2323
"python-dotenv==1.0.0",
2424
"ruff>=0.12.0",
2525
]

tests/conftest.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env python3
2+
3+
from typing import Optional
4+
5+
import pytest
6+
from dotenv import load_dotenv
7+
8+
9+
@pytest.hookimpl(tryfirst=True)
10+
def pytest_report_teststatus(
11+
report: pytest.TestReport, config: pytest.Config
12+
) -> Optional[tuple[str, str, str]]:
13+
if report.passed and report.when == "call":
14+
# Silence the dot progress output for successful call phases
15+
return report.outcome, "", report.outcome.upper()
16+
return None
17+
18+
19+
@pytest.fixture(autouse=True, scope="session")
20+
def load_tests_env():
21+
"""Load test-specific environment variables for the entire test session."""
22+
load_dotenv("tests/.env.test")

tests/test_base_calendar.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
#!/usr/bin/env python3
22

3-
import unittest
43
from unittest.mock import Mock
54

5+
import pytest
6+
67
from ocu.calendars.base_calendar import BaseCalendar
78

89

9-
class TestBaseCalendar(unittest.TestCase):
10-
def test_base_calendar_not_instantiable(self):
11-
"""Should not be able to instantiate a BaseCalendar object by itself"""
12-
with self.assertRaises(TypeError):
13-
BaseCalendar() # type: ignore
10+
def test_base_calendar_not_instantiable():
11+
"""Should not be able to instantiate a BaseCalendar object by itself"""
12+
with pytest.raises(TypeError):
13+
BaseCalendar() # type: ignore
14+
1415

15-
def test_get_event_dicts_not_implemented(self):
16-
"""
17-
Should require the BaseCalendar.get_event_dicts() method to be implemented
18-
by any subclass of BaseCalendar
19-
"""
20-
with self.assertRaises(NotImplementedError):
21-
BaseCalendar.get_event_dicts(Mock())
16+
def test_get_event_dicts_not_implemented():
17+
"""
18+
Should require the BaseCalendar.get_event_dicts() method to be implemented
19+
by any subclass of BaseCalendar
20+
"""
21+
with pytest.raises(NotImplementedError):
22+
BaseCalendar.get_event_dicts(Mock())

0 commit comments

Comments
 (0)