Skip to main content

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​

ProblemSolution
Beat shows no outputEnsure 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 workerFlush Redis: redis-cli FLUSHDB, then restart Beat and Worker
Screenshot timeoutEnsure your frontend dev server is running and WEBDRIVER_BASEURL matches its URL

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