Skip to main content

Blender Pytest plugin.

Project description

pytest-blender

PyPI Python versions License Tests Downloads

Pytest plugin for Blender testing. Executes your pytest testsuite with Blender in headless mode using its builtin Python interpreter.

Install

pip install pytest-blender

Documentation

Usage

Install dependencies in Blender Python interpreter

Before execute it, you need to install your testing dependencies inside the builtin Blender Python interpreter. To get the interpreter location you can use the CLI utility pytest-blender, something like:

blender_python="$(pytest-blender)"
$blender_python -m ensurepip
$blender_python -m pip install -r test-requirements.txt

You can also get the intepreter for a custom Blender installation location with --blender-executable option:

pytest-blender --blender-executable ~/blender-2.91.2-linux64/blender

Execute tests

After installing dependencies, just call pytest as usually.

pytest -svv
Blender 2.82 (sub 7)
Read prefs: ~/.config/blender/2.82/config/userpref.blend
========================= test session starts ==================================
platform linux -- Python 3.8.5, pytest-6.1.2, py-1.9.0, pluggy-0.13.1 -- /usr/bin/blender
cachedir: .pytest_cache
rootdir: /home/mondeja/files/code/pytest-blender
collected 1 item

tests/test_bpy_import.py::test_inside_blender <module 'bpy' from '/usr/share/blender/scripts/modules/bpy/__init__.py'>
PASSED
=========================== 1 passed in 0.01s ==================================

You can specify a custom blender executable path using --blender-executable option:

pytest --blender-executable ~/blender-2.91.2-linux64/blender
Blender 2.91.2 (hash 5be9ef417703 built 2021-01-19 16:16:34)
Read prefs: ~/.config/blender/2.91/config/userpref.blend
found bundled python: ~/blender-2.91.2-linux64/2.91/python
============================ test session starts ===============================
platform linux -- Python 3.7.7, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
rootdir: ~/pytest-blender
collected 1 item

tests/test_bpy_import.py .                                                [100%]

============================== 1 passed in 0.00s ===============================

Arguments propagation

When you call pytest, all options like --blender-executable are passed to the pytest suite running pytest-blender. If you want to pass arguments to blender in its headless execution, add a -- between pytest and blender arguments. If you want to pass arguments to the python Blender's interpreter, you need to add another -- between arguments in a third group.

For example:

pytest -svv --blender-executable ~/blender -- --enable-event-simulate -- -b

In case that you don't want to pass arguments to blender but yes to python, use double arguments group separation (-- --):

pytest -svv -- -- -b

Load startup template

You can use the --blender-template argument to pass a custom startup file:

pytest -svv --blender-template ~/.config/blender/2.93/config/startup.blend

Enable logging

Sometimes is useful to print debugging messages from pytest_blender. You can enable logging in your conftest.py file by the next way:

import logging

pytest_blender_logger = logging.getLogger("pytest_blender")
pytest_blender_logger.setLevel(logging.DEBUG)
pytest_blender_logger.addHandler(logging.StreamHandler())

Reference

Fixtures

# blender_executablestr

Returns the path of the executable that has started the current Blender session.

# blender_versionstr

Returns the version of Blender running in the current session.

# blender_python_executablestr

Returns the path of the Python executable builtin in the Blender release of the currently running session.

# blender_python_versionstr

Returns the version of the Python executable builtin in the Blender release of the currently running session.

# blender_addons_dirstr

