Failed Run of Oct 18, 15:53
pytest --flakytest-profile --flakytest-rate 1000.
Where the time goes
Test time by category- Password hashing47.43 s
- Migrations39.98 s
- Libraries38.24 s
- Database12.22 s
- Mocking3.46 s
- DB schema3.19 s
- Imports3.10 s
- Templates2.16 s
- pytest915 ms
- Factories593 ms
- Unsampled358 ms
- App code146 ms
- Deep copies68 ms
- Waiting46 ms
- Test code35 ms
- Network34 ms
- Cache27 ms
- Logging16 ms
- Serialization11 ms
Session timeline
Fix next
Ranked by the time each fix saves per runUse plain static file storage in tests
Static file storage/manifest handling costs 45.3s.
Details
Where:
- starter_packs/tests.py:840 test_api_formats · 1.24 s
- confs/tests.py:152 _assert_no_naive_warning · 1.15 s
- accounts/tests.py:550 assert_noindex · 1.07 s
- accounts/tests.py:555 assert_indexable · 998 ms
- starter_packs/tests.py:780 test_order_by · 974 ms
- starter_packs/tests.py:820 test_sort_select_avoids_inline_js · 900 ms
- accounts/views.py:428 index · 826 ms
- accounts/tests.py:536 test_developers_on_mastodon · 636 ms
- confs/tests.py:884 test_conference_with_pacific_with_date · 625 ms
- starter_packs/tests.py:197 test_not_owned_starter_pack · 556 ms
Most affected tests:
- starter_packs/tests.py::TestShareStarterPack::test_sort_select_avoids_inline_js
- confs/tests.py::TestConferencePage::test_conference_with_pacific_with_date
- accounts/tests.py::TestStaticPages::test_developers_on_mastodon
- confs/tests.py::TestMigratedLegacyConferences::test_djangoconafrica_page
- starter_packs/tests.py::TestShareStarterPack::test_non_discoverable_accounts
- starter_packs/tests.py::TestStarterPacks::test_index_page_language_filter
- starter_packs/tests.py::TestEditStarterPack::test_not_owned_starter_pack
- accounts/tests.py::TestAccountIndexRobots::test_single_facet_is_indexable
Use a fast password hasher in tests
47.4s (31% of test time) is spent hashing passwords. Slow hashing protects real passwords; in tests it only burns CPU.
Details
Only change the hasher in test settings. Tests that assert on a specific hash format need updating.
Where:
- confs/tests.py:1044 setUp · 8.94 s
- confs/tests.py:1175 setUp · 6.35 s
- confs/tests.py:1176 setUp · 5.77 s
- confs/tests.py:1371 setUp · 5.75 s
- confs/tests.py:1177 setUp · 5.45 s
- confs/tests.py:1372 setUp · 5.35 s
- confs/tests.py:1316 setUp · 3.65 s
- confs/tests.py:1317 setUp · 2.96 s
- fedidevs/tests.py:62 test_authenticated_html_is_private_and_keeps_csrf_header · 1.17 s
- fedidevs/tests.py:63 test_authenticated_html_is_private_and_keeps_csrf_header · 794 ms
Most affected tests:
- confs/tests.py::TestEditConference::test_owner_can_edit
- confs/tests.py::TestEditConference::test_other_user_forbidden_on_approved_conference
- confs/tests.py::TestEditConference::test_edit_does_not_change_slug
- confs/tests.py::TestEditConference::test_other_user_forbidden
- confs/tests.py::TestApproveConference::test_anonymous_sees_pending_banner_without_button
- confs/tests.py::TestApproveConference::test_staff_sees_approve_button_on_detail
- confs/tests.py::TestEditConference::test_owner_can_edit_after_approval
- confs/tests.py::TestConferenceApprovalVisibility::test_other_user_does_not_see_pending
Stop re-running migrations on every test run
Migrations take 40.0s per run, before the first test can start.
Details
CI should still build the database from scratch (no --reuse-db) so broken migrations are caught.
Where:
- confs/tests.py:432 _migrate · 2.48 s
- confs/migrations/0031_seed_conference_tags.py:14 seed_conference_tags · 934 ms
- confs/migrations/0033_remove_legacy_conference_tables.py:388 _get_or_create_conference · 177 ms
- confs/tests.py:430 _migrate · 172 ms
- confs/tests.py:412 _leaf_targets · 170 ms
- confs/migrations/0033_remove_legacy_conference_tables.py:214 _pk_batches · 157 ms
- confs/tests.py:431 _migrate · 145 ms
- confs/migrations/0033_remove_legacy_conference_tables.py:328 _refresh_account_counts · 77 ms
- confs/migrations/0033_remove_legacy_conference_tables.py:398 migrate_legacy_pair · 60 ms
- confs/migrations/0033_remove_legacy_conference_tables.py:360 _attach_lookups_and_tags · 58 ms
Most affected tests:
- confs/tests.py::TestConferencePage::test_conference_with_utc_with_date_no_posts
- accounts/tests.py::TestAccountIndexRobots::test_single_facet_is_indexable
- accounts/tests.py::TestSelectedInstance::test_invalid_selected_instance
- confs/tests.py::TestMigratedLegacyConferences::test_djangoconus_old_url_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
Create shared test data in setUpTestData instead of setUp
setUp() runs before every test and takes 45.8s in total (password hashing 45.5s, db 271ms, factories 20ms) in 7 classes: TestPostAnnouncements (6 tests), TestFollowStarterPack (3 tests), TestConferenceApprovalVisibility (5 tests), TestApproveConference (6 tests).
Details
Since Django 3.2 attributes assigned in setUpTestData are deep-copied per test, so in-memory changes don't leak between tests. Keep objects a test modifies in the database (or re-fetches) as before.
Where:
- confs/tests.py:1044 setUp · 8.97 s
- confs/tests.py:1175 setUp · 6.37 s
- confs/tests.py:1176 setUp · 5.79 s
- confs/tests.py:1371 setUp · 5.76 s
- confs/tests.py:1177 setUp · 5.46 s
- confs/tests.py:1372 setUp · 5.36 s
- confs/tests.py:1316 setUp · 3.67 s
- confs/tests.py:1317 setUp · 2.96 s
- confs/tests.py:1295 setUp · 635 ms
- confs/tests.py:1296 setUp · 614 ms
Most affected tests:
- confs/tests.py::TestEditConference::test_owner_can_edit
- confs/tests.py::TestEditConference::test_other_user_forbidden_on_approved_conference
- confs/tests.py::TestEditConference::test_edit_does_not_change_slug
- confs/tests.py::TestEditConference::test_other_user_forbidden
- confs/tests.py::TestApproveConference::test_anonymous_sees_pending_banner_without_button
- confs/tests.py::TestApproveConference::test_staff_sees_approve_button_on_detail
- confs/tests.py::TestEditConference::test_owner_can_edit_after_approval
- confs/tests.py::TestConferenceApprovalVisibility::test_other_user_does_not_see_pending
Repeated queries (N+1) in the code under test
10 tests run the same query 10+ times, e.g. 45x in test_single_facet_is_indexable. N+1 queries slow the tests and production alike.
Details
This changes application code, so it speeds up production too; the tests stay as they are.
- 45x in test_single_facet_is_indexable: SELECT "confs_conferencetag"."id", "confs_conferencetag"."name", "confs_conferencetag"."slug", "confs_conferencetag"."icon" FROM "confs_conferencetag" WHERE "confs_conferencetag"."slug" = %s LIMIT ? FOR UPDATE
- 45x in test_invalid_selected_instance: SELECT "confs_conferencetag"."id", "confs_conferencetag"."name", "confs_conferencetag"."slug", "confs_conferencetag"."icon" FROM "confs_conferencetag" WHERE "confs_conferencetag"."slug" = %s LIMIT ? FOR UPDATE
- 45x in test_djangoconus_old_url_redirects: SELECT "confs_conferencetag"."id", "confs_conferencetag"."name", "confs_conferencetag"."slug", "confs_conferencetag"."icon" FROM "confs_conferencetag" WHERE "confs_conferencetag"."slug" = %s LIMIT ? FOR UPDATE
- 45x in test_conference_with_utc_with_date_no_posts: SELECT "confs_conferencetag"."id", "confs_conferencetag"."name", "confs_conferencetag"."slug", "confs_conferencetag"."icon" FROM "confs_conferencetag" WHERE "confs_conferencetag"."slug" = %s LIMIT ? FOR UPDATE
- 44x in test_store_daily_stats: SELECT COUNT(*) AS "__count" FROM "accounts_accountlookup" WHERE UPPER("accounts_accountlookup"."language"::text) LIKE UPPER(%s)
Most affected tests:
- accounts/tests.py::TestAccountIndexRobots::test_single_facet_is_indexable
- accounts/tests.py::TestSelectedInstance::test_invalid_selected_instance
- confs/tests.py::TestMigratedLegacyConferences::test_djangoconus_old_url_redirects
- confs/tests.py::TestConferencePage::test_conference_with_utc_with_date_no_posts
- stats/tests.py::TestStats::test_store_daily_stats
- stats/tests.py::TestStats::test_store_daily_stats_with_accounts
- stats/tests.py::TestStats::test_posts_from_yesterday_are_updated
- accounts/tests.py::TestInstanceIndexingBridgy::test_follows_redirect_and_coerces_null_version
Make the test database server skip durability work
Tests spend 55.4s (36%) in the database. Test databases don't need to survive a crash, so the server can skip flushing to disk.
Details
Only affects crash safety of the throwaway test server; query behaviour is identical.
Where:
- confs/tests.py:432 _migrate · 2.48 s
- starter_packs/tests.py:396 test_toggle_after_limit · 1.11 s
- confs/migrations/0031_seed_conference_tags.py:14 seed_conference_tags · 934 ms
- stats/models.py:20 store_daily_stats · 282 ms
- stats/models.py:12 store_daily_stats · 232 ms
- confs/migrations/0033_remove_legacy_conference_tables.py:388 _get_or_create_conference · 177 ms
- confs/tests.py:430 _migrate · 172 ms
- confs/tests.py:412 _leaf_targets · 170 ms
- starter_packs/views.py:729 share_starter_pack · 167 ms
- confs/migrations/0033_remove_legacy_conference_tables.py:214 _pk_batches · 157 ms
Most affected tests:
- accounts/tests.py::TestSelectedInstance::test_invalid_selected_instance
- confs/tests.py::TestConferencePage::test_conference_with_utc_with_date_no_posts
- accounts/tests.py::TestAccountIndexRobots::test_single_facet_is_indexable
- confs/tests.py::TestMigratedLegacyConferences::test_djangoconus_old_url_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
- starter_packs/tests.py::TestToggleStarterPackAccount::test_toggle_after_limit
- mastodon_auth/tests.py::RegisterAppTests::test_raises_with_status_code_on_429
Disable django-debug-toolbar in tests
django-debug-toolbar is installed in the test settings and costs 8.7s.
Details
Where:
- accounts/views.py:428 index · 826 ms
- confs/views.py:299 _conference_detail · 492 ms
- starter_packs/views.py:865 share_starter_pack · 382 ms
- confs/views.py:512 create_conference · 192 ms
- starter_packs/views.py:188 starter_packs · 185 ms
- starter_packs/views.py:729 share_starter_pack · 170 ms
- starter_packs/views.py:858 share_starter_pack · 145 ms
- accounts/views.py:28 __init__ · 145 ms
- confs/views.py:131 conferences · 137 ms
- accounts/templatetags/account_extras.py:27 render_language_emojis · 124 ms
Most affected tests:
- accounts/tests.py::TestSelectedInstance::test_invalid_selected_instance
- confs/tests.py::TestMigratedLegacyConferences::test_dotnetconf_page
- confs/tests.py::TestConferencePage::test_conference_with_utc_with_date_no_posts
- accounts/tests.py::TestAccountIndexRobots::test_single_facet_is_indexable
- fedidevs/tests.py::TestAnonymousCacheAndCsrf::test_anonymous_forms_work_after_csrf_bootstrap
- accounts/tests.py::TestSelectedInstance::test_selected_instance_through_session
- fedidevs/tests.py::TestAnonymousCacheAndCsrf::test_other_pages_keep_unknown_query_params
- accounts/tests.py::TestSelectedInstance::test_selected_instance
pytest takes a long time before the first test runs
Startup takes 7.3s and collection 3.8s on every run, even when you only run one test.
Details
- mastodon_auth/tests.py (1.0s)
- starter_packs/tests.py (207ms)
- accounts/tests.py (52ms)
- confs/tests.py (29ms)
- stats/tests.py (9ms)
- fedidevs/settings.py (1.9s)
- starter_packs/admin.py (1.3s)
- debug_toolbar/panels/sql/__init__.py (885ms)
Modules are imported while tests run
3.1s of test time is spent importing modules: whichever test imports a heavy module first pays for it, which makes that test look slow (and varies with test order).
Details
Where:
- confs/views.py:299 _conference_detail · 152 ms
- mastodon_auth/forms.py:27 clean_instance · 120 ms
- confs/og_images.py:246 render_conference_og_image · 118 ms
- confs/tests.py:431 _migrate · 103 ms
- accounts/management/commands/indexer.py:81 handle · 91 ms
- confs/tests.py:875 test_conference_with_utc_with_date_no_posts · 81 ms
- confs/tests.py:412 _leaf_targets · 73 ms
- accounts/views.py:428 index · 65 ms
- starter_packs/splash_images.py:192 is_character_in_font · 39 ms
- accounts/tests.py:555 assert_indexable · 34 ms
Most affected tests:
- accounts/tests.py::TestSelectedInstance::test_invalid_selected_instance
- accounts/tests.py::TestAccountIndexRobots::test_single_facet_is_indexable
- confs/tests.py::TestMigratedLegacyConferences::test_djangoconus_old_url_redirects
- confs/tests.py::TestConferencePage::test_conference_with_utc_with_date_no_posts
- confs/tests.py::TestConferenceOgImage::test_management_command_renders_missing_and_skips_current
- confs/tests.py::TestLegacyConferenceDataMigration::test_drops_legacy_tables_when_uniques_are_mysql_style_indexes
- mastodon_auth/tests.py::MastodonLoginFormTests::test_cleans_instance_to_ascii_hostname
- confs/tests.py::TestLegacyConferenceDataMigration::test_copies_overlapping_legacy_rows_without_clobbering_existing_data
Tests
1–200 of 301, slowest first · click a column to sort this pageMemory
Busiest worker peaked at 207 MB; all 4 together at about 673 MB| Worker | Tests | Peak | Grew by |
|---|---|---|---|
| gw0 | 101 | 202 MB | 57 MB |
| gw1 | 118 | 195 MB | 54 MB |
| gw2 | 49 | 207 MB | 35 MB |
| gw3 | 33 | 178 MB | 40 MB |
Slowest fixtures
Exact setup time across the session| Fixture | Scope | Calls | Total |
|---|---|---|---|
| _django_setup_unittest | class | 75 | 39.77 s |
| django_db_setup | session | 4 | 39.69 s |
| _unittest_setUpClass_fixture_TestSelectedInstance | class | 1 | 290 ms |
| _unittest_setUpClass_fixture_TestShareStarterPack | class | 2 | 208 ms |
| _unittest_setUpClass_fixture_TestEditStarterPackAccounts | class | 2 | 206 ms |
| _unittest_setUpClass_fixture_TestConferencePage | class | 2 | 192 ms |
| _unittest_setUpClass_fixture_TestPinAccountInStarterPack | class | 2 | 153 ms |
| _unittest_setUpClass_fixture_TestOwnerManagement | class | 2 | 122 ms |
| _unittest_setUpClass_fixture_TestFollowStarterPack | class | 2 | 108 ms |
| _unittest_setUpClass_fixture_TestFollowBg | class | 1 | 77 ms |
| _unittest_setUpClass_fixture_TestWebfingerBackfill | class | 1 | 73 ms |
| _django_isolate_apps | function | 301 | 65 ms |
| _unittest_setUpClass_fixture_TestStarterPacks | class | 1 | 62 ms |
| _unittest_setUpClass_fixture_TestRemoteFollowStarterPack | class | 2 | 61 ms |
| _unittest_setUpClass_fixture_TestAddAccountsSearch | class | 1 | 60 ms |