--- last_review: "2025-01-01" last_reviewer: "-" documented_code: [ ] --- ```{tags} how-to, developer, end-to-end-test ``` # Safely writing system/end-to-end tests :::{note} This page has been migrated from the old documentation, and has not yet been fully revised. There might be inconsistencies or errors when using with current LinkAhead versions. ::: % TODO: Issue: https://gitlab.indiscale.com/caosdb/src/linkahead-docs/-/issues/92 % TODO: Decide whether this should be a how-to or a tutorial and rewrite with that in mind When writing system or end-to-end tests, both when developing LinkAhead itself and when developing your LinkAhead custom code, we often need to write/update/or delete entities -- we might even want to clear the entire database before and after running the tests, as it is done, for example, in the [LinkAhead Python Integration Tests](https://gitlab.com/linkahead/linkahead-pyinttest). Of course, we do not want to accidentally run such a test suite against a production LinkAhead instance. Luckily LinkAhead offers infrastructure that ensures that system tests are only run against the LinkAhead instance that they are intended to, and no other instance. This tutorial explains how to set up this infrastructure. The test infrastructure is implemented in the [`linkahead.utils.register_tests`](/reference/pylib/api/linkahead.utils.register_tests.rst) and requires an environment variable `_CAOSDB_INTEGRATION_TEST_SUITE_KEY` in the LinkAhead server. If you're using LinkAhead control, you can set this variable in your `profile.yml`. ```yaml profile-name: # Usually, this is "default" conf: server: conf: # Sets the environment variable for the LinkAhead server # inside the docker container. _CAOSDB_INTEGRATION_TEST_SUITE_KEY: "MY_TEST_KEY_STRING" ``` :::{warning} For safety reasons, never set `_CAOSDB_INTEGRATION_TEST_SUITE_KEY` on a server used for production. ::: Once this environment variable is set, we can use the `linkahead.utils.register_tests.set_key` function to register our system test file(s). Assume you're writing your tests in a file called `test_system.py`, you import this function and use it at the top of your code. ```python from linkahead.utils import register_tests register_tests.set_key("MY_TEST_KEY_STRING") ``` Afterward you can use, e.g., the `clear_database` fixture to wipe the database before and after executing a specific test. ```python import linkahead as db from linkahead.utils import register_tests register_tests.set_key("MY_TEST_KEY_STRING") # You can use a pytest fixture as an argument of your test function, # see https://docs.pytest.org/en/7.1.x/how-to/fixtures.html. def test_is_empty(register_tests.clear_database): # Test that there is no entity in the database assert db.execute_query("COUNT ENTITY") == 0 ``` If you had registered the tests with a different key, i.e., called `register_tests.set_key` with argument that doesn't match the value of `_CAOSDB_INTEGRATION_TEST_SUITE_KEY`, the `clear_database` fixture would have raised an error and would not have deleted anything. In case you want to use more specific write or delete actions before or after running your tests, you can use the `register_tests._assure_test_is_registered` method which compares the registered key with the server environment variable and raises an error if they don't match. This method needs to be called **before** any write transaction is executed, of course. In a test function, this could look the following. ```python def test_insert_and_delete(): # Check before writing register_tests._assure_test_is_registered() # Test that a RecordType can be inserted and deleted rt = db.RecordType(name="TestType").insert() assert len(db.execute_query(f"FIND RECORDTYPE WITH id={rt.id}")) == 1 rt.delete() assert len(db.execute_query(f"FIND RECORDTYPE WITH id={rt.id}")) == 0 ``` ## Setting the test key interactively The above explanations work when running your system tests manually by executing `pytest` on the command line yourself and in an automated setting like a CI pipeline. When running a test that uses the `register_tests` module interactively against a server that does not have the `_CAOSDB_INTEGRATION_TEST_SUITE_KEY` environment variable, you will be asked whether you want to register the test the first time you run it. If you agree, the environment variable is set by the `register_tests` module. This requires your server to run in debug mode, e.g., by having ```yaml profile-name: # Usually, this is "default" conf: debug: true ``` in your `profile.yml`. Otherwise, the environment variable can't be set by the client.