Returns the scripts/addons directory of Blender (see [Blender Directory Layout), the directory in which by default are located the addons installed using the install_addons_from_dir fixture.

It tries to get it using the BLENDER_USER_SCRIPTS environment variable, but if is not defined attempts to discover it from the PATH.

# install_addons_from_dir(addons_dir, addon_module_names=None, save_userpref=True, default_set=True, persistent=True, **kwargs) ⇒ list

Function that installs and enables a set of addons which are located in a directory. By "addons" Blender understands Python scripts whose file names end with .py or .zip files for packages with multiple modules.

This function is designed to be executed before the pytest session to install the addons that you want to test, using the others fixtures disable_addons or uninstall_addons to disable or remove them after the execution of the test suite:

import os

import pytest

@pytest.fixture(scope="session", autouse=True)
def register_addons(install_addons_from_dir, disable_addons):
    addon_module_names = install_addons_from_dir(os.path.abspath("src"))
    yield
    disable_addons(addon_module_names)
import os

import pytest

@pytest.fixture(scope="session", autouse=True)
def register_addons(install_addons_from_dir, uninstall_addons):
    addon_module_names = install_addons_from_dir(os.path.abspath("src"))
    yield
    uninstall_addons(addon_module_names)

The difference between disabling addons and uninstalling them is that disabling removes the files from the Blender's addons directory but disabling keep the files there, allowing you to enable it manually from the preferences.

  • addons_dir (str) Directory in which are located the files of the addons.
  • addon_module_names (list) Name of the addons modules. If not defined (default) these will be discovered searching for addons in addons_dir directory.
  • save_userpref (bool) Save user preferences after installation.
  • default_set (bool) Set the user-preference calling addon_utils.enable.
  • persistent (bool) Ensure the addon is enabled for the entire session (after loading new files).
  • **kwargs (dict) Subsecuent keyword arguments are passed to bpy.ops.preferences.addon_install.

Returns the addon module names as a list, ready to be passed to disable_addons or uninstall_addons.

# disable_addons(addon_module_names, save_userpref=True, default_set=True, **kwargs)

Function that disables a set of addons by module name. Is designed to disable your addons after a pytest suite execution (check install_addons_from_dir for an example).

  • addon_module_names (list) Name of the addons modules as is returned by install_addons_from_dir.
  • save_userpref (bool) Save user preferences after installation.
  • default_set (bool) Set the user-preference calling addon_utils.disable.
  • **kwargs (dict) Subsecuent keyword arguments are passed to addon_utils.disable.

# uninstall_addons(addon_module_names)

Function that uninstall a set of addons by module name. Is designed to remove your addons from the Blender's addons directory after a pytest suite execution (check install_addons_from_dir for an example).

CI integration

You can use blender-downloader to download multiple versions of Blender in your CI and test against them. There is an example for Github Actions in the CI configuration of this repository:

jobs:
  test:
    name: Test
    runs-on: ${{ matrix.platform }}
    strategy:
      matrix:
        platform:
          - ubuntu-latest
          - macos-latest
        blender-version:
          - '3.1.2'
          - '2.93.9'
          - '2.83.9'
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python v3.9
        uses: actions/setup-python@v3
        with:
          python-version: 3.9
      - name: Upgrade PIP
        run: python -m pip install --upgrade pip
      - name: Cache Blender ${{ matrix.blender-version }}
        uses: actions/cache@v3
        id: cache-blender
        with:
          path: |
            blender-*
            _blender-executable-path.txt
          key: ${{ runner.os }}-${{ matrix.blender-version }}
      - name: Download Blender ${{ matrix.blender-version }}
        if: steps.cache-blender.outputs.cache-hit != 'true'
        id: download-blender
        run: |
          python -m pip install --upgrade blender-downloader
          echo "$(blender-downloader \
          ${{ matrix.blender-version }} --extract --remove-compressed \
          --quiet --print-blender-executable)" > _blender-executable-path.txt
      - name: Install dependencies
        id: install-dependencies
        run: |
          python -m pip install .[test]
          blender_executable="$(< _blender-executable-path.txt tr -d '\n')"
          python_blender_executable="$(pytest-blender --blender-executable $blender_executable)"
          $python_blender_executable -m ensurepip
          $python_blender_executable -m pip install pytest
          echo "::set-output name=blender-executable::$blender_executable"
      - name: Test with pytest
        run: pytest -svv --blender-executable "${{ steps.install-dependencies.outputs.blender-executable }}" tests

Versions compatibility

  • Latest version that officially supports Python3.6 is v1.2.1.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytest_blender-2.0.0.tar.gz (14.1 kB view details)

Uploaded Source

Built Distribution

pytest_blender-2.0.0-py3-none-any.whl (12.1 kB view details)

Uploaded Python 3

File details

Details for the file pytest_blender-2.0.0.tar.gz.

File metadata

  • Download URL: pytest_blender-2.0.0.tar.gz
  • Upload date:
  • Size: 14.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.0 CPython/3.9.12

File hashes

Hashes for pytest_blender-2.0.0.tar.gz
Algorithm Hash digest
SHA256 a6e8c4aa55136cb9a61cf7f2e262dd1d87a84e70bc295063e679ba1a70bf72ca
MD5 37e619be7dcd79d277a9211f9d667c90
BLAKE2b-256 f480d0d011925a715521a3e6d7b2a29267c332b93965fab28efe851bea5f54e7

See more details on using hashes here.

File details

Details for the file pytest_blender-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: pytest_blender-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 12.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.0 CPython/3.9.12

File hashes

Hashes for pytest_blender-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 97eebb3ab6cf9515f6e9d54c6217bf5fea82956731419652786fb956550df351
MD5 ef4affc1bc5d69a569e0ff2acbad9796
BLAKE2b-256 2f3eefeda83ef33c98e648fa75a96926c9d0fffb0225d4173cca91aad8828aa4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page