Testing - pytest
Write and run tests with pytest.
Django includes its own test runner and unittest classes. But a lot of people (myself included) prefer pytest.
In Plain I've removed the Django test runner and a lot of the implications that come with it.
There are a few utilities that remain to make testing easier,
and plain-test
is a wrapper around pytest
.
1import pytest
2from plain.runtime import settings as plain_settings
3from plain.runtime import setup
4from plain.test.client import Client, RequestFactory
5
6
7def pytest_configure(config):
8 # Run Plain setup before anything else
9 setup()
10
11
12@pytest.fixture(autouse=True, scope="session")
13def _allowed_hosts_testserver():
14 # Add testserver to ALLOWED_HOSTS so the test client can make requests
15 plain_settings.ALLOWED_HOSTS = [*plain_settings.ALLOWED_HOSTS, "testserver"]
16
17
18@pytest.fixture()
19def client() -> Client:
20 """A Plain test client instance."""
21 return Client()
22
23
24@pytest.fixture()
25def request_factory() -> RequestFactory:
26 """A Plain RequestFactory instance."""
27 return RequestFactory()
28
29
30@pytest.fixture()
31def settings():
32 class SettingsProxy:
33 def __init__(self):
34 self._original = {}
35
36 def __getattr__(self, name):
37 return getattr(plain_settings, name)
38
39 def __setattr__(self, name, value):
40 if name.startswith("_"):
41 super().__setattr__(name, value)
42 else:
43 if name not in self._original:
44 self._original[name] = getattr(plain_settings, name, None)
45 setattr(plain_settings, name, value)
46
47 def _restore(self):
48 for key, value in self._original.items():
49 setattr(plain_settings, key, value)
50
51 proxy = SettingsProxy()
52 yield proxy
53 proxy._restore()