| .. Licensed to the Apache Software Foundation (ASF) under one | |
| or more contributor license agreements. See the NOTICE file | |
| distributed with this work for additional information | |
| regarding copyright ownership. The ASF licenses this file | |
| to you under the Apache License, Version 2.0 (the | |
| "License"); you may not use this file except in compliance | |
| with the License. You may obtain a copy of the License at | |
| .. http://www.apache.org/licenses/LICENSE-2.0 | |
| .. Unless required by applicable law or agreed to in writing, | |
| software distributed under the License is distributed on an | |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| KIND, either express or implied. See the License for the | |
| specific language governing permissions and limitations | |
| under the License. | |
| Airflow System Tests | |
| ==================== | |
| System tests verify the correctness of Airflow Operators by running them in Dags and allowing to communicate with | |
| external services. A system test tries to look as close to a regular Dag as possible, and it generally checks the | |
| "happy path" (a scenario featuring no errors) ensuring that the Operator works as expected. | |
| System tests need to communicate with external services/systems that are available | |
| if you have appropriate credentials configured for your tests. | |
| .. contents:: Table of Contents | |
| :depth: 2 | |
| :local: | |
| Purpose of System Tests | |
| ----------------------- | |
| The purpose of these tests is to: | |
| - assure high quality of providers and their integration with Airflow core, | |
| - avoid regression in providers when doing changes to the Airflow, | |
| - autogenerate documentation for Operators from code, | |
| - provide runnable example Dags with use cases for different Operators, | |
| - serve both as examples and test files. | |
| - the excerpts from these system tests are used to generate documentation | |
| Usage options | |
| ------------- | |
| The System tests allow for two ways of execution: invoking an Airflow Executor of the developer's choice, or to simulate | |
| the executor's actions (based on base, generic executor behavior) rather focusing on the Dags execution only. | |
| The former behavior can be particularly useful: | |
| - to test custom Airflow Executors against a "real-life" environment | |
| - to test custom Airflow Operators (Decorators, etc.) against a "real-life" environment | |
| The latter can be useful in attempt to concentrate on the Dag execution within the tests, avoiding interference coming | |
| from additional layers of complexity. | |
| The Airflow System tests can be very useful as much for automated pipelines as for manual executions. | |
| Configuration | |
| ------------- | |
| Environment for System Tests | |
| ............................ | |
| **Prerequisites:** You may need to set some variables to run system tests. | |
| Usually you must set-up ``SYSTEM_TESTS_ENV_ID`` to a random value to avoid conflicts with other tests and | |
| set it before running test command. | |
| .. code-block:: bash | |
| SYSTEM_TESTS_ENV_ID=SOME_RANDOM_VALUE | |
| Executor | |
| ........ | |
| Regarding the usage of Executors: by default Airflow System tests are not using an Airflow executor. But instead | |
| simulate the core behavior of a simple, generic one (like ``LocalExecutor``). | |
| In case you would like to have an actual Executor involved, you need to set the following variable: | |
| .. code-block:: bash | |
| export _AIRFLOW__SYSTEM_TEST_USE_EXECUTOR = 1 | |
| Custom configuration file | |
| ......................... | |
| .. note:: This section mostly corresponds when developing custom providers, outside of the Apache Airflow codebase | |
| The Airflow configuration system works in a way, that for test environments specific test configuration file locations | |
| are enforced to avoid accidentally loading configuration of valid Airflow installations. There are pytest fixtures | |
| available for Airflow Unit tests, however those are not possible to be used for Airflow System tests. | |
| An option to load a custom configuration file for your System Tests may be to add something similar to ``conftest.py``, to | |
| an early stage of pytest session initialization (for example in the ``pytest_configure`` function): | |
| .. code-block:: python | |
| from airflow.configuration import conf | |
| conf.read_file(open(f"{YOUR_TEST_CONFIG_FILE}")) | |
| Custom configuration allows an easy way to load numerous custom options at once (typically ones that may correspond | |
| to custom providers). | |
| Running the System Tests | |
| ------------------------ | |
| There are multiple ways of running system tests. Each system test is a self-contained Dag, so it can be run as any | |
| other Dag. Some tests may require access to external services, enabled APIs or specific permissions. Make sure to | |
| prepare your environment correctly, depending on the system tests you want to run - some may require additional | |
| configuration which should be documented by the relevant providers in their subdirectory | |
| ``providers/<provider_name>/tests/system/<provider_name>/README.md``. | |
| Running as Airflow Dags | |
| ....................... | |
| If you have a working Airflow environment with a scheduler and a webserver, you can import system test files into | |
| your Airflow instance as Dags and they will be automatically triggered. If the setup of the environment is correct | |
| (depending on the type of tests you want to run), they should be executed without any issues. The instructions on | |
| how to set up the environment is documented in each provider's system tests directory. Make sure that all resource | |
| required by the tests are also imported. | |
| Running via Pytest + Breeze | |
| ........................... | |
| Running system tests with pytest is the easiest with `Breeze <https://github.com/apache/airflow/blob/main/dev/breeze/doc/README.rst>`_. | |
| Breeze makes sure that the environment is pre-configured, and all additional required services are started, | |
| off-loading the developer from the overhead of test environment setup. | |
| Running manually via Pytest | |
| ........................... | |
| You can either run them using your IDE (if you have installed plugin/widget supporting pytest) or using the following | |
| example of command: | |
| For core: | |
| .. code-block:: bash | |
| pytest --system airflow-core/tests/system/example_empty.py | |
| For providers: | |
| .. code-block:: bash | |
| pytest --system providers/google/tests/system/google/cloud/bigquery/example_bigquery_queries.py | |
| NOTE: If using an actual Executor, you may need to make sure that the Airflow API server is running as well. | |
| (In order to benefit from default configuration, it should be a run locally.) | |
| .. code-block:: bash | |
| uv run airflow api-server | |
| Running manually via Pytest outside of the Airflow codebase | |
| ........................................................... | |
| .. note:: This section mostly corresponds when developing custom providers, outside of the Apache Airflow codebase | |
| 1. Airflow Plugin | |
| You will need to use the Airflow pytest plugin, which is available as part of the ``apache-airflow-devel-common`` | |
| package. It's a good choice to install the package (as it makes the plugin and related dependences easily available). | |
| However the plugin it is generally used within the Airflow codebase (not as a package), so you may be facing issues | |
| using it on its own, outside of the Airflow codebase. In this case you could clone the Airflow git repository, and set | |
| the following environment variables to point to this location. This should ensure a safe and stable use of the pytest | |
| plugin. | |
| .. code-block:: bash | |
| export AIRFLOW_SOURCES=<CLONE_OF_THE_AIRFLOW_GIT_REPO> | |
| 2. Airflow API server | |
| In case you want to run tests against an Airflow Executor, you will need to have the Airflow API server available. | |
| NOTE: You have to make sure that the API server is sharing certain configuration as the test environment. This is | |
| particularly important so that the Airflow Task SDK may be able to communicate to the API Server. | |
| (For example, the same JWT secret must be used on both sides for token encryption/description. By default the Airflow | |
| test environment is using temporary JWT secrets generated on-the-fly. If you want to keep control over these settings, | |
| the best solution is to follow instructions from the :ref:`Custom configuration file` section. | |
| Running via Breeze | |
| .................. | |
| You can also run system tests using Breeze. To do so, you need to run the following command: | |
| For core: | |
| .. code-block:: bash | |
| breeze testing system-tests airflow-core/tests/system/example_empty.py | |
| If you need to add some initialization of environment variables when entering Breeze, you can add a | |
| ``environment_variables.env`` file in the ``files/airflow-breeze-config/environment_variables.env`` file. | |
| It will be automatically sourced when entering the Breeze environment. You can also add some additional | |
| initialization commands in the ``files/airflow-breeze-config/init.sh`` file if you want to execute | |
| something always at the time of entering Breeze. | |
| For system tests run in Breeze, you can also forward authentication from the host to your Breeze container. | |
| You can specify the ``--forward-credentials`` flag when starting Breeze. Then, it will also forward the | |
| most commonly used credentials stored in your ``home`` directory. Use this feature with care as it makes | |
| your personal credentials visible to anything that you have installed inside the Docker container. | |
| Currently forwarded credentials are: | |
| * credentials stored in ``${HOME}/.aws`` for ``aws`` - Amazon Web Services client | |
| * credentials stored in ``${HOME}/.azure`` for ``az`` - Microsoft Azure client | |
| * credentials stored in ``${HOME}/.config`` for ``gcloud`` - Google Cloud client (among others) | |
| * credentials stored in ``${HOME}/.docker`` for ``docker`` client | |
| * credentials stored in ``${HOME}/.snowsql`` for ``snowsql`` - SnowSQL (Snowflake CLI client) | |
| ------ | |
| For other kinds of tests look at `Testing document <../09_testing.rst>`__ |