Factorizer/Cluster ERP WikiCluster ERP Türkçe
Home / Contributing

Reference

Python tests

The pytest suite of Cluster ERP in tests/, its configuration, how to run it, and how live tests are waived with CLUSTER_SKIP_LIVE_TESTS.

The Python tests of Cluster ERP live in tests/ and run with pytest. This page lists the configuration, the command CI uses, the files grouped by area, and the rules for tests that need a live server or database. Browser tests are a separate suite; see e2e battery.

Scope and source

  • Defined in: tests/test_*.py and [tool.pytest.ini_options] in pyproject.toml.
  • Run by: the CI job test (.github/workflows/ci.yml:124).
  • Count: 106 test files, counted with ls tests/test_*.py. The folder has no conftest.py, and the repository root has none either (searched with ls).

Configuration

Name Value Meaning Source
asyncio_mode auto async def tests run without a marker pyproject.toml:152
testpaths tests pytest collects only tests/ pyproject.toml:153
pytest >=8.0.0 Version floor in the dev extra pyproject.toml:81
pytest-asyncio >=0.24.0 Version floor in the dev extra pyproject.toml:82

Running the tests

CI runs the suite after it has applied all migrations to an empty PostgreSQL 16 database (.github/workflows/ci.yml:113, .github/workflows/ci.yml:124):

python -m pytest -q --no-header -p no:cacheprovider

The same job sets CLUSTER_SKIP_LIVE_TESTS to 1 (.github/workflows/ci.yml:99). The workflow comment states why: the live guards need a booted server, and CI waives them so that the waiver is visible (.github/workflows/ci.yml:17-20).

Live tests

A live test needs a running server or a reachable test database. Eight files read CLUSTER_SKIP_LIVE_TESTS (counted with grep -l). They use two patterns.

Pattern Behaviour Files Source
Skip the whole module when waived A module-level skipif skips every test when the variable is 1 test_cal03_owner_calendars_live.py, test_calendar_owner_inherits_group_live.py, test_change_history_tables_live.py, test_deactivation_sweep_live.py, test_demo_data_live.py, test_login_budget_live.py tests/test_demo_data_live.py:24-27, tests/test_cal03_owner_calendars_live.py:22-24
Fail unless waived Without a server the test fails; only the variable turns the failure into a skip test_readiness_contract.py, test_search_contract.py tests/test_readiness_contract.py:37-44, tests/test_search_contract.py:162-171

The second pattern exists because "a silently skipped guard is indistinguishable from a passing one" (tests/test_readiness_contract.py:12-14). The live HTTP tests read the server address from CLUSTER_E2E_BASE, the same variable the browser battery uses (tests/test_readiness_contract.py:27).

Other tests depend on their environment without that variable:

Condition Behaviour Source
No reachable database The partial-index and foreign-key index checks skip tests/test_live_row_uniqueness.py:88-89, tests/test_fk_indexes.py:97-98
No bash on the machine The node script tests skip tests/test_bootstrap_node_script.py:35, tests/test_pg_tune_script.py:32
No bash or git The install script test skips tests/test_install_role_gate.py:41-44

Test files by area

The files are grouped by their names and module docstrings. A file sits in one group only.

Area Count Files
Architecture, static quality, and schema guards 9 test_architecture_boundaries.py, test_e2e_db_isolation.py, test_fk_indexes.py, test_fresh_install_contract.py, test_live_row_uniqueness.py, test_meta_representations.py, test_metadata_driven_rules.py, test_static_quality.py, test_webapp_asset_links.py
Analytics 18 test_analytics_classification.py, test_analytics_contributions.py, test_analytics_cross.py, test_analytics_forecasting.py, test_analytics_gates.py, test_analytics_inference.py, test_analytics_inference2.py, test_analytics_logit.py, test_analytics_pca_kmeans.py, test_analytics_plots.py, test_analytics_profiling.py, test_analytics_recipe.py, test_analytics_rmanova.py, test_analytics_saved_models.py, test_analytics_shapiro.py, test_analytics_statistics.py, test_analytics_stratification.py, test_analytics_summaries.py
Identity, access, tenancy, and privacy 30 test_abac_enforcement.py, test_abac_evaluator.py, test_abac_policy_condition.py, test_admin_bootstrap.py, test_at_rest_and_second_factor.py, test_auth_cache_stamp.py, test_authz_conformance.py, test_change_history_redaction.py, test_content_disposition.py, test_data_map_package1.py, test_data_map_package2.py, test_data_map_package3.py, test_data_map_package4.py, test_entitlement_stamp.py, test_erasure_ledger.py, test_log_sanitizer.py, test_login_budget_live.py, test_login_identifier.py, test_privacy_requests.py, test_residency_check.py, test_row_scope.py, test_secure_defaults.py, test_sensitive_fields_policy.py, test_settings_regions.py, test_settings_secret.py, test_signup_closed.py, test_signup_notice.py, test_signup_tokens.py, test_signup_validation.py, test_tenancy.py
Operations, deployment, and start-up 18 test_alembic_env_logging.py, test_backup_pipe.py, test_backup_retention.py, test_boot_migration_lock.py, test_bootstrap_node_script.py, test_change_history_tables_live.py, test_control_retention.py, test_database_plan_cache.py, test_deactivation_sweep_live.py, test_demo_data_live.py, test_install_restart_policy.py, test_install_role_gate.py, test_pg_tune_script.py, test_readiness_contract.py, test_request_cost.py, test_security_txt.py, test_server_keep_alive.py, test_staging_fixtures_guard.py
Business rules and module behaviour 28 test_board_calendar_chain.py, test_bom_bugfix_batch_2026_10_08.py, test_cal03_owner_calendars_live.py, test_calendar_owner_inherits_group_live.py, test_intranet_event_lifecycle.py, test_intranet_request_type_seeds.py, test_leave_day_math.py, test_mail_transport.py, test_nesting_units.py, test_order_shipment_chain.py, test_party_form_contract.py, test_procurement_descriptions.py, test_record_formatter_csv.py, test_record_links.py, test_refresh_routing_body.py, test_sales_delivery_day_party.py, test_scheduling_calendar.py, test_scheduling_calendar_chain.py, test_scheduling_capacity_units.py, test_search_contract.py, test_store_catalog_assets.py, test_subscription_math.py, test_system_mail.py, test_tenant_field_catalog.py, test_tenant_fields.py, test_work_center_capacity_cap.py, test_working_time_dst.py, test_working_time_overrides.py
Desktop client 3 test_desktop_app_scope.py, test_desktop_datetime_field.py, test_desktop_table_text_insets.py

The architecture guards are explained on architecture boundaries. The static quality test runs Ruff and mypy; see lint and type check. tests/test_e2e_db_isolation.py checks the browser suites as text; see e2e battery.

Constraints and validation

  • Tests that start subprocesses or reach a database name their own database; the battery isolation guard applies to the browser suites only (tests/test_e2e_db_isolation.py:1-19).
  • Not determined from code: a coverage measurement. No coverage tool is declared in pyproject.toml and none runs in .github/workflows/ci.yml.

Terms introduced

Term Code identifier Definition Turkish term Source
live test CLUSTER_SKIP_LIVE_TESTS A pytest test that needs a running server or a reachable test database and that the variable can waive. Canlı test tests/test_readiness_contract.py:12-14

Verified against commit 92f8051 on 2026-11-13.

Verified against commit 92f8051 · 2026-11-13