5.6 KiB
Testing, packaging, installing, and releasing Blender extensions
The goal is to test the same artifact a user installs, while keeping local Blender preferences and production scenes out of the test.
Test layers
1. Syntax and registration
Import/register the extension in Blender's Python, not system Python. Ordinary
Python usually has no compatible bpy module.
A useful smoke test should:
- start from
--factory-startup --background; - register or enable the extension;
- build its own minimal scene and data-blocks;
- invoke the public operator/API;
- assert outputs and persistent results;
- assert selection, active object, render state, and source data restoration;
- assert temporary objects/materials/meshes/images were removed;
- print one unmistakable success marker.
The current extension test is:
./blender/scripts/test.sh
When more extensions are added, give each one a focused test file and make the shared test helper run each in a fresh Blender process. Fresh processes prevent registration and global-state leakage between tests.
2. Manifest validation
Validate source metadata before packaging:
blender --factory-startup --command extension validate \
blender/material_id_baker
Then validate the actual ZIP:
VERSION=1.2.0
blender --factory-startup --command extension validate \
"dist/material_id_baker-${VERSION}.zip"
ZIP validation catches package-root and build-exclusion mistakes that source validation cannot.
3. Installed-package test
Build all packages:
./build-all.sh
Install into an isolated Blender profile on Linux/macOS:
test_profile="$(mktemp -d)"
BLENDER_USER_RESOURCES="$test_profile" ./install-all.sh
Then launch Blender with the same BLENDER_USER_RESOURCES and assert registered
operators/classes are present. Do not point install tests at the developer's real
profile unless the user explicitly wants to update it.
On Windows, set BLENDER_USER_RESOURCES to a temporary directory before running
install-all.bat from the same Command Prompt.
4. Manual UI test
Headless tests do not prove layout quality or interactive behavior. Before a release, install the ZIP and check:
- panel location, labels, spacing, disabled states, and tooltips;
- behavior with no object, wrong object type, wrong mode, missing UV/material,
linked data, shared data, and unsaved
.blendpaths as relevant; - Undo/Redo for scene changes;
- disabling and re-enabling without restarting Blender;
- saving/reopening the
.blendwhen properties or generated data persist; - output in the Image Editor, Shader Editor, Outliner, and exporter as relevant.
Build helpers in this repository
build-all.sh recursively discovers blender_manifest.toml under blender/
and writes versioned packages to dist/:
BLENDER_BIN=/path/to/blender-5.2 ./build-all.sh
install-all.sh builds, installs, and enables only the packages produced by
that invocation:
BLENDER_EXTENSION_REPO=user_default ./install-all.sh
Windows:
set "BLENDER_BIN=C:\Program Files\Blender Foundation\Blender 5.2\blender.exe"
set "BLENDER_EXTENSION_REPO=user_default"
install-all.bat
Close open Blender processes before replacing an extension. Reinstalling files does not reload a module already imported by a running process.
Versioning and release checklist
Use semantic versions in blender_manifest.toml:
- patch: compatible bug fix or internal improvement;
- minor: backward-compatible user-visible feature;
- major: breaking behavior/configuration/workflow change.
Release sequence:
- Finish source and documentation changes.
- Update/add automated tests and run them.
- Bump the manifest version.
- Validate the source directory.
- Run
./build-all.sh. - Validate the new versioned ZIP.
- Install the ZIP into an isolated profile and confirm it enables.
- Perform the relevant manual UI/export test in the target Blender version.
- Inspect ZIP contents; source/tests/repository files must not leak into it.
- Distribute the immutable ZIP. Do not replace a published ZIP without also changing its version.
Inspect package contents on Unix-like systems with:
unzip -l dist/<id>-<version>.zip
An add-on extension ZIP should normally contain blender_manifest.toml,
__init__.py, its internal modules/assets, and declared wheels—nothing from
other extensions or repository-level tests.
Headless installation scopes
For the current Blender user, the supported CLI operation is:
blender --factory-startup --command extension install-file \
-r user_default -e dist/<id>-<version>.zip
-e enables the extension and updates that user's preferences.
For a machine-wide deployment, extract packages into the read-only system repository layout:
$BLENDER_SYSTEM_EXTENSIONS/
system/
<id>/
blender_manifest.toml
__init__.py
System-repository availability is separate from per-user enablement. Managed
deployments can use a startup script under BLENDER_SYSTEM_SCRIPTS/startup/ to
enable required packages. See Blender's
production deployment guide.