Home Explore Blog Models CI



nixpkgs

17th chunk of `doc/languages-frameworks/python.section.md`
e70697fbb3f42b1c5949bd000d70c5d06a8518ded7cbc7540000000100000fae
`enabledTests` and `disabledTests`

:   To specify keywords for class names or test method names.

`enabledTestMarks` and `disabledTestMarks`

:   To specify test marks.

`pytestFlags`

:   To append additional command-line arguments to `pytest`.

By default, `pytest` automatically discovers which tests to run.
If tests are explicitly enabled, only those tests will run.
A test, that is both enabled and disabled, will not run.

The following example demonstrates usage of various `pytestCheckHook` attributes:

```nix
{
  nativeCheckInputs = [ pytestCheckHook ];

  # Allow running the following test paths and test objects.
  enabledTestPaths = [
    # Find tests under the tests directory.
    # The trailing slash is not necessary.
    "tests/"

    # Additionally run test_foo
    "other-tests/test_foo.py::Foo::test_foo"
  ];

  # Override the above-enabled test paths and test objects.
  disabledTestPaths = [
    # Tests under tests/integration requires additional data.
    "tests/integration"
  ];

  # Allow tests by keywords matching their class names or method names.
  enabledTests = [
    # pytest by default only runs test methods begin with "test_" or end with "_test".
    # This includes all functions whose name contains "test".
    "test"
  ];

  # Override the above-enabled tests by keywords matching their class names or method names.
  disabledTests = [
    # Tests touching networks.
    "upload"
    "download"
  ];

  # Additional pytest flags
  pytestFlags = [
    # Disable benchmarks and run benchmarking tests only once.
    "--benchmark-disable"
  ];
}
```

These attributes are all passed into the derivation directly
and added to the `pytest` command without additional Bash expansion.
It requires `__structuredAttrs = true` to pass list elements containing spaces.

The `<enabled/disabled>TestsPaths` attributes expand Unix-style globs.
If a test path contains characters like `*`, `?`, `[`, or `]`, you can
quote them with square brackets (`[*]`, `[?]`, `[[]`, and `[]]`) to match literally.

The `<enabled/disabled>Tests` and `<enabled/disabled>TestMarks` attribute pairs
form a logical expression `((included_element1) or (included_element2)) and not (excluded_element1) and not (excluded_element2)`
which will be passed to pytest's `-k` and `-m` flags respectively.
With `__structuredAttrs = true` enabled, they additionally support sub-expressions.

For example, you could disable test items like `TestFoo::test_bar_functionality`
by disabling tests that match both `"Foo"` **and** `"bar"`:

```nix
{
  __structuredAttrs = true;

  disabledTests = [ "Foo and bar" ];
}
```

The main benefits of using `pytestCheckHook` to construct `pytest` commands
is structuralization and eval-time accessibility.
This is especially helpful to select tests or specify flags conditionally:

```nix
{
  disabledTests = [
    # touches network
    "download"
    "update"
  ]
  ++ lib.optionals (pythonAtLeast "3.8") [
    # broken due to python3.8 async changes
    "async"
  ]
  ++ lib.optionals stdenv.buildPlatform.isDarwin [
    # can fail when building with other packages
    "socket"
  ];
}
```

#### Using pythonImportsCheck {#using-pythonimportscheck}

Although unit tests are highly preferred to validate correctness of a package, not
all packages have test suites that can be run easily, and some have none at all.
To help ensure the package still works, [`pythonImportsCheck`](#using-pythonimportscheck) can attempt to import
the listed modules.

```nix
{
  pythonImportsCheck = [
    "requests"
    "urllib"
  ];
}
```

roughly translates to:

```nix
{
  postCheck = ''
    PYTHONPATH=$out/${python.sitePackages}:$PYTHONPATH
    python -c "import requests; import urllib"
  '';
}
```

However, this is done in its own phase, and not dependent on whether [`doCheck = true;`](#var-stdenv-doCheck).

This can also be useful in verifying that the package doesn't assume commonly
present packages (e.g. `setuptools`).

#### Using pythonRelaxDepsHook {#using-pythonrelaxdepshook}

Title: Advanced `pytestCheckHook` Configuration and `pythonImportsCheck` for Nix Python Packages
Summary
This chunk elaborates on `pytestCheckHook` attributes, specifically `enabled/disabledTests`, `enabled/disabledTestMarks`, and `pytestFlags`, providing a comprehensive example of their usage to selectively run or exclude tests based on paths, keywords, and marks, and to pass custom `pytest` arguments. It explains how `__structuredAttrs = true` facilitates complex logical expressions for test selection and underscores the benefits of `pytestCheckHook` for structural and conditional test configuration. Furthermore, the text introduces `pythonImportsCheck` as a mechanism to verify package functionality for packages without easily runnable test suites. This check attempts to import specified Python modules in a dedicated phase, independent of `doCheck`, and also helps confirm that packages do not implicitly rely on commonly present, but unlisted, dependencies.