Testing the Framework
splent_framework ships a set of pytest fixtures and helpers that handle app creation, database lifecycle, and test client setup for feature tests. Use them instead of writing your own to stay consistent with the framework conventions.
For a complete guide on how to set up and write tests in a feature — including fixtures, test users, scope selection, and examples at every level — see Feature testing.
Table of contents
Fixtures
File: splent_framework.fixtures.fixtures
Import all fixtures in your feature’s conftest.py:
# tests/conftest.py
from splent_framework.fixtures.fixtures import * # noqa: F401,F403
All fixtures share a _reset_db() helper that disables MariaDB FK checks during drop, so cross-feature FK references don’t block table cleanup:
def _reset_db():
db.session.remove()
with db.engine.connect() as conn:
conn.execute(text("SET FOREIGN_KEY_CHECKS=0"))
db.metadata.drop_all(bind=conn)
conn.execute(text("SET FOREIGN_KEY_CHECKS=1"))
db.metadata.create_all(bind=conn)
conn.commit()
test_app (session scope)
Creates the Flask application in testing mode once per test session, then drops and recreates all database tables.
@pytest.fixture(scope="session")
def test_app():
app = get_create_app_in_testing_mode()
with app.app_context():
_reset_db()
yield app
Use when: you need direct access to the Flask app object (e.g., to read app.config or push a context manually).
Scope: session — the app is created once and shared across all tests in the session.
test_client (function scope)
Provides a Flask test client with full database isolation per test. All tables are dropped and recreated before the test runs.
@pytest.fixture(scope="function")
def test_client(test_app):
with test_app.app_context():
_reset_db()
with test_app.test_client() as client:
yield client
Use when: you want a clean database for every single test function.
Example:
def test_login(test_client):
response = test_client.post("/login", data={
"email": "user@example.com",
"password": "secret",
})
assert response.status_code == 302
test_client_module (module scope)
Same as test_client but scoped to the module. The database is reset once at the start of the module, not between individual tests.
@pytest.fixture(scope="module")
def test_client_module(test_app):
with test_app.app_context():
_reset_db()
with test_app.test_client() as client:
yield client
Use when: tests in the same module share state (e.g., a sequence of operations that build on each other) and resetting the database between each test would be too expensive or would break the intended flow.
clean_database (function scope)
Manually resets the database within a test. Does not provide a client — combine with test_client_module when you need selective resets within a module-scoped client.
@pytest.fixture(scope="function")
def clean_database(test_app):
with test_app.app_context():
_reset_db()
yield
Use when: you have module-scoped state for most tests but one specific test must start with an empty database.
Test helpers
Auth helpers
File: splent_framework.helpers.test_helpers_auth
Utilities for authenticating test clients:
from splent_framework.helpers.test_helpers_auth import login, logout
def test_protected_route(test_client):
login(test_client, "user@example.com", "secret")
response = test_client.get("/profile")
assert response.status_code == 200
logout(test_client)
Writing tests for a feature
Each feature scaffold generated by feature:create includes a layered test structure:
tests/
├── conftest.py # Shared fixtures (imports from splent_framework.fixtures)
├── unit/ # Mocked dependencies, no DB, no HTTP — fast
│ └── test_services.py
├── integration/ # Real test DB, repositories, services
│ └── test_repositories.py
├── functional/ # Flask test_client, full HTTP request/response cycles
│ └── test_routes.py
├── e2e/ # Selenium browser automation (real server required)
│ └── test_browser.py
└── load/ # Locust performance tests
└── locustfile.py
The conftest.py imports framework fixtures and defines feature-specific fixtures (test users, seed data, etc.). See Feature testing for a complete guide on fixture setup, scope selection, and examples at every level.
Running feature tests
From inside the SPLENT CLI container:
splent feature:test auth # Single feature, default levels
splent feature:test auth --unit # Unit tests only
splent feature:test auth --integration -v # Integration, verbose
splent feature:test # All features
app_loader
File: splent_framework.utils.app_loader
Used internally by the fixtures to import the active product’s create_app:
def get_create_app_in_testing_mode():
app_name = os.getenv("SPLENT_APP")
module = importlib.import_module(app_name)
return module.create_app("testing")
This avoids any dependency on the CLI during test execution. Tests run purely in the Python environment with no Docker or CLI involvement.
See also
feature:test— CLI command to run a feature’s test suite- Application initialization —
TestingConfigdetails - Database —
dbsingleton used by fixtures