flakytest.dev anze3db fedidevs
All environments · last 30 days

Test suite performance

Suite wall time
39.07 s
avg over 10 profiled runs
Total test time
1m 44s
sum of test durations per run
Tests
310
in 1 environment
Failure rate
0.0%
1 of 3,654 results
Flaky tests
0

Suite wall time per run

Click a point to open the run

Where the time goes

Avg test time per run
CI github-actions:test
1m 44s
Database Network Password hashing App code Factories Migrations Other (Libraries, DB schema, Templates, Mocking, ...)

Slowest tests

All tests →
Test and why it's slow Avg Share of suite Runs
accounts/tests.py::TestSelectedInstance::test_invalid_selected_instance
82% migrations · fixture django_db_setup (session scope) pytest_django/fixtures.py:186
7.51 s
7.2%
10
accounts/tests.py::TestAccountIndexRobots::test_single_facet_is_indexable
82% migrations · test body accounts/tests.py:572
5.22 s
5.0%
10
confs/tests.py::TestConferencePage::test_conference_with_utc_with_date_no_posts
83% migrations · test body confs/tests.py:875
4.95 s
4.8%
10
confs/tests.py::TestMigratedLegacyConferences::test_djangoconus_old_url_redirects
85% migrations · test body confs/tests.py:184
4.74 s
4.6%
10
accounts/tests.py::TestAccountIndexRobots::test_two_facets_are_noindex
82% migrations · fixture django_db_setup (session scope) pytest_django/fixtures.py:186
2.55 s
2.5%
10
confs/tests.py::TestMigratedLegacyConferences::test_fwd50_date_redirects
85% migrations · fixture django_db_setup (session scope) pytest_django/fixtures.py:186
2.48 s
2.4%
10
confs/tests.py::TestSyncAnnouncements::test_is_idempotent_and_refreshes_unposted_content
87% migrations · fixture django_db_setup (session scope) pytest_django/fixtures.py:186
2.40 s
2.3%
10
confs/tests.py::TestEditConference::test_edit_does_not_change_slug
92% password hashing · setUp confs/tests.py:1177
1.89 s
1.8%
10
confs/tests.py::TestEditConference::test_other_user_forbidden_on_approved_conference
94% password hashing · setUp confs/tests.py:1175
1.88 s
1.8%
10
confs/tests.py::TestLegacyConferenceDataMigration::test_copies_overlapping_legacy_rows_without_clobbering_existing_data
76% migrations · test body confs/tests.py:440
1.77 s
1.7%
10

Fix next

From the latest run per environment, by time saved
1

Use plain static file storage in tests

Static file storage/manifest handling costs 26.2s.

High App code ci:github-actions:test
26.23 s per run
Fix: In test settings use STORAGES["staticfiles"] = {"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage"} so templates don't need a manifest. Read the guide
Details

Where:

  • accounts/views.py:425 index · 924 ms
  • starter_packs/views.py:862 share_starter_pack · 660 ms
  • confs/views.py:509 create_conference · 596 ms
  • accounts/tests.py:550 TestAccountIndexRobots.assert_noindex · 564 ms
  • starter_packs/views.py:185 starter_packs · 492 ms
  • starter_packs/tests.py:781 TestShareStarterPack.test_order_by · 484 ms
  • starter_packs/views.py:858 share_starter_pack · 472 ms
  • starter_packs/tests.py:841 TestShareStarterPack.test_api_formats · 441 ms
  • confs/tests.py:1067 TestCreateConference.test_form_renders_for_authenticated_user · 358 ms
  • confs/views.py:296 _conference_detail · 322 ms

Most affected tests:

  • confs/tests.py::TestCreateConference::test_form_renders_for_authenticated_user
  • accounts/tests.py::TestSelectedInstance::test_invalid_selected_instance
  • starter_packs/tests.py::TestShareStarterPack::test_share_starter_pack
  • starter_packs/tests.py::TestShareStarterPack::test_languages_hidden_when_unset
  • accounts/tests.py::TestAccountIndexRobots::test_two_facets_are_noindex
  • confs/tests.py::TestConferencePage::test_conference_with_utc_with_date_no_posts
  • confs/tests.py::TestCreateConference::test_rejects_more_than_three_icons
  • accounts/tests.py::TestAccountIndexRobots::test_single_facet_is_indexable
2

Use a fast password hasher in tests

26.7s (29% of test time) is spent hashing passwords. Slow hashing protects real passwords; in tests it only burns CPU.

High Password hashing ci:github-actions:test
25.39 s per run
Fix: In your test settings set PASSWORD_HASHERS = ["django.contrib.auth.hashers.MD5PasswordHasher"] (currently PBKDF2PasswordHasher). Read the guide
Details

Only change the hasher in test settings. Tests that assert on a specific hash format need updating.

