Skip to main content

How to install the µTest++ Testing Framework

GitHub package.json version NPM Version NPM Downloads NPM Downloads license

As an xpm package, the the most convenient way to integrate the µTest++ Testing Framework into a project is to add it as a dependency via xpm.

However, as any source code library, this project can also be integrated into another project in the traditional manner, either by copying the relevant files into the target project, or by linking the entire project as a Git submodule.

xpm packages (xPacks) refresher

xpm packages, abbreviated as xPacks, are general-purpose, language-neutral software packages. They use the same format as npm packages, which is a collection of files/folders and a package.json file with the package metadata.

xpm can install source and binary packages.

For more details, please see the previous explanation in the Getting Started page.

Automated install

Alongside the source files, this project also includes a package.json file containing the metadata that identifies it as an xpm/npm package, enabling direct installation from GitHub or from the npmjs.com registry as @micro-os-plus/micro-test-plus.

Prerequisites

The only requirement for an automated install is a recent xpm, which is a portable Node.js command line application that complements npm with several extra features specific to C/C++ projects.

To install xpm, follow the instructions in the xpm install page.

If already installed, it is always a good idea to update it to the latest version with:

npm install --location=global xpm@latest
tip

Although not mandated by xpm, it is also a good idea to upgrade npm to the latest version, and node to a reasonably recent version (currently npm requires a node >=18.17.0).

Local installs

One of the xPack design goals is to allow each project to choose the exact versions of the libraries it requires.

Similarly to npm being able to install specific versions of the JavaScript tools into each project, xpm was also designed to be able to install specific versions of the required libraries locally into each project.

Therefore, similarly to the way npm installs the JavaScript packages into node_modules, xpm installs the libraries into xpacks. Here there will be separate folders with the installed packages, for example xpacks/@micro-os-plus/micro-test-plus.

Initialise the project

Upon initial use, ensure that a package.json file is present in the project root folder.

This can be achieved by running xpm init in the desired project folder (substitute my-project accordingly):

cd my-project
xpm init
Under the hood

The main purpose of xpm init is to create a package.json file, if not already present.

In addition to name & version, the minimal package.json must include a property named xpacks, even empty. This property is mandatory to identify the package as an xpm package.

Install via xpm

The next step is to install the micro-test-plus package into the project.

The command to install the latest available version of micro-test-plus is:

xpm install @micro-os-plus/micro-test-plus@latest --verbose

To install a specific version, specify it explicitly:

xpm install @micro-os-plus/micro-test-plus@3.2.2 --verbose
Installation details

The above xpm install command will do the following:

  • identify the desired version of @micro-os-plus/micro-test-plus, download it into a cache and unpack it into a versioned folder in the user's global xPacks store (if not already there); check the output of the xpm install command for the actual folder used on your platform;
  • create a local symbolic link like xpacks/@micro-os-plus/micro-test-plus pointing to the versioned folder in the user's global xPacks store
  • add @micro-os-plus/micro-test-plus to package.json as a dependency; this associates a specific version of the µTest++ Testing Framework with the current project (details below).
tip

The install location can be configured using the XPACKS_STORE_FOLDER environment variable; for more details please check the xpm folders page.

Reproducibility and dependencies

To ensure reproducibility, it is essential for each project to always use the exact desired versions of the required libraries, regardless of the libraries installed in the system.

To achieve this goal, xpm records all locally installed packages as dependencies in the project package.json file.

The result looks like this:

  "xpack": {
"minimumXpmRequired": "0.20.7",
"dependencies": {
"@micro-os-plus/micro-test-plus": {
"specifier": "3.2.2",
"local": "link",
"platforms": "all"
}
},
"devDependencies": {},
"properties": {},
"actions": {},
"buildConfigurations": {}
}

If the package.json is saved in the revision system, the above definition acts as a hard reference to the specific version of the µTest++ Testing Framework.

After cloning the project into a different location, the command xpm install can be used to install all dependencies.

This is particularly useful for CI/CD environments.

Install folder hierarchy

After following the links, the result is a structure like this:

% tree -l
.
├── LICENSE
├── package.json
└── xpacks
└── @micro-os-plus
└── micro-test-plus
├── CHANGELOG.md
├── CMakeLists.txt
├── LICENSE
├── LICENSE-Boost
├── README.md
├── include
│   └── micro-os-plus
│   ├── detail.h
│   ├── inlines.h
│   ├── literals.h
│   ├── math.h
│   ├── micro-test-plus.h
│   ├── reflection.h
│   ├── test-reporter-inlines.h
│   ├── test-reporter.h
│   ├── test-runner.h
│   ├── test-suite.h
│   └── type-traits.h
├── meson.build
├── package.json
└── src
├── micro-test-plus.cpp
├── test-reporter.cpp
├── test-runner.cpp
└── test-suite.cpp

