mirror of
https://github.com/nix-community/home-manager.git
synced 2025-11-08 19:46: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.
|
configuration file is compared to a known correct file.
|
||||||
|
|
||||||
It is relatively easy to create tests by modeling the existing tests,
|
It is relatively easy to create tests by modeling the existing tests,
|
||||||
found in the `tests` project directory. For a full reference to the
|
found in the `tests` project directory.
|
||||||
functions available in test scripts, you can look at NMT's
|
|
||||||
|
## 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).
|
[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}
|
## Using the tests command {#sec-tests-command}
|
||||||
|
|
||||||
Home Manager provides a convenient `tests` command for discovering and running tests:
|
Home Manager provides a convenient `tests` command for discovering and running tests:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue