blender/tests/python/CMakeLists.txt
Sean Kim 86a8d6f812 Tests: Convert texture paint test to general "Undo History" test
Previously, this test covered multiple areas, both the general "Undo
History" operator, as well as texture paint behavior when mixed with
memfile steps.

Over the last few months, the test has been somewhat inconsistent,
leading to noise / untrustworthy results. Equivalent image undo
tests are being added as part of !164048, so this commit removes the
existing `texture_paint_complex` test in favor of a test that more
specifically targets multiple undo system boundaries being crossed.

If the test still remains flakey after this PR, it can be disabled or
otherwise further tweaked.

Pull Request: https://projects.blender.org/blender/blender/pulls/164086
2026-09-30 17:43:50 +02:00

1989 lines
57 KiB
CMake

# SPDX-FileCopyrightText: 2011-2023 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later
# Use '--write-blend=/tmp/test.blend' to view output
set(TEST_SRC_DIR ${CMAKE_SOURCE_DIR}/tests/files)
set(TEST_PYTHON_DIR ${CMAKE_SOURCE_DIR}/tests/python)
set(TEST_OUT_DIR ${CMAKE_BINARY_DIR}/tests)
# ugh, any better way to do this on testing only?
file(MAKE_DIRECTORY ${TEST_OUT_DIR})
file(MAKE_DIRECTORY ${TEST_OUT_DIR}/io_tests)
file(MAKE_DIRECTORY ${TEST_OUT_DIR}/blendfile_io)
# Check which tests can be enabled.
if(IS_DIRECTORY ${TEST_SRC_DIR}/render)
set(TEST_SRC_DIR_EXISTS TRUE)
if(OPENIMAGEIO_TOOL)
set(TEST_OPENIMAGEIO_TOOL_EXISTS TRUE)
else()
set(TEST_OPENIMAGEIO_TOOL_EXISTS FALSE)
message(STATUS "Tests: Disabling render tests, missing oiiotool")
endif()
else()
set(TEST_SRC_DIR_EXISTS FALSE)
message(STATUS "Tests: Disabling most tests, no test data in ${TEST_SRC_DIR}")
endif()
if(WITH_SYSTEM_PYTHON_TESTS)
if(NOT EXISTS "${TEST_SYSTEM_PYTHON_EXE}")
message(STATUS
"Tests: Disabling 'System Python', no valid system python path, set TEST_SYSTEM_PYTHON_EXE."
)
set(WITH_SYSTEM_PYTHON_TESTS OFF)
endif()
endif()
# Run Blender command with parameters.
function(add_blender_test_impl testname envvars_list exe)
add_test(
NAME ${testname}
COMMAND ${exe} ${ARGN}
)
blender_test_set_envvars("${testname}" "${envvars_list}")
endfunction()
function(add_blender_test testname)
add_blender_test_impl(
"${testname}"
""
"${TEST_BLENDER_EXE}"
${TEST_BLENDER_EXE_PARAMS}
"${TEST_BLENDER_EXE_PARAMS_NO_THUMB}"
${ARGN}
)
endfunction()
function(add_blender_test_allow_error testname)
# Remove `--debug-exit-on-error` since errors are printed on e.g. meshes with
# invalid data or failed image loading, but sometimes we want to test those.
set(EXE_PARAMS ${TEST_BLENDER_EXE_PARAMS})
list(REMOVE_ITEM EXE_PARAMS --debug-exit-on-error)
add_blender_test_impl(
"${testname}"
""
"${TEST_BLENDER_EXE}"
${EXE_PARAMS}
"${TEST_BLENDER_EXE_PARAMS_NO_THUMB}"
${ARGN}
)
endfunction()
if(WITH_UI_TESTS)
set(_blender_headless_env_vars "BLENDER_BIN=${TEST_BLENDER_EXE}")
if(WITH_UI_TESTS_HEADLESS)
# Currently only WAYLAND is supported, support for others may be added later.
# In this case none of the WESTON environment variables will be used.
if(WITH_GHOST_WAYLAND)
set(_weston_bin_in_libdir OFF)
if(DEFINED LIBDIR)
set(_weston_bin_default "${LIBDIR}/wayland_weston/bin/weston")
else()
set(_weston_bin_default "weston")
endif()
set(WESTON_BIN "${_weston_bin_default}" CACHE STRING "\
The location of weston, leave blank for the default location."
)
mark_as_advanced(WESTON_BIN)
if((DEFINED LIBDIR) AND ("${WESTON_BIN}" STREQUAL "${_weston_bin_default}"))
set(_weston_bin_in_libdir ON)
endif()
list(APPEND _blender_headless_env_vars
"WESTON_BIN=${WESTON_BIN}"
)
if(_weston_bin_in_libdir)
list(APPEND _blender_headless_env_vars
"WAYLAND_ROOT_DIR=${LIBDIR}/wayland"
"WESTON_ROOT_DIR=${LIBDIR}/wayland_weston"
)
endif()
endif()
else()
list(APPEND _blender_headless_env_vars
"PASS_THROUGH=1"
)
endif()
function(add_blender_test_ui_backend testname backend)
# Remove `--background`
set(EXE_PARAMS ${TEST_BLENDER_EXE_PARAMS})
list(REMOVE_ITEM EXE_PARAMS --background)
add_blender_test_impl(
"${testname}"
"${_blender_headless_env_vars}"
"${TEST_PYTHON_EXE}"
"${CMAKE_SOURCE_DIR}/tests/utils/blender_headless.py"
# NOTE: attempting to maximize the window causes problems with a headless `weston`,
# while this could be investigated, use windowed mode instead.
# Use a window size that balances software GPU rendering with enough room to use the UI.
--factory-startup
# Workaround for https://projects.blender.org/blender/blender/issues/154770.
--no-native-pixels
# No need for window frame with tests.
--no-window-frame
-p 0 0 800 600
--gpu-backend ${backend}
# Log operator calls at a debug level so it is easier to debug runs on the buildbot that fail
--log "operator" --log-level "debug"
"${EXE_PARAMS}"
"${TEST_BLENDER_EXE_PARAMS_NO_THUMB}"
"${ARGN}"
)
endfunction()
function(add_blender_test_ui testname)
if(WITH_OPENGL_BACKEND)
add_blender_test_ui_backend(
"ui_opengl_${testname}"
"opengl"
"${ARGN}"
)
endif()
if(WITH_METAL_BACKEND)
add_blender_test_ui_backend(
"ui_metal_${testname}"
"metal"
"${ARGN}"
)
endif()
if(WITH_VULKAN_BACKEND AND WITH_GPU_RENDER_TESTS_VULKAN AND WITH_UI_TESTS_VULKAN)
add_blender_test_ui_backend(
"ui_vulkan_${testname}"
"vulkan"
"${ARGN}"
)
endif()
endfunction()
endif()
# Run Python script outside Blender.
function(add_python_test testname testscript)
if(NOT TEST_PYTHON_EXE)
message(FATAL_ERROR "No Python configured for running tests, set TEST_PYTHON_EXE.")
endif()
add_test(
NAME ${testname}
COMMAND ${TEST_PYTHON_EXE} ${TEST_PYTHON_EXE_EXTRA_ARGS} ${testscript} ${ARGN}
WORKING_DIRECTORY $<TARGET_FILE_DIR:blender>
)
blender_test_set_envvars("${testname}" "")
endfunction()
# Run Python render test.
function(add_render_test testname testscript)
if(TEST_OPENIMAGEIO_TOOL_EXISTS)
set(_args ${ARGN} --blender "${TEST_BLENDER_EXE}" --oiiotool "${OPENIMAGEIO_TOOL}")
if(WITH_TESTS_BATCHED)
list(APPEND _args --batch)
endif()
add_python_test(${testname} ${testscript} ${_args})
endif()
endfunction()
# Run Python script outside Blender, using system default Python3 interpreter,
# NOT the one specified in `TEST_PYTHON_EXE`.
function(add_system_python_test testname testscript)
if(NOT WITH_SYSTEM_PYTHON_TESTS)
return()
endif()
add_test(
NAME ${testname}
COMMAND ${TEST_SYSTEM_PYTHON_EXE} ${testscript} ${ARGN}
WORKING_DIRECTORY $<TARGET_FILE_DIR:blender>
)
blender_test_set_envvars("${testname}" "")
endfunction()
# ------------------------------------------------------------------------------
# TESTS USING SYSTEM PYTHON
# ------------------------------------------------------------------------------
add_system_python_test(
script_validate_on_system_python
${CMAKE_CURRENT_LIST_DIR}/system_python/load_tool_scripts.py
--root-dir ${CMAKE_SOURCE_DIR}
)
# ------------------------------------------------------------------------------
# GENERAL PYTHON CORRECTNESS TESTS
# ------------------------------------------------------------------------------
add_blender_test(
script_load_keymap
--python ${CMAKE_CURRENT_LIST_DIR}/bl_keymap_completeness.py
)
add_blender_test(
script_validate_keymap
--python ${CMAKE_CURRENT_LIST_DIR}/bl_keymap_validate.py
-- --relaxed # Disable minor things that should not cause tests to break.
)
add_blender_test(
script_load_addons
--python ${CMAKE_CURRENT_LIST_DIR}/bl_load_addons.py
)
add_blender_test(
script_load_modules
--python ${CMAKE_CURRENT_LIST_DIR}/bl_load_py_modules.py
)
add_blender_test(
script_bundled_modules
--python ${CMAKE_CURRENT_LIST_DIR}/bl_bundled_modules.py -- --inside-blender
)
add_blender_test(
script_http_downloader
--python ${CMAKE_CURRENT_LIST_DIR}/bl_http_downloader.py
)
add_blender_test(
script_disk_file_hash_service_test
--python ${CMAKE_CURRENT_LIST_DIR}/bl_disk_file_hash_service_test.py
)
# Blender is launched by the script so each test controls the command-line arguments & preferences
# `add_blender_test` hard-codes these arguments which isn't compatible with the tests,
# see `TEST_BLENDER_EXE_PARAMS`.
add_python_test(
script_blend_autoexec_cli
${CMAKE_CURRENT_LIST_DIR}/bl_blend_autoexec_cli.py
--blender "${TEST_BLENDER_EXE}"
)
# OpenColorIO config of projects found when opening blend files.
add_blender_test(
script_ocio_config
--python ${CMAKE_CURRENT_LIST_DIR}/bl_ocio_config_tests.py
)
# test running operators doesn't segfault under various conditions
if(WITH_TESTS_EXPERIMENTAL)
add_blender_test(
script_run_operators
--python ${CMAKE_CURRENT_LIST_DIR}/bl_run_operators.py
)
endif()
# ------------------------------------------------------------------------------
# PY API TESTS
# ------------------------------------------------------------------------------
add_blender_test(
script_pyapi_bpy_app
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_bpy_app.py
)
if(WITH_GPU_BACKEND_TESTS)
if(WITH_OPENGL_BACKEND)
add_blender_test(
script_pyapi_gpu_opengl
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_gpu.py
--gpu-backend opengl
)
endif()
if(WITH_METAL_BACKEND)
add_blender_test(
script_pyapi_gpu_metal
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_gpu.py
--gpu-backend metal
)
endif()
if(WITH_VULKAN_BACKEND)
add_blender_test(
script_pyapi_gpu_vulkan
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_gpu.py
--gpu-backend vulkan
)
endif()
endif()
add_blender_test(
script_pyapi_bpy_app_tempdir
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_bpy_app_tempdir.py
)
add_blender_test(
script_pyapi_bpy_path
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_bpy_path.py
)
add_blender_test(
script_pyapi_bpy_utils_units
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_bpy_utils_units.py
)
add_blender_test(
script_pyapi_mathutils
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_mathutils.py
)
add_blender_test(
script_pyapi_bpy_driver_secure_eval
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_bpy_driver_secure_eval.py
)
add_blender_test(
script_pyapi_idprop
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_idprop.py
)
add_blender_test(
script_pyapi_idprop_datablock
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_idprop_datablock.py
)
add_blender_test(
script_pyapi_prop
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_prop.py
)
add_blender_test(
script_pyapi_prop_array
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_prop_array.py
)
add_blender_test(
script_pyapi_text
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_text.py
)
add_blender_test(
script_pyapi_bmesh
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_bmesh.py
)
add_blender_test(
imbuf_py_api
--python ${CMAKE_CURRENT_LIST_DIR}/bl_imbuf_py_api.py
)
add_blender_test(
operator_function_py_api
--python ${CMAKE_CURRENT_LIST_DIR}/bl_operator_function_py_api.py
)
add_blender_test(
operator_wrap_py_api
--python ${CMAKE_CURRENT_LIST_DIR}/bl_operator_wrap_py_api.py
)
add_blender_test(
script_pyapi_grease_pencil
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_grease_pencil.py
)
add_blender_test(
script_pyapi_annotations
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_annotations.py
)
add_blender_test(
script_pyapi_blf_buffer
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_blf.py
--
--mode=BUFFER
)
# TODO: investigate if this can be supported, as the GPU can be used for rendering.
# Requires `gpu.init()`, not available for the build-bots for the default environment.
if(FALSE)
add_blender_test(
script_pyapi_blf_gpu
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_blf.py
--
--mode=GPU
)
endif()
add_blender_test(
script_pyapi_blf_vfont
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_blf.py
--
--mode=VFONT
# Use Workbench render instead of simple GPU rasterization.
# Most build-bots systems fail with `gpu.init()` otherwise this could be avoided.
# Ideally it could be removed eventually as it's slower.
--use-vfont-render
)
# Build RST documentation & PYI stubs (without building the full HTML docs).
# See the `bl_pyapi_doc_gen.py` doc-string for details.
add_blender_test(
script_pyapi_doc_gen
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_doc_gen.py --
)
# ------------------------------------------------------------------------------
# DATA MANAGEMENT TESTS
# ------------------------------------------------------------------------------
add_blender_test(
id_management
--python ${CMAKE_CURRENT_LIST_DIR}/bl_id_management.py
)
add_blender_test(
bl_rna_paths
--python ${CMAKE_CURRENT_LIST_DIR}/bl_rna_paths.py
)
add_blender_test(
bl_rna_accessors
--python ${CMAKE_CURRENT_LIST_DIR}/bl_rna_accessors.py
)
# ------------------------------------------------------------------------------
# BLEND IO & LINKING
# ------------------------------------------------------------------------------
add_blender_test(
blendfile_io
--python ${CMAKE_CURRENT_LIST_DIR}/bl_blendfile_io.py --
--output-dir ${TEST_OUT_DIR}/blendfile_io/
)
add_blender_test(
blendfile_autosave
--python ${CMAKE_CURRENT_LIST_DIR}/bl_blendfile_autosave.py --
--src-test-dir ${TEST_SRC_DIR}/io_tests/blend_autosave/
--output-dir ${TEST_OUT_DIR}/blendfile_autosave/
)
# This test can be extremely long, especially in debug builds.
# Generate BLENDFILE_VERSIONING_SPLIT_RANGE instances of the test,
# each processing their own subset of the whole set of blendfiles.
if(TEST_SRC_DIR_EXISTS)
set(BLENDFILE_VERSIONING_SPLIT_RANGE 128)
math(EXPR BLENDFILE_VERSIONING_SPLIT_RANGE_CMAKE "${BLENDFILE_VERSIONING_SPLIT_RANGE} - 1")
foreach(idx RANGE ${BLENDFILE_VERSIONING_SPLIT_RANGE_CMAKE})
add_blender_test(
"blendfile_versioning_${idx}_over_${BLENDFILE_VERSIONING_SPLIT_RANGE}"
--log "*blendfile*"
--debug-memory
--debug
--python ${CMAKE_CURRENT_LIST_DIR}/bl_blendfile_versioning.py --
--src-test-dir ${TEST_SRC_DIR}/
--output-dir ${TEST_OUT_DIR}/blendfile_io/
--slice-range ${BLENDFILE_VERSIONING_SPLIT_RANGE}
--slice-index ${idx}
)
endforeach()
add_blender_test(
blendfile_liblink
--python ${CMAKE_CURRENT_LIST_DIR}/bl_blendfile_liblink.py --
--src-test-dir ${TEST_SRC_DIR}/
--output-dir ${TEST_OUT_DIR}/blendfile_io/
)
add_blender_test(
blendfile_relationships
--python ${CMAKE_CURRENT_LIST_DIR}/bl_blendfile_relationships.py --
--src-test-dir ${TEST_SRC_DIR}/
--output-dir ${TEST_OUT_DIR}/blendfile_io/
)
add_blender_test(
blendfile_library_overrides
--python ${CMAKE_CURRENT_LIST_DIR}/bl_blendfile_library_overrides.py --
--output-dir ${TEST_OUT_DIR}/blendfile_io/
--test-dir "${TEST_SRC_DIR}/libraries_and_linking"
)
add_blender_test(
blendfile_header
--python ${CMAKE_CURRENT_LIST_DIR}/bl_blendfile_header.py --
--testdir "${TEST_SRC_DIR}/io_tests/blend_parsing"
)
endif()
# ------------------------------------------------------------------------------
# GLOBAL UNDO TESTS
# ------------------------------------------------------------------------------
add_blender_test(
global_undo
--log "*undo*"
--log-level debug
--debug-memory
--debug
--python ${CMAKE_CURRENT_LIST_DIR}/bl_global_undo.py --
--src-test-dir ${TEST_SRC_DIR}/
--output-dir ${TEST_OUT_DIR}/global_undo/
)
# ------------------------------------------------------------------------------
# MODELING TESTS
# ------------------------------------------------------------------------------
if(TEST_SRC_DIR_EXISTS)
add_blender_test(
bmesh_bevel
${TEST_SRC_DIR}/modeling/bevel_regression.blend
--python ${TEST_PYTHON_DIR}/bevel_operator.py
--
--run-all-tests
)
add_blender_test(
bmesh_boolean
${TEST_SRC_DIR}/modeling/bool_regression.blend
--python ${TEST_PYTHON_DIR}/boolean_operator.py
--
--run-all-tests
)
add_blender_test(
bmesh_split_faces
${TEST_SRC_DIR}/modeling/split_faces_test.blend
--python-text run_tests
)
add_blender_test(
curve_to_mesh
${TEST_SRC_DIR}/modeling/curve_to_mesh.blend
--python ${TEST_PYTHON_DIR}/curve_to_mesh.py
--
--run-all-tests
)
add_blender_test(
curves_extrude
${TEST_SRC_DIR}/modeling/curves_extrude.blend
--python ${TEST_PYTHON_DIR}/curves_extrude.py
--
--run-all-tests
)
add_blender_test(
mesh_join
--python ${TEST_PYTHON_DIR}/mesh_join.py
)
add_blender_test_allow_error(
mesh_validate
--python ${TEST_PYTHON_DIR}/mesh_validate.py
--
--testdir "${TEST_SRC_DIR}"
)
add_blender_test(
object_edit
--python ${TEST_PYTHON_DIR}/object_edit.py
)
add_blender_test(
object_conversion
${TEST_SRC_DIR}/modeling/object_conversion.blend
--python ${TEST_PYTHON_DIR}/object_conversion.py
--
--run-all-tests
)
add_blender_test(
object_api
--python ${TEST_PYTHON_DIR}/bl_object.py
)
add_blender_test(
node_tools
--python ${TEST_PYTHON_DIR}/bl_node_tool.py
)
endif()
add_blender_test(
geometry_attributes
--python ${CMAKE_CURRENT_LIST_DIR}/bl_geometry_attributes.py
)
add_blender_test(
geo_node_file_reporting
--python ${CMAKE_CURRENT_LIST_DIR}/bl_geo_node_file_reporting.py
--
--testdir "${TEST_SRC_DIR}"
)
# ------------------------------------------------------------------------------
# MODIFIERS TESTS
# ------------------------------------------------------------------------------
if(TEST_SRC_DIR_EXISTS)
add_blender_test(
object_modifier_array
${TEST_SRC_DIR}/modifier_stack/array_test.blend
--python-text run_tests.py
)
add_blender_test(
modifiers
${TEST_SRC_DIR}/modeling/modifiers/modifiers.blend
--python ${TEST_PYTHON_DIR}/modeling/modifiers/modifiers.py
)
add_blender_test(
modifiers_multires
${TEST_SRC_DIR}/modeling/modifiers/multires_modifier.blend
--python ${TEST_PYTHON_DIR}/modeling/modifiers/multires_modifier.py
)
add_blender_test(
modifiers_armature
${TEST_SRC_DIR}/modeling/modifiers/armature_modifier.blend
--python ${TEST_PYTHON_DIR}/modeling/modifiers/armature_modifier.py
)
add_blender_test(
physics_cloth
${TEST_SRC_DIR}/physics/cloth_test.blend
--python ${TEST_PYTHON_DIR}/physics_cloth.py
--
--run-all-tests
)
add_blender_test(
physics_softbody
${TEST_SRC_DIR}/physics/softbody_test.blend
--python ${TEST_PYTHON_DIR}/physics_softbody.py
--
--run-all-tests
)
add_blender_test(
physics_dynamic_paint
${TEST_SRC_DIR}/physics/dynamic_paint_test.blend
--python ${TEST_PYTHON_DIR}/physics_dynamic_paint.py
--
--run-all-tests
)
if(WITH_MOD_FLUID)
add_blender_test(
physics_fluid_cache
${TEST_SRC_DIR}/render/motion_blur/fluid_motion_blur.blend
--python ${TEST_PYTHON_DIR}/physics_fluid_cache.py
)
endif()
add_blender_test(
deform_modifiers
${TEST_SRC_DIR}/modeling/deform_modifiers.blend
--python ${TEST_PYTHON_DIR}/deform_modifiers.py
--
--run-all-tests
)
if(WITH_MOD_OCEANSIM)
add_blender_test(
physics_ocean
${TEST_SRC_DIR}/physics/ocean_test.blend
--python ${TEST_PYTHON_DIR}/physics_ocean.py
--
--run-all-tests
)
endif()
add_blender_test(
physics_particle_system
${TEST_SRC_DIR}/physics/physics_particle_test.blend
--python ${TEST_PYTHON_DIR}/physics_particle_system.py
--
--run-all-tests
)
add_blender_test(
physics_particle_legacy_texture_uv
${TEST_SRC_DIR}/physics/particle_legacy_texture_uv.blend
--python ${TEST_PYTHON_DIR}/physics_particle_legacy_texture_uv.py
)
add_blender_test(
physics_particle_instance
${TEST_SRC_DIR}/physics/physics_particle_instance.blend
--python ${TEST_PYTHON_DIR}/physics_particle_instance.py
--
--run-all-tests
)
add_blender_test(
constraints
--python ${CMAKE_CURRENT_LIST_DIR}/bl_constraints.py
--
--testdir "${TEST_SRC_DIR}/constraints"
)
endif()
# ------------------------------------------------------------------------------
# OPERATORS TESTS
# ------------------------------------------------------------------------------
if(TEST_SRC_DIR_EXISTS)
add_blender_test(
operators
${TEST_SRC_DIR}/modeling/operators.blend
--python ${TEST_PYTHON_DIR}/operators.py
--
--run-all-tests
)
endif()
# ------------------------------------------------------------------------------
# ANIMATION TESTS
# ------------------------------------------------------------------------------
add_blender_test(
bl_animation_armature
--python ${CMAKE_CURRENT_LIST_DIR}/bl_animation_armature.py
--
--testdir "${TEST_SRC_DIR}/animation"
)
add_blender_test(
bl_animation_bake
--python ${CMAKE_CURRENT_LIST_DIR}/bl_animation_bake.py
)
add_blender_test(
bl_animation_context_markers
--python ${TEST_PYTHON_DIR}/bl_animation_context_markers.py
)
add_blender_test(
bl_animation_copy_paste
--python ${CMAKE_CURRENT_LIST_DIR}/bl_animation_copy_paste.py
--
--testdir "${TEST_SRC_DIR}/animation"
)
add_blender_test(
bl_animation_rename
--python ${CMAKE_CURRENT_LIST_DIR}/bl_animation_rename.py
)
add_blender_test(
bl_animation_nla_strip
--python ${CMAKE_CURRENT_LIST_DIR}/bl_animation_nla_strip.py
)
add_blender_test(
bl_animation_pose_slide
--python ${CMAKE_CURRENT_LIST_DIR}/bl_animation_pose_slide.py
)
if(TEST_SRC_DIR_EXISTS)
add_blender_test(
bl_animation_drivers
--python ${CMAKE_CURRENT_LIST_DIR}/bl_animation_drivers.py
--
--testdir "${TEST_SRC_DIR}/animation"
)
add_blender_test(
bl_animation_shapekey
--python ${CMAKE_CURRENT_LIST_DIR}/bl_animation_shapekey.py
--
--testdir "${TEST_SRC_DIR}/animation"
)
add_blender_test(
bl_animation_fcurves
--python ${CMAKE_CURRENT_LIST_DIR}/bl_animation_fcurves.py
--
--testdir "${TEST_SRC_DIR}/animation"
)
add_blender_test(
bl_animation_action
--python ${CMAKE_CURRENT_LIST_DIR}/bl_animation_action.py
--
--testdir "${TEST_SRC_DIR}/animation"
--output-dir "${TEST_OUT_DIR}/bl_animation_action"
)
add_blender_test(
bl_animation_convert
--python ${CMAKE_CURRENT_LIST_DIR}/bl_animation_convert.py
--
--testdir "${TEST_SRC_DIR}/animation"
)
add_blender_test(
bl_animation_keyframing
--python ${CMAKE_CURRENT_LIST_DIR}/bl_animation_keyframing.py
--
--testdir "${TEST_SRC_DIR}/animation"
)
add_blender_test(
bl_animation_motion_path
--python ${CMAKE_CURRENT_LIST_DIR}/bl_animation_motion_path.py
--
--testdir "${TEST_SRC_DIR}/animation"
)
add_blender_test(
bl_pose_assets
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pose_assets.py
--
--testdir "${TEST_SRC_DIR}/animation"
)
add_blender_test(
bl_rigging_symmetrize
--python ${CMAKE_CURRENT_LIST_DIR}/bl_rigging_symmetrize.py
--
--testdir "${TEST_SRC_DIR}/animation"
)
add_blender_test(
vertex_group_painting
--python ${CMAKE_CURRENT_LIST_DIR}/vertex_group_painting.py
--
--testdir "${TEST_SRC_DIR}/animation"
)
endif()
# ------------------------------------------------------------------------------
# BRUSH TESTS
add_blender_test(
bl_brush
--python ${CMAKE_CURRENT_LIST_DIR}/sculpt_paint/brush_asset_test.py
)
# ------------------------------------------------------------------------------
# NODE GROUP TESTS
# ------------------------------------------------------------------------------
if(TEST_SRC_DIR_EXISTS)
add_blender_test(
bl_node_structure_type_inference
--python ${CMAKE_CURRENT_LIST_DIR}/bl_node_structure_type_inference.py
--
--testdir "${TEST_SRC_DIR}/node_group"
)
add_blender_test(
bl_node_socket_usage_inference
--python ${CMAKE_CURRENT_LIST_DIR}/bl_node_socket_usage_inference.py
--
--testdir "${TEST_SRC_DIR}/node_group"
)
add_blender_test(
bl_node_group_compat
--python ${CMAKE_CURRENT_LIST_DIR}/bl_node_group_compat.py
--
--testdir "${TEST_SRC_DIR}/node_group"
)
add_blender_test(
bl_node_group_interface
--python ${CMAKE_CURRENT_LIST_DIR}/bl_node_group_interface.py
--
--testdir "${TEST_SRC_DIR}/node_group"
)
add_blender_test(
bl_node_copy_operators
--python ${CMAKE_CURRENT_LIST_DIR}/bl_node_copy_operators.py
--
--testdir "${TEST_SRC_DIR}/node_group"
)
add_blender_test(
bl_node_link_drag
--python ${CMAKE_CURRENT_LIST_DIR}/bl_node_link_drag.py
--
--testdir "${TEST_SRC_DIR}/node_group"
)
endif()
# ------------------------------------------------------------------------------
# SVG TESTS
# ------------------------------------------------------------------------------
if(TEST_SRC_DIR_EXISTS)
set(_svg_render_tests complex path)
foreach(render_test ${_svg_render_tests})
add_render_test(
io_curve_svg_${render_test}
${CMAKE_CURRENT_LIST_DIR}/bl_io_curve_svg_test.py
--testdir "${TEST_SRC_DIR}/io_tests/svg/${render_test}"
--outdir "${TEST_OUT_DIR}/io_curve_svg"
)
endforeach()
unset(_svg_render_tests)
endif()
# ------------------------------------------------------------------------------
# RENDER TESTS
# ------------------------------------------------------------------------------
if((WITH_CYCLES OR WITH_GPU_RENDER_TESTS) AND TEST_SRC_DIR_EXISTS)
set(render_tests
attributes
camera
colorspace
bsdf
gsplat
hair
image_colorspace
image_data_types
image_mapping
image_mipmap
image_texture_limit
integrator
light
light_group
light_linking
lightprobe
mesh
node_inlining
pointcloud
principled_bsdf
raycast
shader
shadow
shadow_catcher
sss
texture
transparency
)
set(workbench_tests
workbench
camera
colorspace
hair
image_colorspace
image_data_types
image_mapping
image_texture_limit
mesh
pointcloud
texture
)
if(WITH_OPENSUBDIV)
list(APPEND render_tests displacement)
endif()
if(WITH_FREESTYLE)
list(APPEND render_tests render_layer)
list(APPEND workbench_tests render_layer)
endif()
if(WITH_MOD_FLUID)
list(APPEND render_tests motion_blur reports volume)
list(APPEND workbench_tests volume)
endif()
if(WITH_OPENVDB AND WITH_MOD_FLUID)
# Some tests in the OpenVDB folder make use of fluid simulations to generate smoke
list(APPEND render_tests openvdb)
list(APPEND workbench_tests openvdb)
# Some tests in the instancing folder make use of OpenVDB volumes
list(APPEND render_tests instancing)
list(APPEND workbench_tests instancing)
endif()
if(WITH_OPENIMAGEDENOISE)
list(APPEND render_tests denoise denoise_animation)
endif()
# Disabled until new OpenPGL version with deterministic results.
# if(WITH_CYCLES_PATH_GUIDING)
# list(APPEND render_tests guiding)
# endif()
if(WITH_GPU_RENDER_TESTS)
list(APPEND render_tests grease_pencil)
list(APPEND workbench_tests grease_pencil)
endif()
set(gpu_render_tests ${render_tests})
# Remove cycles specific tests.
list(FILTER gpu_render_tests EXCLUDE REGEX light_group|shadow_catcher|denoise|guiding|reports)
# Add EEVEE specific tests.
set(eevee_tests ${gpu_render_tests};lighting_nodes)
list(SORT render_tests)
list(SORT gpu_render_tests)
list(SORT eevee_tests)
list(SORT workbench_tests)
# Cycles
if(WITH_CYCLES)
set(_cycles_all_test_devices CPU CUDA OPTIX HIP HIP-RT METAL METAL-RT ONEAPI ONEAPI-RT)
set(_cycles_osl_test_devices CPU OPTIX)
foreach(_cycles_device ${CYCLES_TEST_DEVICES})
if(NOT ${_cycles_device} IN_LIST _cycles_all_test_devices)
message(FATAL_ERROR "Unknown Cycles test device ${_cycles_device}."
"Supported devices are: ${_cycles_all_test_devices}")
endif()
string(TOLOWER "${_cycles_device}" _cycles_device_lower)
set(_cycles_render_tests bake;bake_raytrace;${render_tests};osl;updates)
set(_cycles_osl_test_type none)
if(WITH_CYCLES_OSL)
# If the render device is CPU, or a GPU WITH_CYCLES_TEST_OSL enabled,
# then enable the limited OSL tests (Tests OSL camera with OSL shading turned off).
# This specific configuration is chosen to avoid long test times on the GPU due to
# OSL JIT compilation, unless the developer explicitly enables OSL tests.
if(("${_cycles_device_lower}" STREQUAL "cpu") OR (WITH_CYCLES_TEST_OSL AND ${_cycles_device} IN_LIST _cycles_osl_test_devices))
set(_cycles_osl_test_type limited)
endif()
endif()
foreach(render_test ${_cycles_render_tests})
set(_cycles_test_name "cycles_${render_test}_${_cycles_device_lower}")
if(NOT(WITH_CYCLES_TEST_OSL AND WITH_CYCLES_OSL AND ("${render_test}" STREQUAL "osl")))
# Only run OSL specific tests during this phase if WITH_CYCLES_TEST_OSL isn't enabled
add_render_test(
${_cycles_test_name}
${CMAKE_CURRENT_LIST_DIR}/cycles_render_tests.py
--testdir "${TEST_SRC_DIR}/render/${render_test}"
--outdir "${TEST_OUT_DIR}/cycles"
--device ${_cycles_device}
--osl "${_cycles_osl_test_type}"
)
if(NOT ("${_cycles_device_lower}" STREQUAL "cpu"))
set_tests_properties(${_cycles_test_name} PROPERTIES RUN_SERIAL TRUE)
endif()
endif()
# OSL variations of every test if WITH_CYCLES_TEST_OSL is set.
if(WITH_CYCLES_TEST_OSL AND NOT "${_cycles_osl_test_type}" STREQUAL "none")
add_render_test(
${_cycles_test_name}_osl
${CMAKE_CURRENT_LIST_DIR}/cycles_render_tests.py
--testdir "${TEST_SRC_DIR}/render/${render_test}"
--outdir "${TEST_OUT_DIR}/cycles_osl"
--device ${_cycles_device}
--osl "all"
)
if(NOT ("${_cycles_device_lower}" STREQUAL "cpu"))
set_tests_properties(${_cycles_test_name}_osl PROPERTIES RUN_SERIAL TRUE)
endif()
endif()
unset(_cycles_test_name)
endforeach()
unset(_cycles_osl_test_type)
endforeach()
unset(_cycles_osl_test_devices)
unset(_cycles_all_test_devices)
endif()
if(WITH_GPU_RENDER_TESTS)
function(add_gpu_render_tests name script render_tests)
if(WITH_OPENGL_BACKEND)
foreach(render_test ${render_tests})
add_render_test(
${name}_opengl_${render_test}
${CMAKE_CURRENT_LIST_DIR}/${script}
--testdir "${TEST_SRC_DIR}/render/${render_test}"
--outdir "${TEST_OUT_DIR}/${name}_opengl"
--gpu-backend opengl
${ARGN}
)
endforeach()
endif()
if(WITH_METAL_BACKEND)
foreach(render_test ${render_tests})
add_render_test(
${name}_metal_${render_test}
${CMAKE_CURRENT_LIST_DIR}/${script}
--testdir "${TEST_SRC_DIR}/render/${render_test}"
--outdir "${TEST_OUT_DIR}/${name}_metal"
--gpu-backend metal
${ARGN}
)
endforeach()
endif()
if(WITH_VULKAN_BACKEND
AND (NOT (name STREQUAL "storm_hydra" OR name STREQUAL "storm_usd") OR WITH_STORM_TESTS_VULKAN))
foreach(render_test ${render_tests})
add_render_test(
${name}_vulkan_${render_test}
${CMAKE_CURRENT_LIST_DIR}/${script}
--testdir "${TEST_SRC_DIR}/render/${render_test}"
--outdir "${TEST_OUT_DIR}/${name}_vulkan"
--gpu-backend vulkan
${ARGN}
)
endforeach()
endif()
endfunction()
add_gpu_render_tests(eevee "eevee_render_tests.py" "${eevee_tests}")
add_gpu_render_tests(workbench "workbench_render_tests.py" "${workbench_tests}")
if(WITH_GPU_RENDER_TESTS_HEADED)
add_gpu_render_tests(overlay "overlay_render_tests.py" "overlay")
endif()
if(WITH_HYDRA)
add_gpu_render_tests(storm_hydra "storm_render_tests.py" "${gpu_render_tests}" --export_method "HYDRA")
endif()
if(WITH_HYDRA)
add_gpu_render_tests(storm_usd "storm_render_tests.py" "${gpu_render_tests}" --export_method "USD")
endif()
endif()
endif()
if(WITH_CYCLES AND WITH_CYCLES_OSL)
add_blender_test(
cycles_osl_compile_test
--python ${CMAKE_CURRENT_LIST_DIR}/cycles_osl_compile_test.py
--
--testdir "${TEST_SRC_DIR}/render"
)
endif()
# ------------------------------------------------------------------------------
# COMPOSITOR TESTS
# ------------------------------------------------------------------------------
if(TEST_SRC_DIR_EXISTS)
set(compositor_tests
input
output
color
filter
texture
utilities
vector
group
pixel_nodes
multiple_node_setups
)
if(WITH_LIBMV)
list(APPEND compositor_tests keying mask tracking transform anisotropic_filtering)
endif()
foreach(comp_test ${compositor_tests})
add_render_test(
compositor_cpu_${comp_test}
${CMAKE_CURRENT_LIST_DIR}/compositor_render_tests.py
--testdir "${TEST_SRC_DIR}/compositor/${comp_test}"
--outdir "${TEST_OUT_DIR}/compositor_cpu"
)
endforeach()
add_blender_test(
compositor_cpu_file_output
--python ${CMAKE_CURRENT_LIST_DIR}/compositor_file_output_tests.py
--
--testdir "${TEST_SRC_DIR}/compositor/file_output/"
--outdir "${TEST_OUT_DIR}/compositor_cpu/file_output"
--device "CPU"
)
endif()
if(WITH_GPU_COMPOSITOR_TESTS AND TEST_SRC_DIR_EXISTS)
set(compositor_tests
input
output
color
filter
texture
utilities
vector
group
pixel_nodes
multiple_node_setups
)
if(WITH_LIBMV)
list(APPEND compositor_tests keying mask tracking transform)
endif()
if(WITH_OPENGL_BACKEND)
foreach(comp_test ${compositor_tests})
add_render_test(
compositor_opengl_${comp_test}
${CMAKE_CURRENT_LIST_DIR}/compositor_render_tests.py
--testdir "${TEST_SRC_DIR}/compositor/${comp_test}"
--outdir "${TEST_OUT_DIR}/compositor_opengl"
--gpu-backend opengl
)
endforeach()
add_blender_test(
compositor_opengl_file_output
--gpu-backend opengl
--python ${CMAKE_CURRENT_LIST_DIR}/compositor_file_output_tests.py
--
--testdir "${TEST_SRC_DIR}/compositor/file_output/"
--outdir "${TEST_OUT_DIR}/compositor_opengl/file_output"
--device "GPU"
)
endif()
if(WITH_METAL_BACKEND)
foreach(comp_test ${compositor_tests})
add_render_test(
compositor_metal_${comp_test}
${CMAKE_CURRENT_LIST_DIR}/compositor_render_tests.py
--testdir "${TEST_SRC_DIR}/compositor/${comp_test}"
--outdir "${TEST_OUT_DIR}/compositor_metal"
--gpu-backend metal
)
endforeach()
add_blender_test(
compositor_metal_file_output
--gpu-backend metal
--python ${CMAKE_CURRENT_LIST_DIR}/compositor_file_output_tests.py
--
--testdir "${TEST_SRC_DIR}/compositor/file_output/"
--outdir "${TEST_OUT_DIR}/compositor_metal/file_output"
--device "GPU"
)
endif()
if(WITH_VULKAN_BACKEND AND WITH_GPU_RENDER_TESTS_VULKAN)
foreach(comp_test ${compositor_tests})
add_render_test(
compositor_vulkan_${comp_test}
${CMAKE_CURRENT_LIST_DIR}/compositor_render_tests.py
--testdir "${TEST_SRC_DIR}/compositor/${comp_test}"
--outdir "${TEST_OUT_DIR}/compositor_vulkan"
--gpu-backend vulkan
)
endforeach()
add_blender_test(
compositor_vulkan_file_output
--gpu-backend vulkan
--python ${CMAKE_CURRENT_LIST_DIR}/compositor_file_output_tests.py
--
--testdir "${TEST_SRC_DIR}/compositor/file_output/"
--outdir "${TEST_OUT_DIR}/compositor_vulkan/file_output"
--device "GPU"
)
endif()
endif()
add_blender_test(
compositing_node_group
--python ${CMAKE_CURRENT_LIST_DIR}/compositing_node_group.py
)
# ------------------------------------------------------------------------------
# GEOMETRY NODE TESTS
# ------------------------------------------------------------------------------
if(TEST_SRC_DIR_EXISTS)
set(geo_node_tests
attributes
closure
curve_primitives
curves
curves/interpolate_curves
empty_object
essentials
foreach_geometry_element_zone
geometry
grease_pencil
import
instance
list
repeat_zone
mesh_primitives
mesh
mesh/bevel
mesh/extrude
mesh/split_edges
mesh/triangulate
points
simulation
texture
utilities
vector
)
if(WITH_AUDASPACE AND WITH_FFTW3)
list(APPEND geo_node_tests sound)
endif()
if(WITH_GMP)
list(APPEND geo_node_tests mesh/boolean)
endif()
if(WITH_OPENVDB)
list(APPEND geo_node_tests volume)
endif()
if(WITH_OPENSUBDIV)
list(APPEND geo_node_tests mesh/subdivision)
endif()
foreach(geo_node_test ${geo_node_tests})
file(GLOB files "${TEST_SRC_DIR}/modeling/geometry_nodes/${geo_node_test}/*.blend")
foreach(file ${files})
get_filename_component(filename ${file} NAME_WE)
add_blender_test(
geo_node_${geo_node_test}_${filename}
${file}
--python ${TEST_PYTHON_DIR}/geo_node_test.py
)
endforeach()
endforeach()
endif()
# ------------------------------------------------------------------------------
# SCREENSHOT TESTS
# ------------------------------------------------------------------------------
if(WITH_GPU_RENDER_TESTS AND TEST_SRC_DIR_EXISTS)
set(render_tests
)
if(WITH_TESTS_EXPERIMENTAL)
# The viewport tests are flaky and difficult to keep up to date for use
# in a CI environment due to constantly changing UI, but may still be helpful
# for local development.
#
# Additionally, they do not currently succeed in an ASAN build. (2025-01-29)
list(APPEND render_tests viewport)
endif()
foreach(render_test ${render_tests})
add_render_test(
screenshot_${render_test}
${CMAKE_CURRENT_LIST_DIR}/ui_screenshot_tests.py
--testdir "${TEST_SRC_DIR}/screenshot/${render_test}"
--outdir "${TEST_OUT_DIR}/screenshot"
)
endforeach()
endif()
# ------------------------------------------------------------------------------
# I/O TESTS
# ------------------------------------------------------------------------------
if(WITH_ALEMBIC AND TEST_SRC_DIR_EXISTS)
find_package_wrapper(Alembic)
if(NOT ALEMBIC_FOUND)
message(FATAL_ERROR "Alembic is enabled but cannot be found")
endif()
get_filename_component(real_include_dir ${ALEMBIC_INCLUDE_DIR} REALPATH)
get_filename_component(ALEMBIC_ROOT_DIR ${real_include_dir} DIRECTORY)
add_python_test(
io_alembic_export_tests
${CMAKE_CURRENT_LIST_DIR}/alembic_export_tests.py
--blender "${TEST_BLENDER_EXE}"
--testdir "${TEST_SRC_DIR}/alembic"
--alembic-root "${ALEMBIC_ROOT_DIR}"
)
add_blender_test(
script_alembic_io
--python ${CMAKE_CURRENT_LIST_DIR}/bl_alembic_io_test.py
--
--testdir "${TEST_SRC_DIR}/alembic"
--outdir "${TEST_OUT_DIR}/io_alembic"
)
endif()
if(WITH_USD AND TEST_SRC_DIR_EXISTS)
add_blender_test(
io_usd_export
--python ${CMAKE_CURRENT_LIST_DIR}/bl_usd_export_test.py
--
--testdir "${TEST_SRC_DIR}/usd"
)
add_blender_test(
io_usd_import
--python ${CMAKE_CURRENT_LIST_DIR}/bl_usd_import_test.py
--
--testdir "${TEST_SRC_DIR}/usd"
--outdir "${TEST_OUT_DIR}/io_usd"
)
# The collection IO tests need USD
add_blender_test(
io_collections
--python ${CMAKE_CURRENT_LIST_DIR}/io_collections_test.py
--
--testdir "${TEST_SRC_DIR}/io_tests/io_collections"
)
endif()
if(TEST_SRC_DIR_EXISTS)
add_blender_test_allow_error(
io_fbx_import
--python ${CMAKE_CURRENT_LIST_DIR}/io_fbx_import_test.py
--
--testdir "${TEST_SRC_DIR}/io_tests/fbx"
--outdir "${TEST_OUT_DIR}/io_fbx"
)
endif()
if(TEST_SRC_DIR_EXISTS)
add_blender_test_allow_error(
io_gltf_import
--python ${CMAKE_CURRENT_LIST_DIR}/io_gltf_import_test.py
--
--testdir "${TEST_SRC_DIR}/io_tests/gltf/import"
--outdir "${TEST_OUT_DIR}/io_gltf_import"
)
endif()
if(TEST_SRC_DIR_EXISTS)
add_blender_test_allow_error(
io_gltf_roundtrip
--python ${CMAKE_CURRENT_LIST_DIR}/io_gltf_roundtrip_test.py
--
--testdir "${TEST_SRC_DIR}/io_tests/gltf/roundtrip"
--outdir "${TEST_OUT_DIR}/io_gltf_roundtrip"
)
endif()
if(TEST_SRC_DIR_EXISTS)
add_blender_test_allow_error(
io_gltf_export
--python ${CMAKE_CURRENT_LIST_DIR}/io_gltf_export_test.py
--
--testdir "${TEST_SRC_DIR}/io_tests/gltf/export"
--outdir "${TEST_OUT_DIR}/io_gltf_export"
)
endif()
if(WITH_IO_WAVEFRONT_OBJ AND TEST_SRC_DIR_EXISTS)
add_blender_test_allow_error(
io_obj_import
--python ${CMAKE_CURRENT_LIST_DIR}/io_obj_import_test.py
--
--testdir "${TEST_SRC_DIR}/io_tests/obj"
--outdir "${TEST_OUT_DIR}/io_obj"
)
endif()
if(WITH_IO_PLY AND TEST_SRC_DIR_EXISTS)
add_blender_test_allow_error(
io_ply_import
--python ${CMAKE_CURRENT_LIST_DIR}/io_ply_import_test.py
--
--testdir "${TEST_SRC_DIR}/io_tests/ply"
--outdir "${TEST_OUT_DIR}/io_ply"
)
endif()
if(WITH_IO_STL AND TEST_SRC_DIR_EXISTS)
add_blender_test_allow_error(
io_stl_import
--python ${CMAKE_CURRENT_LIST_DIR}/io_stl_import_test.py
--
--testdir "${TEST_SRC_DIR}/io_tests/stl"
--outdir "${TEST_OUT_DIR}/io_stl"
)
endif()
if(WITH_CODEC_FFMPEG AND TEST_SRC_DIR_EXISTS)
add_python_test(
ffmpeg
${CMAKE_CURRENT_LIST_DIR}/ffmpeg_tests.py
--blender "${TEST_BLENDER_EXE}"
--testdir "${TEST_SRC_DIR}/ffmpeg"
)
endif()
if(TEST_SRC_DIR_EXISTS AND TEST_OPENIMAGEIO_TOOL_EXISTS)
set(OPTIONAL_FORMATS "")
if(WITH_IMAGE_CINEON)
set(OPTIONAL_FORMATS "${OPTIONAL_FORMATS} CINEON")
endif()
if(WITH_IMAGE_OPENJPEG)
set(OPTIONAL_FORMATS "${OPTIONAL_FORMATS} OPENJPEG")
endif()
if(WITH_IMAGE_WEBP)
set(OPTIONAL_FORMATS "${OPTIONAL_FORMATS} WEBP")
endif()
add_blender_test(
imbuf_save
--python ${CMAKE_CURRENT_LIST_DIR}/bl_imbuf_save.py
--
-test_dir "${TEST_SRC_DIR}/imbuf_io"
-output_dir "${TEST_OUT_DIR}/imbuf_io/save"
-oiiotool "${OPENIMAGEIO_TOOL}"
-optional_formats "${OPTIONAL_FORMATS}"
)
add_blender_test_allow_error(
imbuf_load
--python ${CMAKE_CURRENT_LIST_DIR}/bl_imbuf_load.py
--
-test_dir "${TEST_SRC_DIR}/imbuf_io"
-output_dir "${TEST_OUT_DIR}/imbuf_io/load"
-oiiotool "${OPENIMAGEIO_TOOL}"
-optional_formats "${OPTIONAL_FORMATS}"
)
endif()
# ------------------------------------------------------------------------------
# SEQUENCER RENDER TESTS
# ------------------------------------------------------------------------------
if(TEST_SRC_DIR_EXISTS)
set(render_tests
filter
transform
blend_modes_byte
blend_modes_float
colorspace
)
set(video_output_tests "")
if(WITH_LIBMV)
list(APPEND render_tests effects)
endif()
if(WITH_CODEC_FFMPEG)
list(APPEND render_tests ffmpeg)
list(APPEND video_output_tests video_output)
endif()
foreach(render_test ${render_tests})
add_render_test(
sequencer_cpu_${render_test}
${CMAKE_CURRENT_LIST_DIR}/sequencer_render_tests.py
--testdir "${TEST_SRC_DIR}/sequence_editing/${render_test}"
--outdir "${TEST_OUT_DIR}/sequencer_cpu"
)
endforeach()
foreach(video_output_test ${video_output_tests})
add_render_test(
sequencer_cpu_${video_output_test}
${CMAKE_CURRENT_LIST_DIR}/sequencer_video_output_tests.py
--testdir "${TEST_SRC_DIR}/sequence_editing/${video_output_test}"
--outdir "${TEST_OUT_DIR}/sequencer_cpu"
)
endforeach()
add_blender_test(
sequencer_input_colorspace
--python ${CMAKE_CURRENT_LIST_DIR}/sequencer_input_colorspace.py
--
--testdir "${TEST_SRC_DIR}/sequence_editing"
)
add_blender_test(
sequencer_strip_naming
--python ${CMAKE_CURRENT_LIST_DIR}/sequencer_strip_naming.py
)
add_blender_test(
sequencer_load_meta_stack
${TEST_SRC_DIR}/sequence_editing/vse_load_meta_stack.blend
--python ${TEST_PYTHON_DIR}/sequencer_load_meta_stack.py
)
if(WITH_GPU_COMPOSITOR_TESTS)
if(WITH_OPENGL_BACKEND)
foreach(render_test ${render_tests})
add_render_test(
sequencer_opengl_${render_test}
${CMAKE_CURRENT_LIST_DIR}/sequencer_render_tests.py
--testdir "${TEST_SRC_DIR}/sequence_editing/${render_test}"
--outdir "${TEST_OUT_DIR}/sequencer_opengl"
--gpu-backend opengl
)
endforeach()
endif()
if(WITH_METAL_BACKEND)
foreach(render_test ${render_tests})
add_render_test(
sequencer_metal_${render_test}
${CMAKE_CURRENT_LIST_DIR}/sequencer_render_tests.py
--testdir "${TEST_SRC_DIR}/sequence_editing/${render_test}"
--outdir "${TEST_OUT_DIR}/sequencer_metal"
--gpu-backend metal
)
endforeach()
endif()
if(WITH_VULKAN_BACKEND AND WITH_GPU_RENDER_TESTS_VULKAN)
foreach(render_test ${render_tests})
add_render_test(
sequencer_vulkan_${render_test}
${CMAKE_CURRENT_LIST_DIR}/sequencer_render_tests.py
--testdir "${TEST_SRC_DIR}/sequence_editing/${render_test}"
--outdir "${TEST_OUT_DIR}/sequencer_vulkan"
--gpu-backend vulkan
)
endforeach()
endif()
endif()
endif()
# ------------------------------------------------------------------------------
# SCULPTING & PAINTING TESTS
# ------------------------------------------------------------------------------
if(TEST_SRC_DIR_EXISTS)
add_blender_test(
bl_voxel_remesh
--python ${CMAKE_CURRENT_LIST_DIR}/sculpt_paint/voxel_remesh_test.py
)
add_blender_test(
bl_voxel_remesh_compare
${TEST_SRC_DIR}/sculpting/voxel_remesh_compare.blend
--python ${CMAKE_CURRENT_LIST_DIR}/sculpt_paint/voxel_remesh_compare_test.py
)
add_blender_test(
bl_sculpt_mask
--python ${CMAKE_CURRENT_LIST_DIR}/sculpt_paint/mask_test.py
--
--testdir "${TEST_SRC_DIR}/sculpting"
)
add_blender_test(
bl_sculpt_face_set
--python ${CMAKE_CURRENT_LIST_DIR}/sculpt_paint/face_set_test.py
--
--testdir "${TEST_SRC_DIR}/sculpting"
)
add_blender_test(
bl_multires
--python ${CMAKE_CURRENT_LIST_DIR}/sculpt_paint/multires_operators_test.py
--
--testdir "${TEST_SRC_DIR}/sculpting"
)
add_blender_test(
bl_sculpt_mesh_filter
--python ${CMAKE_CURRENT_LIST_DIR}/sculpt_paint/mesh_filter_test.py
--
--testdir "${TEST_SRC_DIR}/sculpting"
)
add_blender_test(
bl_sculpt_automasking
--python ${CMAKE_CURRENT_LIST_DIR}/sculpt_paint/automask_test.py
--
--testdir "${TEST_SRC_DIR}/sculpting"
)
add_blender_test(
bl_sculpt_brushes
--python ${CMAKE_CURRENT_LIST_DIR}/sculpt_paint/sculpt_brushes_test.py
--
--testdir "${TEST_SRC_DIR}/mesh_paint"
)
add_blender_test(
bl_vertex_paint_brushes
--python ${CMAKE_CURRENT_LIST_DIR}/sculpt_paint/vertex_paint_brushes_test.py
--
--testdir "${TEST_SRC_DIR}/mesh_paint"
)
add_blender_test(
bl_weight_paint_brushes
--python ${CMAKE_CURRENT_LIST_DIR}/sculpt_paint/weight_paint_brushes_test.py
--
--testdir "${TEST_SRC_DIR}/mesh_paint"
)
add_blender_test(
bl_texture_paint_brushes
--python ${CMAKE_CURRENT_LIST_DIR}/sculpt_paint/texture_paint_brushes_test.py
--
--testdir "${TEST_SRC_DIR}/mesh_paint"
)
add_blender_test(
bl_texture_paint_undo
--python ${CMAKE_CURRENT_LIST_DIR}/sculpt_paint/texture_paint_undo_test.py
)
add_blender_test(
bl_grease_pencil_paint_tests
--python ${CMAKE_CURRENT_LIST_DIR}/sculpt_paint/grease_pencil_paint_tests.py
--
--testdir "${TEST_SRC_DIR}/grease_pencil"
)
add_blender_test(
bl_sculpt_brush_curve_presets
--python ${CMAKE_CURRENT_LIST_DIR}/sculpt_paint/brush_strength_curves_test.py
--
--testdir "${TEST_SRC_DIR}/sculpting"
)
endif()
if(WITH_GPU_MESH_PAINT_TESTS AND TEST_SRC_DIR_EXISTS)
set(render_tests
brushes
)
foreach(render_test ${render_tests})
add_render_test(
sculpt_render_${render_test}
${CMAKE_CURRENT_LIST_DIR}/sculpt_brush_render_tests.py
--testdir "${TEST_SRC_DIR}/sculpting/${render_test}"
--outdir "${TEST_OUT_DIR}/sculpting"
)
endforeach()
endif()
# ------------------------------------------------------------------------------
# Headless GUI Tests
# ------------------------------------------------------------------------------
if(WITH_UI_TESTS)
# This could be generated with:
# `"${TEST_PYTHON_EXE}" "${CMAKE_CURRENT_LIST_DIR}/ui_simulate/run.py" --list-tests`
# list explicitly so changes bisecting/updated are sure to re-run CMake.
set(_ui_tests
test_editor_types.test_open_editor_types
test_search_in_editors.test_properties_search
test_search_in_editors.test_outliner_search
test_search_in_editors.test_dopesheet_search
test_search_in_editors.test_graph_editor_search
test_search_in_editors.test_file_browser_search
test_operator_poll.test_operator_search_poll_gating
test_operator_poll.test_operator_poll_sweep
test_sculpt.asset_shelf_brush_selection
test_sculpt.face_set_expand
test_sculpt.face_set_gestures
test_sculpt.hide_gestures
test_sculpt.mask_expand_and_invert
test_sculpt.mask_gestures
test_sculpt.trim_gestures
test_sculpt.primitive_tool_add
test_tools.sculpt_mode_toolbar
test_transform.view3d_mesh_edit_snap_to_self
test_transform.view3d_mesh_edit_snap_to_self_shape_key
test_undo.compositor_make_group
test_undo.text_editor_edit_mode_mix
test_undo.text_editor_simple
test_undo.view3d_edit_mode_multi_window
test_undo.view3d_font_edit_mode_object_mix
test_undo.view3d_font_edit_mode_simple
test_undo.view3d_mesh_edit_mode_object_mix
test_undo.view3d_mesh_edit_shape_key
test_undo.view3d_mesh_edit_separate
test_undo.view3d_mesh_particle_edit_mode_simple
test_undo.view3d_multi_mode_undo_history
test_undo.view3d_multi_mode_multi_window
test_undo.view3d_multi_mode_select
test_undo.view3d_particle_edit_undo_from_texture_paint
test_undo.view3d_sculpt_dyntopo_and_edit
test_undo.view3d_sculpt_dyntopo_simple
test_undo.view3d_sculpt_dyntopo_stroke_toggle
test_undo.view3d_sculpt_with_memfile_step
test_undo.view3d_sculpt_with_empty_memfile_step
test_undo.view3d_sculpt_trim
test_undo.view3d_simple
test_undo.view3d_texture_paint_simple
test_workspace.sanity_check_general
test_workspace.sanity_check_2d_animation
test_workspace.sanity_check_sculpting
test_workspace.sanity_check_storyboarding
test_workspace.sanity_check_vfx
test_workspace.sanity_check_video_editing
test_fullscreen.wm_toggle_fullscreen
test_fullscreen.wm_toggle_stacked_fullscreen_file_browser
test_fullscreen.wm_toggle_stacked_fullscreens
test_quick_effects.add_quick_fur
test_quick_effects.add_quick_smoke
test_quick_effects.add_quick_liquid
test_quick_effects.add_quick_explode
test_render.interactive_rendering_cycles
test_render.interactive_rendering_eevee
test_render.animation_rendering_and_player
test_bpy_types.unregister_referenced_type
test_drag_interactions.view3d_object_drag
test_drag_interactions.viewport_navigation_drags
test_drag_interactions.node_single_drag
test_drag_interactions.node_multiple_drag
test_drag_interactions.dopesheet_keyframe_drag
test_drag_interactions.graph_editor_drag
test_drag_interactions.uv_editor_drag
test_drag_interactions.image_editor_pan
test_drop_interactions.view3d_drop_world
test_drop_interactions.view3d_drop_world_session_uid
test_drop_interactions.view3d_drop_world_cancel
test_drop_interactions.ui_drop_material_slot
test_drop_interactions.scene_drop_scene_asset
test_drop_interactions.scene_drop_scene_asset_cancel
test_drop_interactions.scene_drop_scene_asset_child_window
test_drop_interactions.file_browser_drop_folder
test_sequencer.compositor_modifier_mask_with_single_input
test_menu_search_and_exec.view3d_add
test_menu_search_and_exec.modifier_add
test_menu_search_and_exec.sequencer_add
test_menu_search_and_exec.sequencer_modifier_add
test_menu_search_and_exec.shader_node_add
test_menu_search_and_exec.compositor_node_add
test_menu_search_and_exec.geometry_node_add
test_menu_search_and_exec.node_swap_search
test_menu_search_and_exec.grease_pencil_layer_search
test_pie_menus.test_object_mode_pie_edit
test_pie_menus.test_snap_pie_cursor_to_world_origin
test_pie_menus.test_pivot_pie_cursor
test_pie_menus.test_orientation_pie_cursor
test_pie_menus.test_shading_pie_solid
test_pie_menus.test_view_pie_camera
test_pie_menus.test_transform_gizmo_pie_show_gizmos
test_pie_menus.test_shading_ex_pie_toggle_overlays
test_pie_menus.test_proportional_editing_falloff_pie_sphere
test_pie_menus.test_sculpt_automasking_pie_topology
test_pie_menus.test_graph_editor_pivot_pie_cursor
test_pie_menus.test_graph_editor_view_pie_view_all
test_pie_menus.test_dopesheet_snap_pie_current_frame
test_pie_menus.test_dopesheet_view_pie_view_all
test_pie_menus.test_sequencer_pivot_pie_cursor
test_pie_menus.test_nla_snap_pie_current_frame
test_pie_menus.test_nla_view_pie_view_all
test_pie_menus.test_image_pivot_pie_cursor
test_pie_menus.test_image_view_pie_view_all
test_pie_menus.test_filebrowser_view_pie_list_horizontal
test_pie_menus.test_clip_pivot_pie_cursor
test_pie_menus.test_clip_marker_pie_affine
test_pie_menus.test_clip_solving_pie_tripod_solver
test_pie_menus.test_clip_view_pie_view_all
test_pie_menus.test_anim_keyframe_insert_pie_location
test_pie_menus.test_weight_paint_vgroup_lock_pie
test_button_input.test_string_buttons_interactions
test_tool_activation.view3d
test_tool_activation.image_editor
test_tool_activation.node_editor
test_tool_activation.sequencer
test_modifiers_constraints_draw.modifiers_constraints_draw
test_preferences_draw_all.test_preferences_draw_all
test_info_reports.test_info_report_selection_modes
test_info_reports.test_info_report_delete
test_info_reports.test_info_report_operator_poll
test_blend_autoexec.pref_enabled_drop_blend_file_untrusted
test_blend_autoexec.pref_enabled_drop_blend_file_trusted
test_blend_autoexec.pref_enabled_open_file_selector_trusted
test_blend_autoexec.pref_enabled_open_file_selector_untrusted
test_blend_autoexec.pref_disabled_open_file_selector
test_blend_autoexec.pref_disabled_drop_blend_file
test_blend_autoexec.pref_disabled_drop_blend_file_trusted_source
)
foreach(ui_test ${_ui_tests})
add_blender_test_ui(
"${ui_test}"
--enable-event-simulate
--python "${CMAKE_CURRENT_LIST_DIR}/ui_simulate/run_blender_setup.py"
--
--tests "${ui_test}"
)
endforeach()
unset(_ui_tests)
# The command line overriding the preference can't be set from within a test.
set(_ui_tests_enable_autoexec
test_blend_autoexec.pref_disabled_drop_blend_file_enable_autoexec
test_blend_autoexec.pref_enabled_drop_blend_file_untrusted_enable_autoexec
test_blend_autoexec.pref_disabled_drop_blend_file_trusted_source_enable_autoexec
test_blend_autoexec.pref_disabled_open_file_selector_enable_autoexec
test_blend_autoexec.pref_enabled_open_file_selector_untrusted_enable_autoexec
test_blend_autoexec.pref_disabled_drop_blend_file_trusted_source_next_enable_autoexec
)
foreach(ui_test ${_ui_tests_enable_autoexec})
add_blender_test_ui(
"${ui_test}"
--enable-autoexec
--enable-event-simulate
--python "${CMAKE_CURRENT_LIST_DIR}/ui_simulate/run_blender_setup.py"
--
--tests "${ui_test}"
)
endforeach()
unset(_ui_tests_enable_autoexec)
set(_ui_tests_disable_autoexec
test_blend_autoexec.pref_enabled_drop_blend_file_disable_autoexec
test_blend_autoexec.pref_enabled_drop_blend_file_trusted_source_disable_autoexec
test_blend_autoexec.pref_enabled_drop_blend_file_untrusted_trusted_source_disable_autoexec
test_blend_autoexec.pref_enabled_open_file_selector_disable_autoexec
test_blend_autoexec.pref_enabled_drop_blend_file_trusted_source_next_disable_autoexec
)
foreach(ui_test ${_ui_tests_disable_autoexec})
add_blender_test_ui(
"${ui_test}"
--disable-autoexec
--enable-event-simulate
--python "${CMAKE_CURRENT_LIST_DIR}/ui_simulate/run_blender_setup.py"
--
--tests "${ui_test}"
)
endforeach()
unset(_ui_tests_disable_autoexec)
# test_open_editor_types opens many areas, each needing its own GLContext.
# The number of available context is limit by driver and not queryable.
if(WITH_OPENGL_BACKEND)
set_tests_properties(
ui_opengl_test_editor_types.test_open_editor_types
PROPERTIES DISABLED TRUE
)
endif()
endif()
# ------------------------------------------------------------------------------
# VIEW LAYER Tests
# ------------------------------------------------------------------------------
if(TEST_SRC_DIR_EXISTS)
# TODO: disabled for now after collection unification
# add_subdirectory(view_layer)
endif()
# ------------------------------------------------------------------------------
# Remote Asset Library tests
# ------------------------------------------------------------------------------
if(TEST_SRC_DIR_EXISTS)
add_subdirectory(assets)
endif()
# ------------------------------------------------------------------------------
# Linux Release sanity checks
# ------------------------------------------------------------------------------
if(WITH_LINUX_OFFICIAL_RELEASE_TESTS)
get_filename_component(release_root_folder ${TEST_BLENDER_EXE} DIRECTORY)
set(extra_args "")
if(WITH_COMPILER_ASAN)
set(extra_args
${extra_args}
--sanitizer-build
)
endif()
add_python_test(
linux_release_sanity_checks
${CMAKE_SOURCE_DIR}/tools/check_blender_release/check_release.py
-- --directory "${release_root_folder}" ${extra_args}
)
unset(extra_args)
unset(release_root_folder)
endif()