Install & Compatibility
Where this runs
tested against v0.1.35 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.632s · 28.3MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 3.1s · import 0.566s · 29MB
27MB installed
● package 27MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
NutterFixture
✓ from runtime.nutterfixture import NutterFixture
The NutterFixture is the base class for creating test fixtures in Databricks notebooks. The `tag` decorator is also commonly imported from the same module.
This quickstart demonstrates how to create a Nutter test fixture within a Databricks notebook. It defines a class inheriting from `NutterFixture`, sets up `before_all` and `after_all` methods, and includes `assertion_` prefixed methods for individual test cases. The tests are executed by calling `execute_tests()` on an instance of the fixture.
# Save this as a Databricks notebook, e.g., 'test_my_notebook'
%pip install nutter
from runtime.nutterfixture import NutterFixture
import os
class MyNotebookTestFixture(NutterFixture):
def __init__(self):
super().__init__()
# Initialize any test-specific variables or parameters
self.expected_value = 42
def before_all(self):
# This method runs once before all assertion methods.
# Typically, you would run the notebook under test here.
# For simplicity, we'll simulate a result.
# Example: dbutils.notebook.run('path/to/notebook_under_test', 600, {'param1': 'value1'})
self.actual_result = self.expected_value # Simulate successful notebook execution
def assertion_check_result_matches_expected(self):
# Nutter discovers methods prefixed with 'assertion_' as test cases.
assert self.actual_result == self.expected_value, "The result should match the expected value"
def assertion_ensure_truthy_condition(self):
# Another example test case
assert True, "This condition should always be true"
def after_all(self):
# This method runs once after all assertion methods have completed.
# Use it for cleanup, if necessary.
print("All tests completed for MyNotebookTestFixture.")
# Instantiate and execute the test fixture
result = MyNotebookTestFixture().execute_tests()
print(result.to_string())
# Optional: Exit with a non-zero status in a Databricks job if tests fail
# This is crucial for CI/CD pipelines to correctly report failures.
# In a Databricks job, the environment variable 'DATABRICKS_IS_JOB' might be set,
# or you can infer it from dbutils.notebook.entry_point.getDbutils().notebook().getContext().currentRunId().isDefined()
# For local testing, this print acts as an indicator.
# In a real Databricks job, you'd use dbutils.notebook.exit() if result.is_success is False.
if os.environ.get('DATABRICKS_IS_JOB_RUN', 'False').lower() == 'true' and not result.is_success:
print("Tests failed in job context. Exiting with failure code.")
# Example for actual job exit (requires dbutils):
# dbutils.notebook.exit("Tests failed")
nutter --version
Debug
Known issues
breakingAs of v0.1.33, the `run_` prefix is no longer required for defining test cases. Instead, you define multiple `assertion_` methods, and they are executed after the `before_all` method. Code relying solely on `run_` methods for test discovery will need to adapt to the `assertion_` convention.fixRename test methods from `run_testname` to `assertion_testname`. The `run_` method is still useful if you need to explicitly call `dbutils.notebook.run` within a specific test case.
affects: >=0.1.33
gotchaNutter CLI execution (outside Databricks notebooks) requires specific environment variables to authenticate with Databricks: `DATABRICKS_HOST` (the workspace URL) and `DATABRICKS_TOKEN` (a personal access token). Failure to set these will prevent CLI execution.fixSet `DATABRICKS_HOST` and `DATABRICKS_TOKEN` environment variables in your execution environment (e.g., shell, CI/CD pipeline).
affects: All versions
gotchaTest notebooks must follow a naming convention, typically `test_<notebook_under_test>`. The Nutter CLI and Runner components rely on this pattern for automatic test discovery.fixEnsure your test notebooks are named `test_your_notebook_name.py` (or `.ipynb`). When using the CLI to run multiple tests via pattern, omit the `test_` prefix in the pattern itself.
affects: All versions
gotchaWhen Nutter tests are run in Azure DevOps pipelines, users have reported `Fatal Python error: _enter_buffered_busy: could not acquire lock for <_io.BufferedWriter name='<stdout>'>` errors during interpreter shutdown. This can obscure actual test results.fixConsider using alternative approaches for capturing and reporting test results (e.g., JUnit format) rather than relying solely on standard output. Investigation into daemon threads in the notebook's code or test environment might also be necessary.
affects: Reported with v0.1.35, potentially earlier versions.
gotchaThe default polling interval for checking notebook execution status increased from 1 second to 5 seconds in v0.1.34. This means tests might take longer to report completion, though it can be controlled.fixIf faster status updates are required for specific scenarios, you can adjust the polling interval using the `poll_wait_time` flag in the Nutter CLI.
affects: >=0.1.34
Errors
Common errors & fixes
CRITICAL:NutterCLI:400 Client Error: Bad Request for url: ... Response from server: { 'error_code': 'INVALID_STATE', 'message': 'Run result is empty. There may have been issues while saving or ' 'reading results.'}
The Nutter CLI failed to retrieve the output or results from the Databricks job run, often due to transient issues with the Databricks API or the test notebook not producing expected output/results in a timely manner or in a format Nutter expects.
fixEnsure the Databricks cluster is healthy, the test notebook completes successfully, and its output is not excessively large or malformed. Consider increasing the `--timeout` for the Nutter CLI execution or retrying the operation.
ImportError: cannot import name 'NutterFixture' from 'runtime.nutterfixture'
The `NutterFixture` class is part of the Nutter Runner, which is installed as a cluster library on Databricks and is intended for execution within Databricks notebooks. This error occurs when attempting to import `NutterFixture` in a local Python environment (e.g., VS Code or a CI/CD agent outside Databricks) where the `runtime` package is not available.
fixThe `NutterFixture` base class is meant to be imported and implemented by test fixtures *within* Databricks notebooks. For local or CI/CD execution, you use the `nutter` CLI to trigger tests on Databricks, not to run the fixture code locally. Ensure `nutter` is installed via `pip install nutter` for CLI usage.
nutter tests fail with latest pytest
There is a known incompatibility between specific versions of the Nutter CLI and newer versions of `pytest`, particularly when `pytest` is installed automatically by IDEs like VS Code, leading to test failures or unexpected behavior.
fixDowngrade `pytest` to a compatible version, typically `pytest==5.0.1`, using the command: `pip install --force-reinstall pytest==5.0.1`.
Nutter detects variables starting with 'run_' as test cases
Nutter uses a specific naming convention, where any function or variable prefixed with `run_` is automatically identified and attempted to be executed as a test case, which can lead to unexpected failures if not intended.
fixRename any variables, helper functions, or internal methods within your Databricks test notebooks that are not actual test execution steps to avoid the `run_` prefix. Only use `run_` for your explicit test execution functions.
Upgrade
Version history
0.1.35latest on PyPI · released Dec 16, 2022
Audit
Dependencies
No dependency data recorded yet.