Tests: Add UI test for verifying all sculpt tool properties

This commit adds a UI test that activates each of the default tools for
a mesh in Sculpt Mode and verifies that no Python errors are emitted
when the corresponding tool settings are displayed to the user.

Note that this does not test all of the default bundled brushes.

Pull Request: https://projects.blender.org/blender/blender/pulls/144397
This commit is contained in:
Sean Kim
2025-09-16 16:15:47 +02:00
committed by Sean Kim
parent 60978e0b90
commit 3995359236
2 changed files with 125 additions and 0 deletions

View File

@@ -1379,6 +1379,7 @@ if(WITH_UI_TESTS)
# list explicitly so changes bisecting/updated are sure to re-run CMake.
set(_ui_tests
test_sculpt.asset_shelf_brush_selection
test_tools.sculpt_mode_toolbar
test_undo.compositor_make_group
test_undo.text_editor_edit_mode_mix
test_undo.text_editor_simple

View File

@@ -0,0 +1,124 @@
# SPDX-FileCopyrightText: 2025 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later
"""
This file does not run anything, it's methods are accessed for tests by: ``run.py``.
"""
def _test_window(windows_exclude=None):
import bpy
wm = bpy.data.window_managers[0]
if windows_exclude is None:
return wm.windows[0]
for window in wm.windows:
if window not in windows_exclude:
return window
return None
def _test_vars(window):
import unittest
from modules.easy_keys import EventGenerate
return (
EventGenerate(window),
unittest.TestCase(),
)
def _window_area_get_by_type(window, space_type):
for area in window.screen.areas:
if area.type == space_type:
return area
def sculpt_mode_toolbar():
e, t = _test_vars(window := _test_window())
# In the default properties area, set it to the tool tab to force access of all
# tool properties when a tool is activated.
properties_area = _window_area_get_by_type(window, 'PROPERTIES')
properties_area.spaces[0].context = 'TOOL'
yield e.ctrl.tab().s() # Sculpt via pie menu.
area = _window_area_get_by_type(window, 'VIEW_3D')
position = (area.x + int(area.width * 0.05), area.y + area.height // 2)
e.cursor_position_set(*position, move=True) # Move mouse over the toolbar
yield e.shift.space()
yield e.one()
t.assertEqual(window.workspace.tools.from_space_view3d_mode('SCULPT').idname, "builtin.brush")
yield e.shift.space()
yield e.two()
t.assertEqual(window.workspace.tools.from_space_view3d_mode('SCULPT').idname, "builtin_brush.paint")
yield e.shift.space()
yield e.three()
t.assertEqual(window.workspace.tools.from_space_view3d_mode('SCULPT').idname, "builtin_brush.mask")
yield e.shift.space()
yield e.four()
t.assertEqual(window.workspace.tools.from_space_view3d_mode('SCULPT').idname, "builtin_brush.draw_face_sets")
yield e.shift.space()
yield e.b()
t.assertEqual(window.workspace.tools.from_space_view3d_mode('SCULPT').idname, "builtin.box_mask")
yield e.shift.space()
yield e.eight()
t.assertEqual(window.workspace.tools.from_space_view3d_mode('SCULPT').idname, "builtin.box_hide")
yield e.shift.space()
yield e.shift.two()
t.assertEqual(window.workspace.tools.from_space_view3d_mode('SCULPT').idname, "builtin.box_face_set")
yield e.shift.space()
yield e.shift.six()
t.assertEqual(window.workspace.tools.from_space_view3d_mode('SCULPT').idname, "builtin.box_trim")
yield e.shift.space()
yield e.shift.zero()
t.assertEqual(window.workspace.tools.from_space_view3d_mode('SCULPT').idname, "builtin.line_project")
yield e.shift.space()
yield e.ctrl.one()
t.assertEqual(window.workspace.tools.from_space_view3d_mode('SCULPT').idname, "builtin.mesh_filter")
yield e.shift.space()
yield e.ctrl.two()
t.assertEqual(window.workspace.tools.from_space_view3d_mode('SCULPT').idname, "builtin.cloth_filter")
yield e.shift.space()
yield e.ctrl.three()
t.assertEqual(window.workspace.tools.from_space_view3d_mode('SCULPT').idname, "builtin.color_filter")
yield e.shift.space()
yield e.ctrl.w()
t.assertEqual(window.workspace.tools.from_space_view3d_mode('SCULPT').idname, "builtin.face_set_edit")
yield e.shift.space()
yield e.ctrl.four()
t.assertEqual(window.workspace.tools.from_space_view3d_mode('SCULPT').idname, "builtin.mask_by_color")
yield e.shift.space()
yield e.ctrl.five()
t.assertEqual(window.workspace.tools.from_space_view3d_mode('SCULPT').idname, "builtin.move")
yield e.shift.space()
yield e.ctrl.six()
t.assertEqual(window.workspace.tools.from_space_view3d_mode('SCULPT').idname, "builtin.rotate")
yield e.shift.space()
yield e.ctrl.seven()
t.assertEqual(window.workspace.tools.from_space_view3d_mode('SCULPT').idname, "builtin.scale")
yield e.shift.space()
yield e.t()
t.assertEqual(window.workspace.tools.from_space_view3d_mode('SCULPT').idname, "builtin.transform")
yield e.shift.space()
yield e.d()
t.assertEqual(window.workspace.tools.from_space_view3d_mode('SCULPT').idname, "builtin.annotate")