Where:

  • confs/tests.py:1044 TestCreateConference.setUp · 4.48 s
  • confs/tests.py:1175 TestEditConference.setUp · 4.07 s
  • confs/tests.py:1177 TestEditConference.setUp · 3.78 s
  • confs/tests.py:1176 TestEditConference.setUp · 3.36 s
  • confs/tests.py:1371 TestApproveConference.setUp · 2.98 s
  • confs/tests.py:1372 TestApproveConference.setUp · 2.67 s
  • confs/tests.py:1316 TestConferenceApprovalVisibility.setUp · 1.51 s
  • confs/tests.py:1317 TestConferenceApprovalVisibility.setUp · 1.50 s
  • confs/tests.py:1295 TestUnapproveConference.setUp · 612 ms
  • fedidevs/tests.py:63 TestAnonymousCacheAndCsrf.test_authenticated_html_is_private_and_keeps_csrf_header · 599 ms

Most affected tests:

  • confs/tests.py::TestEditConference::test_owner_can_edit
  • confs/tests.py::TestEditConference::test_edit_does_not_change_slug
  • confs/tests.py::TestEditConference::test_other_user_forbidden
  • confs/tests.py::TestEditConference::test_other_user_forbidden_on_approved_conference
  • fedidevs/tests.py::TestAnonymousCacheAndCsrf::test_authenticated_html_is_private_and_keeps_csrf_header
  • confs/tests.py::TestEditConference::test_owner_can_edit_after_approval
  • confs/tests.py::TestApproveConference::test_get_not_allowed
  • confs/tests.py::TestApproveConference::test_staff_approves

Documentation

3

Stop re-running migrations on every test run

Migrations take 25.3s per run, before the first test can start.

High Migrations ci:github-actions:test
22.73 s per run
Fix: Run with --reuse-db (add it to addopts in pytest.ini/pyproject) so the test database survives between runs; pass --create-db when migrations change. If no test depends on data migrations, --nomigrations builds the schema straight from the models, which is faster still. Read the guide
Details

CI should still build the database from scratch (no --reuse-db) so broken migrations are caught.

Where:

  • confs/tests.py:432 TestLegacyConferenceDataMigration._migrate · 1.25 s
  • confs/migrations/0031_seed_conference_tags.py:14 seed_conference_tags · 787 ms
  • confs/tests.py:412 TestLegacyConferenceDataMigration._leaf_targets · 136 ms
  • confs/migrations/0033_remove_legacy_conference_tables.py:388 _get_or_create_conference · 87 ms
  • confs/migrations/0033_remove_legacy_conference_tables.py:325 _refresh_account_counts · 86 ms
  • confs/migrations/0033_remove_legacy_conference_tables.py:214 _pk_batches · 78 ms
  • confs/tests.py:430 TestLegacyConferenceDataMigration._migrate · 71 ms
  • confs/tests.py:431 TestLegacyConferenceDataMigration._migrate · 58 ms
  • confs/migrations/0033_remove_legacy_conference_tables.py:398 migrate_legacy_pair · 48 ms
  • confs/tests.py:486 TestLegacyConferenceDataMigration._seed_overlapping_legacy_data · 46 ms

Most affected tests:

  • accounts/tests.py::TestAccountIndexRobots::test_two_facets_are_noindex
  • accounts/tests.py::TestSelectedInstance::test_invalid_selected_instance
  • confs/tests.py::TestSyncAnnouncements::test_is_idempotent_and_refreshes_unposted_content
  • confs/tests.py::TestMigratedLegacyConferences::test_fwd50_date_redirects
  • confs/tests.py::TestLegacyConferenceDataMigration::test_copies_overlapping_legacy_rows_without_clobbering_existing_data
  • confs/tests.py::TestLegacyConferenceDataMigration::test_drops_legacy_tables_when_uniques_are_mysql_style_indexes

Documentation

4

Run migrations once, not once per worker

Each of the 4 pytest-xdist workers builds its own test database by running every migration: 25.5s in total, about 6.4s per worker. 19.1s of it repeats work another worker already did.

Medium Migrations ci:github-actions:test
19.11 s per run
Fix: Migrate once and copy the database: let one worker build the test database and have the others create theirs from it as a template (on PostgreSQL, CREATE DATABASE ... TEMPLATE ..., which copies files instead of running migrations). Django's own test runner already does this with --parallel. Read the guide
Details

Every copy is built by the same migrations, so a broken migration still fails the run.

  • {'total': 25.485, 'builds': 4, 'workers': 4, 'per_build': 6.371}

Documentation

CI vs local

Tests that are much slower in CI, and why

Upload profiles from CI and from a developer machine to compare them.

Locally: FLAKYTEST_SECRET_TOKEN=… pytest --flakytest-profile

Failing and flaky tests

1 regression caught
Test Verdict CI fails Local fails Fail rate Last failure
starter_packs/tests.py::TestShareStarterPack::test_api_plain_json Regression caught 1/12 0/0 8% 3 weeks ago
Flaky: failed and passed on the same commit. Regression caught: fixed by a change outside the test file. Test changed: fixed by editing the test. All failing tests →

Environments

Every CI job and developer machine that reported in the last 30 days
Environment Profiled runs Sessions Avg wall time Peak memory Last seen
CI github-actions:test 10 12 39.07 s 679 MB 6 hours ago
CI github-actions 0 0 – – 4 months, 2 weeks ago