Application development guidelines
This section contains development guidelines which apply to all languages
Coding guidelines
General style
A1. Coding style should be consistent at project level or, for complex applications, at least at package level. That is, the same syntax and the same functions should be used throughout all the code to perform the same actions.
A2. Idiomatic constructs of the used language should be preferred.
Variables, functions and packages
B1. The names of the variables and of the functions must be clear and meaningful, and confusing abbreviation must be avoided. As a rule of thumb, the greater the distance between a name’s declaration and its use, the longer the name should be.
B2. The names of the packages should be short and evocative.
B3. Every package should have a package comment, a block comment preceding the package clause. For multi-file packages, the package comment only needs to be present in one file, and any one will do. The package comment should introduce the package and provide information relevant to the package as a whole.
B4. All public variables and functions should be preceded by a comment describing them. The comment should only contain complete sentences ending in a period, the first one being a one-sentence summary starting with the name of the declared variable or function.
B5. TODO
comments in the code should be avoided or timely fixed.
B6. Comments that are not relevant or code that is commented and no longer used should be removed.
B7. Only the strictly necessary variables and functions should be made publicly accessible from outside the package they are defined.
B8. Very long functions (e.g., >100 lines) should be avoided. In general, a function should have a single responsibility.
B9. Functions should contain only the strictly necessary code to carry out their assigned functionalities. This means, for example, that it should be avoided code performing redundant checks to handle cases that would be correctly managed by the regular function execution flow.
B10. When possible, you should privilege the use of standard functions already provided for the language instead of implementing your own.
B11. All implemented functions should be used. Keeping unused functions results, among the other things, in misleading test coverage reports.
B12. Uncomfortably long lines of code should be avoided. Readability should be the most important parameter to take into account when deciding if and where break up a line.
B13. Custom types may be defined when this improves code readability.
Configuration
C1. Applications configuration should be performed by providing options at startup and/or through configuration files and/or through environment variables.
C2. Configuration files must be encoded in a standard format (e.g., TOML), and robust parsers should be used to read them.
C3. Hardcoded values should be avoided.
Errors and log
D1. Errors must always be checked and managed, and in a consistent way throughout the codebase.
D2. The correctness of the format of the arguments that are passed to the Command Line Interface (CLI) of the application, if any, should always be checked before the application tries to use them. Appropriate and clear error messages should be returned to users when they enter bad-formatted arguments, to help them understand what is causing the error.
D3. A lexer/parser may be used to make the parsing of the CLI application arguments more robust.
D4. Log messages should be consistent at project level or, for complex applications, at least at package level.
D5. Logging in complex distributed applications should be performed through dedicated tools which collect all the logs and present them nicely (e.g., prometheus.io) or that trace what is happening by aggregating logs to units of work (e.g., honeycomb.io).
Other
E1. Files: Data files used by applications should be in a standard format (e.g., JSON) and manipulated through dedicated robust libraries.
E2. Multithreading: When using synchronous inter-thread communication the receiver thread should time out if it does not receive anything for a properly defined amount of time.
E3. Network: The previous guideline about timeout also applies for network communications.
Testing
F1. Unit tests should reveal undesired behaviours in normal and corner cases. To this end, they should be reproducible, and their inputs deterministic.
F2. Fuzzy tests can be used in addition to unit tests to check the robustness of the code when fed with random inputs.
F3. Tests should fail with helpful messages saying what was wrong, with what inputs, what was actually got, and what was expected.
F4. Tests should cover 70%-80% of the code.
F5. Applications should be automatically tested every time the code changes. To this end applications should be configured to be tested in a Continuous Integration (CI) platform. The CI platform used in the laboratory is Github Actions.
F6. The whole testing suite for CI should not take more than 5 minutes.
F7. Tests should not be used to implement utility functions. For this purpose proper command-line tools should be implemented instead.
F8. Tests that require external entities to be executed (e.g., a server) should check the value of specifically defined environment variables or flags, and be executed or skipped accordingly. If they are skipped, some feedback should be given to the user about how to run those tests. Alternatively, the external entities may be mocked with appropriate mocking frameworks.
F9. Dummy entries for test purposes should be provided for each typology of stored data.
F10. Besides executing tests, the CI platform should also be configured to perform formatting, linting and coverage checks.
Documentation
G1. Code must be documented through comments, mostly describing APIs and how to use them, exceptions, and special cases.
G2. Not obvious operations, optimisations and tricks should be properly documented.
G3. Hardcoded values should be properly documented.
G4. Applications must be documented through a readme file in the application repository, containing information at least about how to build and test them, how the source code is organised and how to contact the developers. To write the readme file you may follow this template.
G5. Applications may have a space in the lab GitBook containing end-user documentation. When this is the case, the readme file must contain a link to such space.
G6. Documentation about specific operational setup info should be maintained separate from the publicly available documentation, to not confuse users with internal docs and to avoid the accidental check in of security-sensitive information to a public repository. Operational documentation should be much smaller than the generally applicable application documentation (10:1).
G7. The application CLI, if any, should be exhaustively documented through clear and detailed usage info.
G8. The documentation should be regularly updated to reflect the changes in the application.
G9. Errors and typos in documentation should be avoided. Once identified, they must be timely fixed.
Last updated