Files
superset2/docs/developer_docs_versioned_docs/version-6.1.0/testing/backend-testing.md
Superset Dev 752ebd47cb docs: cut 6.1.0 versions for docs, admin_docs, developer_docs, components
- Snapshot all four versioned docs sections at v6.1.0; master continues to
  serve as "Next" (lastVersion: current, banner: unreleased) so editing
  master keeps updating the canonical URLs
- Enable the previously-disabled components plugin and version it
- Rename stale "developer_portal" references to "developer_docs" across
  package.json scripts, manage-versions.mjs, theme files (DocVersionBadge,
  DocVersionBanner), DOCS_CLAUDE.md, and README.md (URL backward-compat
  redirect /developer_portal/* preserved)
- Add admin_docs version scripts; drop dead "tutorials" plugin id from
  the version badge
- Generalize fixVersionedImports in manage-versions.mjs to walk every
  section's snapshot and rewrite ../../src/ and ../../data/ imports,
  catching admin_docs and components files that previous version cuts
  would have broken
- Remove orphan files: developer_portal_versions.json,
  tutorials_versions.json, and stray empty versions.json files inside
  components/ and developer_docs/ content directories
2026-05-02 11:53:56 -07:00

5.4 KiB

title, sidebar_position
title sidebar_position
Backend Testing 3

Backend Testing

🚧 Coming Soon 🚧

Complete guide for testing Superset's Python backend, APIs, and database interactions.

Topics to be covered:

  • Pytest configuration and fixtures
  • Unit testing best practices
  • Integration testing with databases
  • API endpoint testing
  • Mocking strategies and patterns
  • Testing async operations with Celery
  • Security testing guidelines
  • Performance and load testing
  • Test database setup and teardown
  • Coverage requirements

Quick Commands

# Run all backend tests
pytest

# Run specific test file
pytest tests/unit_tests/specific_test.py

# Run with coverage
pytest --cov=superset

# Run tests in parallel
pytest -n auto

# Run only unit tests
pytest tests/unit_tests/

# Run only integration tests
pytest tests/integration_tests/

Testing Alerts & Reports with Celery and MailHog

The Alerts & Reports feature relies on Celery for task scheduling and execution. To test it locally, you need Redis (message broker), Celery Beat (scheduler), a Celery Worker (executor), and an SMTP server to receive email notifications.

Prerequisites

  • Redis running on localhost:6379
  • MailHog installed (a local SMTP server with a web UI for viewing caught emails)

superset_config.py

Your CeleryConfig must include beat_schedule. When you define a custom CeleryConfig class in superset_config.py, it replaces the default entirely. If you omit beat_schedule, Celery Beat will start but never schedule any report tasks.

from celery.schedules import crontab
from superset.tasks.types import ExecutorType

REDIS_HOST = "localhost"
REDIS_PORT = "6379"

class CeleryConfig:
    broker_url = f"redis://{REDIS_HOST}:{REDIS_PORT}/0"
    result_backend = f"redis://{REDIS_HOST}:{REDIS_PORT}/0"
    broker_connection_retry_on_startup = True
    imports = (
        "superset.sql_lab",
        "superset.tasks.scheduler",
        "superset.tasks.thumbnails",
        "superset.tasks.cache",
    )
    worker_prefetch_multiplier = 10
    task_acks_late = True
    beat_schedule = {
        "reports.scheduler": {
            "task": "reports.scheduler",
            "schedule": crontab(minute="*", hour="*"),
        },
        "reports.prune_log": {
            "task": "reports.prune_log",
            "schedule": crontab(minute=0, hour=0),
        },
    }

CELERY_CONFIG = CeleryConfig

# SMTP settings pointing to MailHog
SMTP_HOST = "localhost"
SMTP_PORT = 1025
SMTP_STARTTLS = False
SMTP_SSL = False
SMTP_USER = ""
SMTP_PASSWORD = ""
SMTP_MAIL_FROM = "superset@localhost"

# Must match where your frontend is running
WEBDRIVER_BASEURL = "http://localhost:9000/"

ALERT_REPORTS_EXECUTE_AS = [ExecutorType.OWNER]

FEATURE_FLAGS = {
    "ALERT_REPORTS": True,
    # Recommended for better screenshot support (WebGL/DeckGL charts)
    "PLAYWRIGHT_REPORTS_AND_THUMBNAILS": True,
}

:::note Do not include "superset.tasks.async_queries" in CeleryConfig.imports unless you need Global Async Queries. That module accesses current_app.config at import time and will crash the worker with a "Working outside of application context" error. :::

Starting the Services

Start MailHog, then Celery Beat and Worker in separate terminals:

# Terminal 1 - MailHog (SMTP on :1025, Web UI on :8025)
MailHog

# Terminal 2 - Celery Beat (scheduler)
celery --app=superset.tasks.celery_app:app beat --loglevel=info

# Terminal 3 - Celery Worker (executor)
celery --app=superset.tasks.celery_app:app worker --concurrency=1 --loglevel=info

Use --concurrency=1 to limit resource usage on your dev machine.

Verifying the Setup

  1. Beat should log Scheduler: Sending due task reports.scheduler (reports.scheduler) once per minute
  2. Worker should log Scheduling alert <name> eta: <timestamp> for each active report
  3. Create a test report in Settings > Alerts & Reports with a * * * * * cron schedule
  4. Check http://localhost:8025 (MailHog web UI) for the email within 1-2 minutes

Troubleshooting

Problem Solution
Beat shows no output Ensure beat_schedule is defined in your CeleryConfig and --loglevel=info is set
"Report Schedule is still working, refusing to re-compute" Previous executions are stuck. Reset with: UPDATE report_schedule SET last_state = 'Not triggered' WHERE id = <id>;
Task backlog overwhelming the worker Flush Redis: redis-cli FLUSHDB, then restart Beat and Worker
Screenshot timeout Ensure your frontend dev server is running and WEBDRIVER_BASEURL matches its URL

This documentation is under active development. Check back soon for updates!