Caesar - Documentation and Testing¶
Purpose of Module¶
The features described in this module aim to make Caesar easier to use, maintain and develop, by anyone who is interested in doing so.
Unit Tests¶
Caesar uses pFUnit to build and run unit tests. The unit test files used by pFUnit are preprocessed into fortran, and so the unit tests can be built and run alongside the rest of the code, using CMake.
Each module file *.f90
has an accompanying test file, *_test.pf
, containing the
test procedures for that module. It is impractical for the unit tests to be exhaustive,
and so they aim to cover several standard use cases as well as any obvious edge cases.
In particular, use cases which were known to cause bugs in previous versions of Caesar
are included in the unit tests, as a form of regression testing.
Documentation¶
The documentation for Caesar is generated using Ford. Ford generates documentation directly from the fortran source code, and so the documentation for each procedure is written in the same place as the interface for that procedure.
Each procedure has documentation describing what the procedure does, what the input and output arguments to the procedure are, and what happens in the case of an error. The details of how each procedure works are presented separately, as code comments in the implementation of each procedure.
Helptext¶
Caesar uses a custom system to process the input arguments for the various user-accessible procedures.
Each input argument is defined using a KeywordData
type, which stores the name of
the argument, a helptext string describing the argument, and relevant metadata
including whether or not the argument is optional, and what the argument’s default
value is, if relevant.
Once the array of input arguments for a given procedure has been created, it is passed to the input parsing system. The input parsing system then gets the value of each argument from the user, either from command line arguments, from an input file, or from an interactive procedure which describes each argument to the user in turn, and prompts them to input the argument values.
Once the inputs are parsed, the relevant Caesar subroutine is called, with a dictionary-style container, containing the input arguments as key-value pairs. Each input argument can then be accessed by name, and the container returns the string representation of the argument’s value, which can be parsed by the subroutine.
In addition to driving the input parser, the list of arguments is used to generate
helptext. Calling caesar [mode] --help
generates the list of arguments for the
requested mode
, and prints the helptext for each argument in turn.
Submodules¶
As part of the process of writing documentation and unit tests, every procedure in Caesar was separated into an interface and and implementation, through the use of fortran submodules. This has a number of advantages:
- Submodules allow for circular dependencies which break free from fortran’s strict module hierarchy. This allow modules to be separated into inter-dependent libraries, grouped together based on their functionality rather than their dependencies.
- Circular dependencies make it much easier to add new implementations of abstract classes, as functions which “know about” (i.e. have dependencies on) all of the class implementations can be called by the methods of the parent class. This means that Caesar can easily be updated to use new potential and state representations, sampling methods, and convergence algorithms, without requiring future developers to modify the code in more than a couple of places.
- The documentation for the procedure interfaces and the procedure implementations is separated. This allows for easy browsing of interface documentation, with implementation documentation hidden until needed.
- Unit tests can be checked for code coverage by comparing the test files with the interface files, without having to consider the implementation files.
- When procedure implementations are modified, only the modified submodules need to be re-compiled. This avoids the compilation cascades which are endemic to module-only fortran projects, and dramatically reduces total compilation time for developers.
Source Code¶
The source code for Caesar is available from the
Caesar repository. The source code for the
helptext system is found in the src/common/arguments
directory of this repository.