Skip to content
This repository has been archived by the owner on Nov 7, 2024. It is now read-only.

Developer Notes

Matthew D Jones edited this page Feb 4, 2021 · 42 revisions

Running unit tests

Unit tests are written to use pytest. Once the dependencies have been installed, they can be run from a terminal in the project's root directory by running the command pytest.

Test coverage can be checked by running the following from the root of the repository:

pytest --cov=nexus_constructor

Linter

flake8 is used to check pep8 compliance. It is installed via pip and can be run as flake8 in the project's root directory.

Formatting

black is used as a formatter for this codebase.

It can be used from the CLI from the root directory like so:

black .

or run on individual files with:

black <filename>

Testing the UI

UI tests are being run through the pytest-qt framework. This does have its limitations but has caught out several errors that were only going to be found in production otherwise.

A script for manually testing the UI's functionality can be found at tests/UITests.md

Building a distributable version

A distributable version of the app, with the required python interpreter and libraries included can be built using pyinstaller. It is included in the project's developer requirements file, and these must be installed in order to build the distributable. A build can be run with the following command in the projects root directory:

pyinstaller --windowed --noconfirm nexus-constructor.spec

This will create the executable and copy it's required files to the build subdirectory

pyinstaller is capable of building distributable versions for Windows, OS X, and Linux, but can only do so from a machine running that operating system.

JSON format

NeXus File-writer JSON stores an instrument's data in the format required by ESS-DMSC's Nexus File-writer to produce a standard compliant NeXus file.

See the nexus_constructor/json directory for implementation of saving to and loading from this format.

Custom Validators in the NeXus Constructor

This section describes the custom validators used in the NeXus constructor and their purpose.

UnitValidator

The UnitValidator uses the pint library to check if a text input matches a valid unit of length. It will return QValidator.Intermediate and emit the ValidationFailed signal if:

  • the input could not be converted to a known unit
  • the input is a unit of time/volume/area/etc
  • the input has no units and simply consists of a number
  • the input has a magnitude other than 1 (e.g. "40 cm")

Some of these inputs are required because pint is flexible about what it regards as an acceptable physical quantity object. If given an empty string, pint will convert this to 1 dimensionless instead of throwing an Exception. This behaviour can then cause problems if a dimensionless object is allowed to propagate further into the program and be passed to functions that assume it is a length. In light of this, some care may be required when using pint for checking lengths as you might assume it will reject inputs that it is actually able to accept.

If the input passes all of the above checks then the UnitValidator will return QValidator.Acceptable and emit the ValidationSuccess signal.