7 directories, 24 files

Uninstall

The xpm packages do not use any form of system installer; instead they are distributed as portable archives; therefore they do not require to run any uninstaller; simply removing the links and possibly the user's global xPacks store folder and the user xPack cache folder is enough.

To remove the links created by xpm in the current project, go to the project folder:

cd my-project

and ask xpm to uninstall the package:

xpm uninstall @micro-os-plus/micro-test-plus --verbose

To completely remove the package from the user's global xPacks store:

xpm uninstall --global @micro-os-plus/micro-test-plus --verbose
Clean-ups

For a thorough clean-up, please note that xpm uses only two folders:

  • %APPDATA%\Roaming\xPacks
  • %APPDATA%\Local\Caches\xPacks

They can be removed at any time and space reclaimed; xpm will recreate them on new installs.

However, projects linking to the user's global xPacks store will fail with broken paths.

Install via npm

The package can also be installed with npm or related, but the features specific to C/C++ projects will not be available; therefore, at least for consistency reasons, it is recommended to use xpm.

Manual install

Copy files

The traditional way of using source libraries is to simply copy them into the user project.

The obvious advantage is simplicity, but the downside is that the library becomes part of the project, and any improvements or bug fixes must be manually copied to the project.

Add as a Git submodule

Another common solution is to link the entire project as a Git submodule, for example below an xpacks folder:

cd my-project
git init # Unless already a Git project
mkdir -p xpacks

git submodule add https://github.com/micro-os-plus/micro-test-plus-xpack.git \
xpacks/@micro-os-plus/micro-test-plus

Build & integration info

The project is written in C++, and the tests are expected to be written in C++ as well, although the tested code can also be written in plain C.

The source code has been compiled natively with GCC and LLVM/clang, and cross-compiled on embedded Arm and RISC-V targets, ensuring it is free from warnings.

To run on embedded platforms, the test framework requires minimal support from the system, such as writing to the output stream. Any such environment is acceptable, but for standalone tests, the most common solution is to use Arm semihosting.

To facilitate the integration of this library into user projects, pre-made CMake and meson configuration files are provided (see below).

For other build systems, please refer to the details provided below.

Include folders

The following folders should be passed to the compiler during the build:

  • include

The header files to be included in user projects are:

#include <micro-os-plus/micro-test-plus.h>

Source files

The source files to be added to user projects are:

  • src/micro-test-plus.cpp
  • src/test-reporter.cpp
  • src/test-runner.cpp
  • src/test-suite.cpp

Preprocessor definitions

There are several preprocessor definitions used to configure the build:

  • MICRO_OS_PLUS_INCLUDE_CONFIG_H - to include <micro-os-plus/config.h>
  • MICRO_OS_PLUS_TRACE - to include the trace calls
  • MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS - to enable some tracing messages

Compiler options

The following options must be passed to the compiler and linker:

  • -std=c++20 or higher for C++ sources

Dependencies

The library has the following dependencies:

  • none

CMake

To integrate the micro-test-plus library into a CMake application, add the folder where this project is located to the build:

add_subdirectory("xpacks/@micro-os-plus/micro-test-plus")

The result is an interface library that can be added as an application dependency with:

target_link_libraries(your-target PRIVATE

micro-os-plus::micro-test-plus
)

Meson Build

To integrate the micro-test-plus library into a meson application, add the folder where this project is located to the build:

subdir('xpacks/@micro-os-plus/micro-test-plus')

The result is a dependency object that can be added to an application with:

exe = executable(
your-target,
link_with: [
# Nothing, not static.
],
dependencies: [
micro_os_plus_micro_test_plus_dependency,
]
)

Status

The micro-test-plus library is fully functional, and it is used to test several projects in the µOS++ framework.

Testing

The library is CI tested on every push via GitHub Actions, on Ubuntu, macOS, and Windows.

The tests run on 32 and 64-bit bare-metal platforms (Arm Cortex-M0, Cortex-M3, Cortex-M4F, Cortex-M7F, Cortex-A15, Cortex-A72, RISC-V RV32IMAC, RV64IMAFDC), and natively, with GCC and LLVM/clang.