mirror of
https://github.com/nix-community/home-manager.git
synced 2025-11-08 11:36:05 +01:00
docs/tests: expand test documentation for contributors
Most of it was focused around running the tests instead of how to create/modify them. Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
This commit is contained in:
parent
eb243d27f8
commit
b4a07cd14b
1 changed files with 154 additions and 2 deletions
|
|
@ -6,10 +6,162 @@ the form of \"golden tests\" where, for example, a generated
|
|||
configuration file is compared to a known correct file.
|
||||
|
||||
It is relatively easy to create tests by modeling the existing tests,
|
||||
found in the `tests` project directory. For a full reference to the
|
||||
functions available in test scripts, you can look at NMT's
|
||||
found in the `tests` project directory.
|
||||
|
||||
## Writing Basic Tests {#sec-tests-basic}
|
||||
|
||||
Home Manager tests use the **NMT** framework, which provides
|
||||
a set of assertion functions to verify that modules generate the expected files
|
||||
and configurations. Tests are written as Nix expressions that define both the
|
||||
Home Manager configuration and the test assertions.
|
||||
|
||||
### Test Structure {#sec-tests-structure}
|
||||
|
||||
A basic test file structure looks like:
|
||||
|
||||
```nix
|
||||
{
|
||||
# Home Manager configuration
|
||||
programs.myprogram = {
|
||||
enable = true;
|
||||
settings = {
|
||||
option = "value";
|
||||
};
|
||||
};
|
||||
|
||||
# NMT test script with assertions
|
||||
nmt.script = ''
|
||||
assertFileExists "home-files/.config/myprogram/config.toml"
|
||||
assertFileContent "home-files/.config/myprogram/config.toml" ${./expected-config.toml}
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
### Test Organization {#sec-tests-organization}
|
||||
|
||||
Tests are organized in the `tests` directory structure:
|
||||
|
||||
- `tests/modules/programs/myprogram/default.nix` - Lists all test cases for the module
|
||||
- `tests/modules/programs/myprogram/basic-configuration.nix` - A basic test case
|
||||
- `tests/modules/programs/myprogram/expected-config.toml` - Expected output file
|
||||
|
||||
The `default.nix` file should list all test cases:
|
||||
|
||||
```nix
|
||||
{
|
||||
myprogram-basic-configuration = ./basic-configuration.nix;
|
||||
myprogram-empty-settings = ./empty-settings.nix;
|
||||
}
|
||||
```
|
||||
|
||||
### Common NMT Assertions {#sec-tests-assertions}
|
||||
|
||||
NMT provides several assertion functions:
|
||||
|
||||
- `assertFileExists "path"` - Verify a file was created
|
||||
- `assertPathNotExists "path"` - Verify a file was NOT created
|
||||
- `assertFileContent "path" expected-file` - Compare file contents
|
||||
- `assertFileRegex "path" "regex"` - Check file matches regex
|
||||
|
||||
For a full reference to the functions available in test scripts, you can look at NMT's
|
||||
[bash-lib](https://git.sr.ht/~rycee/nmt/tree/master/item/bash-lib).
|
||||
|
||||
### Practical Examples {#sec-tests-examples}
|
||||
|
||||
Here are some real-world examples of common test patterns:
|
||||
|
||||
**Testing that a configuration file is generated:**
|
||||
```nix
|
||||
{
|
||||
programs.alacritty = {
|
||||
enable = true;
|
||||
settings.font.size = 12;
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists "home-files/.config/alacritty/alacritty.yml"
|
||||
assertFileContains "home-files/.config/alacritty/alacritty.yml" "size: 12"
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
**Testing that no files are created when disabled:**
|
||||
```nix
|
||||
{
|
||||
programs.alacritty.enable = false;
|
||||
|
||||
nmt.script = ''
|
||||
assertPathNotExists "home-files/.config/alacritty"
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
**Testing exact file content against expected output:**
|
||||
```nix
|
||||
{
|
||||
programs.fastfetch = {
|
||||
enable = true;
|
||||
settings.display.color = "blue";
|
||||
};
|
||||
|
||||
nmt.script =
|
||||
let
|
||||
configFile = "home-files/.config/fastfetch/config.jsonc";
|
||||
in
|
||||
''
|
||||
assertFileExists "${configFile}"
|
||||
assertFileContent "${configFile}" ${./expected-config.jsonc}
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
**Testing multiple conditions in one test:**
|
||||
```nix
|
||||
{
|
||||
programs.myprogram = {
|
||||
enable = true;
|
||||
configFile = "custom.conf";
|
||||
extraConfig = "debug = true";
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists "home-files/.config/myprogram/custom.conf"
|
||||
assertFileRegex "home-files/.config/myprogram/custom.conf" "debug = true"
|
||||
assertFileRegex "home-files/.config/myprogram/custom.conf" "^# Generated by Home Manager"
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
### Platform-Specific Tests {#sec-tests-platform-specific}
|
||||
|
||||
When a module is platform-specific (Linux-only or Darwin-only), the test's `default.nix`
|
||||
file should use `lib.optionalAttrs` to conditionally expose tests based on the platform.
|
||||
This prevents evaluation errors on unsupported platforms during the test suite runs.
|
||||
|
||||
**Linux-only module tests:**
|
||||
```nix
|
||||
{ lib, pkgs, ... }:
|
||||
|
||||
lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux {
|
||||
rofi-valid-config = ./valid-config.nix;
|
||||
rofi-custom-theme = ./custom-theme.nix;
|
||||
}
|
||||
```
|
||||
|
||||
**Darwin-only module tests:**
|
||||
```nix
|
||||
{ lib, pkgs, ... }:
|
||||
|
||||
lib.optionalAttrs pkgs.stdenv.hostPlatform.isDarwin {
|
||||
sketchybar-basic = ./basic-configuration.nix;
|
||||
sketchybar-lua-config = ./lua-config.nix;
|
||||
}
|
||||
```
|
||||
|
||||
For cross-platform modules that have packages which need to be stubbed on Darwin,
|
||||
add the package names to `tests/darwinScrublist.nix` to prevent build failures
|
||||
during cross-platform test runs.
|
||||
|
||||
## Using the tests command {#sec-tests-command}
|
||||
|
||||
Home Manager provides a convenient `tests` command for discovering and running tests:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue