CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl-labs/flask-testing

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

1.15x
Quality

99%

Does it follow best practices?

Impact

97%

1.15x

Average score across 5 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

flask-tests.jsonverifiers/

{
  "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"
    }
  ]
}

tile.json