diff --git a/index.xhtml b/index.xhtml index a9a60ea8f..8d00379df 100644 --- a/index.xhtml +++ b/index.xhtml @@ -1012,13 +1012,103 @@ has a message along the lines of

A new modu
 systemd, then a condition like

condition = hostPlatform.isLinux;
 

should be added. If you contribute a module then you don’t need to add this entry, the merger will create an entry for you.

-

Tests

Home Manager includes a basic test suite and it is highly recommended to +

Tests

Home Manager includes a basic test suite and it is highly recommended to include at least one test when adding a module. Tests are typically in 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 -bash-lib.

Using the tests command

Home Manager provides a convenient tests command for discovering and running tests:

# List all available tests
+found in the tests project directory.

Writing Basic Tests

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

A basic test file structure looks like:

{
+  # 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

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:

{
+  myprogram-basic-configuration = ./basic-configuration.nix;
+  myprogram-empty-settings = ./empty-settings.nix;
+}
+
+

Common NMT 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.

+

Practical Examples

Here are some real-world examples of common test patterns:

Testing that a configuration file is generated:

{
+  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:

{
+  programs.alacritty.enable = false;
+
+  nmt.script = ''
+    assertPathNotExists "home-files/.config/alacritty"
+  '';
+}
+

Testing exact file content against expected output:

{
+  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:

{
+  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

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:

{ lib, pkgs, ... }:
+
+lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux {
+  rofi-valid-config = ./valid-config.nix;
+  rofi-custom-theme = ./custom-theme.nix;
+}
+

Darwin-only module tests:

{ 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

Home Manager provides a convenient tests command for discovering and running tests:

# List all available tests
 $ nix run .#tests -- -l
 
 # List tests matching a pattern