Write correct Flask tests -- app factory with test config, application context fixtures, database isolation, file uploads, auth testing, error handlers, mock.patch placement, and essential API test patterns
98
99%
Does it follow best practices?
Impact
97%
1.15xAverage score across 5 eval scenarios
Passed
No known issues
{
"instruction": "Write correct Flask tests following best practices",
"relevant_when": "Agent writes or modifies Flask test files",
"context": "Flask tests use app.test_client() inside an application context. The app factory must accept test config with TESTING=True and a separate database. Fixtures go in conftest.py with app (owns context), client (for requests), and runner (for CLI). Database isolation uses :memory: SQLite or transaction rollback per test. File uploads use data= with BytesIO tuples, not json=. mock.patch targets the import location, and mock args come before fixture args in pytest.",
"sources": [
{
"type": "file",
"filename": "skills/flask-testing/SKILL.md",
"tile": "tessl-labs/flask-testing@0.2.0"
}
],
"checklist": [
{
"name": "app-factory-test-config",
"rule": "Agent's app factory accepts a test configuration (test_config dict or testing flag) that sets TESTING=True and uses a separate test database.",
"relevant_when": "Agent creates or modifies the Flask app factory for testing"
},
{
"name": "app-context-in-fixture",
"rule": "Agent wraps the app fixture in 'with app.app_context():' and yields from inside it, so the test client operates within an application context.",
"relevant_when": "Agent creates Flask test fixtures"
},
{
"name": "conftest-fixture-structure",
"rule": "Agent creates a conftest.py with separate app, client, and optionally runner fixtures. The client fixture depends on the app fixture.",
"relevant_when": "Agent sets up Flask test infrastructure"
},
{
"name": "database-isolation",
"rule": "Agent uses function-scoped fixtures (default) with :memory: SQLite or transaction rollback so each test starts with a clean database. Never uses scope='session' or scope='module' for database fixtures.",
"relevant_when": "Agent configures Flask test database"
},
{
"name": "test-client-used",
"rule": "Agent creates tests using app.test_client() obtained through the client fixture, with json= for JSON POST requests.",
"relevant_when": "Agent writes Flask API tests"
},
{
"name": "file-upload-testing",
"rule": "Agent tests file uploads using data= with content_type='multipart/form-data' and (BytesIO(bytes), filename) tuples. Does not use json= for file uploads. Tests both valid and invalid file types.",
"relevant_when": "Agent writes tests for Flask file upload endpoints"
},
{
"name": "auth-both-paths",
"rule": "Agent tests both authenticated and unauthenticated paths. Logs in through the actual login endpoint, not by faking session cookies. Creates an auth_client fixture for convenience.",
"relevant_when": "Agent writes tests for Flask routes that require authentication"
},
{
"name": "error-handler-body-tested",
"rule": "Agent tests that error handlers (404, 400, 500) return a JSON body with a consistent shape, not just the status code.",
"relevant_when": "Agent writes tests for Flask error responses"
},
{
"name": "mock-patch-location",
"rule": "Agent patches names where they are looked up (the importing module), not where they are defined. E.g., if myapp/routes.py does 'from services.email import send_email', patch 'myapp.routes.send_email'.",
"relevant_when": "Agent uses unittest.mock.patch in Flask tests"
},
{
"name": "mock-before-fixtures",
"rule": "When using @patch with pytest, mock arguments come before fixture arguments in the test function signature.",
"relevant_when": "Agent combines mock.patch with pytest fixtures"
},
{
"name": "cli-test-runner",
"rule": "Agent tests Flask CLI commands using app.test_cli_runner(), not subprocess. Checks both exit_code and output.",
"relevant_when": "Agent writes tests for Flask CLI/Click commands"
},
{
"name": "essential-test-patterns",
"rule": "API test suite includes: happy path (200), validation rejection (400), 404 for missing resource, persistence verification (POST then GET), and error response consistency.",
"relevant_when": "Agent writes Flask API test coverage"
},
{
"name": "csrf-disabled-in-tests",
"rule": "Agent sets WTF_CSRF_ENABLED=False in test config when the app uses Flask-WTF, preventing CSRF validation from blocking test requests.",
"relevant_when": "Agent tests a Flask app that uses Flask-WTF or CSRF protection"
},
{
"name": "run-command-documented",
"rule": "Agent documents that tests are run with 'pytest -v'.",
"relevant_when": "Agent provides instructions for running Flask tests"
}
]
}