# Unit tests for ZOSPy

ZOSPy uses [PyTest][pytest] for unit testing. [Hatch][hatch] is used to automate testing for
different Python versions, and to run tests in an isolated environment. 
Running the tests with hatch also ensures that the package can be properly installed.

## How to run

- Install [hatch]: see the [Contribution guidelines](contributing.md#1-setting-up-a-development-environment).
- Run all tests for all Python versions:
  ```shell
  hatch test -a
  ```
- Alternatively, run tests for only the current Python version:
  ```shell
  hatch test 
  ```
- Tests can be run in extension mode or in standalone mode. By default, tests are run in standalone mode. To run tests in
  extension mode, use the `--extension` command line option. For example:
  ```shell
  hatch test -- --extension
  ```
  To make the tests run faster, UI updates are disabled when testing in extension mode.
  If UI updates are desired, these can be enabled with the `--update-ui` option.
- When running tests in extension mode, first open OpticStudio, enable the Interactive Extension mode, and
  uncheck "Auto Close on Disconnect".

## Command line options

- **`--extension`**: Since the ZOS-API is limited to only a single connection per session, it is not possible to test
  ZOSPy in extension mode and standalone mode simultaneously. Specifying the command line flag `--extension` instructs
  PyTest to connect to Zemax OpticStudio in extension mode. Make sure the interactive extension mode has been activated
  and `Auto Close on Disconnect` is unchecked.
- **`--output-directory <OUTPUT_DIRECTORY>`**: If specified, all created OpticStudio systems are saved to this
  directory.
- **`--opticstudio-directory <OPTICSTUDIO_DIRECTORY>`**: If specified, the path to the OpticStudio installation directory
  is set to this value. This is particularly useful if multiple OpticStudio versions are installed on the same system,
  and you want to use a specific version.
- **`--update-ui`**: If specified, UI updates are enabled when testing in extension mode. This can be useful for debugging
  purposes.

## Generating test reference data

The unit tests for `zospy.analyses` rely on reference data in order to check the validity of analysis results.
If the unit tests are run for the first time using a specific version of ZOSPy, these data are not yet present.
It can be generated by running

```shell
hatch run generate-reference-data
```

The generated reference data files will be added to `tests/data/reference`.

The reference data files are generated using a specification in `scripts/generate_test_reference_data/tests.yaml`.
If new analysis tests are added, this file needs to be extended with a reference specification for these tests.
A documented example specification is shown below.

```yaml
- # OpticStudio model as defined in scripts/generate_test_reference_data/systems.py
  model: simple_system
  # ZOSPy analysis, specified as a module relative to zospy.analyses
  analysis: raysandspots.ray_fan
  # Unit test file, relative to tests/analyses
  file: test_raysandspots.py
  # Unit test for which this reference data is intended
  test: test_ray_fan_returns_correct_result
  # Parameters that are parametrized using @pytest.mark.parametrize
  parametrized: [plot_scale, number_of_rays, tangential, sagittal]
  # List with the parameter sets in parameter_name: parameter_value format
  parameters:
    - plot_scale: 0
      number_of_rays: 20
      tangential: Aberration_Y
      sagittal: Aberration_X
    - plot_scale: 1
      number_of_rays: 40
      tangential: Aberration_Y
      sagittal: Aberration_X
```

[pytest]: https://docs.pytest.org
[hatch]: https://hatch.pypa.io
