Cookbook ๐
The page discusses the practical side of Audition.
Code Examples ๐
Complete code examples can be found in the Audition examples repository hosted on GitHub. Descriptions and links to each example are found below.
- Minimal Example - One function, one test case (the โHello, World!โ of Audition).
- Looped Test - Repeat one test case multiple times.
- Test Fixtures - Define preconditions and postconditions for the runner, suite(s), and test(s).
- Table Driven Testing - Drive tests using an array of input data.
- Capture Standard Streams - Capture
stdout
and verify its contents are correct. - Simulate Standard Input - Simulate
stdin
for code that reads from it. - Catch Crashes - Tests that might crash can be executed in a separate address space.
- Catch Timeouts - Abort long running or hanging tests by using a test timeout.
- Death Testing - Check expected program termination and verify the exit status code.
- Signal Testing - Check if a specific POSIX signal was raised.
- File-driven Testing - Drive tests using files from the file system.
- Snapshot Testing - Like file-driven testing but generates expected output files at runtime.
- Static Function Testing - A strategy for testing static functions.
- Mocking with Fakes - Mock a function by redirecting calls to it to another function.
- Mocking with Stubs - Mock a function by having it always return a hard-coded return value.
- Mocking with Spies - Intercept calls to a function without altering its behavior.
- Selective Mocking - Mock system functions without affecting third-party libraries.
Continuous Integration ๐
Audition can be activated for a single shell session by setting the AUDITION_USER
and AUDITION_KEY
environment variables. The values for these environment variables are provided to you when you purchase Audition.
export AUDITION_USER=
export AUDITION_KEY=
You can activate Audition for use with a public continuous integration (CI) service, like GitHub Actions, by using the aforementioned environment variables and secrets. A โsecretโ is a variable that you can reference from your public CI configuration script, but whose value is hidden from public view. By defining a secret for the AUDITION_USER
and AUDITION_KEY
environment variables you can activate Audition without exposing the values publicly.
Here are some documentation links to popular continuous integration services that explain how to define secrets:
In addition to setting the environment variables, you also need to install Audition on the operating system running the continuous integration service. If you're CI runs on Ubuntu you can install Audition from the shell using the deb
package using the dpkg
command:
$ dpkg -i Audition.deb
If you're CI runs on macOS you can install Audition from the shell using hdiutil
to mount the Audition.dmg file and copying the framework:
$ hdiutil attach Audition.dmg
$ cp -R /Volumes/Audition.dmg/Audition.framework /Library/Frameworks/
If you're CI runs on Windows you can install Audition from the Microsoft Installer (MSI) via the msiexec
command:
msiexec /i Audition.msi /quiet /norestart
The Audition installer adds the installation directory where the Audition DLL can be found to the users PATH variable. Unfortunately, the PATH variable does not automatically update for your current PowerShell session therefore you must refresh it with the following command:
echo "PATH=$env:PATH;$env:LOCALAPPDATA\Programs\Audition" | Out-File -FilePath $env:GITHUB_ENV -Append
and if you're running under the command prompt instead of PowerShell then use the command:
echo "PATH=$PATH:%LOCALAPPDATA%\Programs\Audition" >> $GITHUB_ENV
If you fail to update the PATH, then the Audition DLL will not be found and your test runner will terminate abnormally. When this happens you may see a message like Exit code 0xcC000135
in your output. This is a STATUS_DLL_NOT_FOUND
exception.
GitHub Actions ๐
In this section we'll explore how to integrate Audition with GitHub Actions. Letโs assume you have a project hosted on GitHub that uses Audition for testing. In order to use Audition with GitHub Actions you must first activate it:
Start by creating two secret keys for your Audition user and key. You can create these secrets keys by first navigating to your projects Settings tab ๐ Secrets and variables sidebar link (under โSecurityโ) ๐ Actions. From here you can create two new repository secrets for the user and key. The names you give these secrets are the names you will refer to them by from your workflow YAML file. For this example, we'll name them AUDITION_USER
and AUDITION_KEY
.
Next, in your YAML workflow file, assuming you're running on Windows, you can refer to your secrets and install Audition like so:
jobs:
windows:
name: "Windows"
runs-on: windows-latest
env:
AUDITION_USER: ${{ secrets.AUDITION_USER }}
AUDITION_KEY: ${{ secrets.AUDITION_KEY }}
steps:
- name: Install Audition
run: |
msiexec /i Audition.msi /quiet /norestart
echo "PATH=$PATH:%LOCALAPPDATA%\Programs\Audition" >> $GITHUB_ENV
If you're running on Ubuntu Linux:
jobs:
ubuntu:
name: "Ubuntu"
runs-on: ubuntu-linux
env:
AUDITION_USER: ${{ secrets.AUDITION_USER }}
AUDITION_KEY: ${{ secrets.AUDITION_KEY }}
steps:
- name: Install Audition
run: sudo dpkg -i ./Audition.deb
While the names of your secrest do not matter, the environment variables do as Audition looks for these.
You can also review the workflow file in the Audition examples repository as a real world example.
Compatibility with Sanitizers ๐
If you instrument your unit tests with Clang memory sanitizers, like ASAN or MSAN, it is possible for them to report false positives from Audition. For example, with MSAN you might see the following false positive:
Uninitialized bytes in __interceptor_strlen at offset 0 inside
==393720==WARNING: MemorySanitizer: use-of-uninitialized-value
The reason for these false positives is because Clang sanitizers require all code in your program, including libraries it links against, to be built with instrumentation support. Because the precompiled Audition binaries are not built with instrumentation support this can confuse Clang leading to false positives..
You can suppress false positives by either purchasing access to the Audition source code and compiling it with Clang instrumentation or by using Clangโs -fsanitize-ignorelist
flag. To learn how to use this flag, consult the official Clang documentation.
Integration with Code Coverage Tools ๐
The audition.h
header file implements several inline functions for bridging the gap between Audition's version of libc and your local version of libc. If you attempt to gather code coverage for your project, you may fail to reach 100% coverage due to the inline functions being included in your code coverage metrics. To correct this problem, you must exclude them from your metrics.
The way to exclude functions and files from code coverage metrics depends on the code coverage tool being used. Here, we'll discuss how to remove them for users of lcov
.
Assuming you've captured code coverage data with loc
and written it to a file named coverage.info
, you can remove third-party libraries, like Audition, from the coverage report by running lcov
again with the -r
or --remove
option with a directory wildcard of the library to exclude. Here is a complete example:
# Write code coverage to a file named 'coverage.info'
lcov --capture --output-file coverage.info
# Remove third-party libraries, like Audition, that
# reside in the '/usr/' directory.
lcov --remove coverage.info '/usr/*' -o coverage.info