mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-18 06:21:40 +00:00
Improve debug logs when running BDD tests
I've been spoilt by tools like Behat and so this make it much nicer because it tells you exactly the feature/scenario/step where it failed.
This commit is contained in:
@@ -0,0 +1,19 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
# pytest by default doesn't print steps and where it failed. Let's fix that.
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.hookimpl
|
||||||
|
def pytest_bdd_before_scenario(request, feature, scenario):
|
||||||
|
print(f"\033[94m# {feature.name}\033[0m")
|
||||||
|
print(f"\033[94m## {scenario.name}\033[0m")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.hookimpl(tryfirst=True)
|
||||||
|
def pytest_bdd_after_step(request, feature, scenario, step, step_func, step_func_args):
|
||||||
|
print(f"\033[92m>>> {step.name}\033[0m")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.hookimpl(tryfirst=True)
|
||||||
|
def pytest_bdd_step_error(request, feature, scenario, step, step_func, step_func_args):
|
||||||
|
print(f"\033[1;91m>>> {step.name} <-- FAILED\033[0m")
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import bpy
|
import bpy
|
||||||
|
import pytest
|
||||||
import traceback
|
import traceback
|
||||||
import webbrowser
|
import webbrowser
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@@ -542,6 +543,7 @@ def i_press_operator(operator):
|
|||||||
|
|
||||||
@given(parsers.parse('I click "{button}"'))
|
@given(parsers.parse('I click "{button}"'))
|
||||||
@when(parsers.parse('I click "{button}"'))
|
@when(parsers.parse('I click "{button}"'))
|
||||||
|
@then(parsers.parse('I click "{button}"'))
|
||||||
def i_click_button(button):
|
def i_click_button(button):
|
||||||
panel_spy.refresh_spy()
|
panel_spy.refresh_spy()
|
||||||
for spied_operator in panel_spy.spied_operators:
|
for spied_operator in panel_spy.spied_operators:
|
||||||
@@ -559,6 +561,8 @@ def i_click_button(button):
|
|||||||
# Clicked confirm on an operator's draw dialog
|
# Clicked confirm on an operator's draw dialog
|
||||||
return i_press_operator(panel_spy.panel.bl_idname)
|
return i_press_operator(panel_spy.panel.bl_idname)
|
||||||
debug = "\n".join([f"{i} {v}" for i, v in enumerate(panel_spy.spied_operators)])
|
debug = "\n".join([f"{i} {v}" for i, v in enumerate(panel_spy.spied_operators)])
|
||||||
|
if not debug:
|
||||||
|
debug = f"No buttons were found, here is the text we see: {panel_spy.spied_labels}"
|
||||||
assert False, f"Could not find {button}:\n{debug}"
|
assert False, f"Could not find {button}:\n{debug}"
|
||||||
|
|
||||||
|
|
||||||
@@ -603,6 +607,7 @@ def i_refresh_the_selected_objects():
|
|||||||
bonsai.bim.handler.active_object_callback()
|
bonsai.bim.handler.active_object_callback()
|
||||||
|
|
||||||
|
|
||||||
|
@given("I deselect all objects")
|
||||||
@when("I deselect all objects")
|
@when("I deselect all objects")
|
||||||
def i_deselect_all_objects():
|
def i_deselect_all_objects():
|
||||||
bpy.context.view_layer.objects.active = None
|
bpy.context.view_layer.objects.active = None
|
||||||
@@ -668,7 +673,9 @@ def then_the_object_name_is_placed_in_the_collection_collection(name: str, colle
|
|||||||
def additionally_the_object_name_is_selected(name):
|
def additionally_the_object_name_is_selected(name):
|
||||||
obj = bpy.context.scene.objects.get(name)
|
obj = bpy.context.scene.objects.get(name)
|
||||||
if not obj:
|
if not obj:
|
||||||
assert False, f'The object "{name}" could not be selected'
|
total = len(bpy.context.scene.objects)
|
||||||
|
debug = "\n".join([o.name for o in bpy.context.scene.objects])
|
||||||
|
assert False, f'The object "{name}" could not be selected. Available objects ({total} total):\n{debug}'
|
||||||
bpy.context.view_layer.objects.active = obj
|
bpy.context.view_layer.objects.active = obj
|
||||||
obj.select_set(True)
|
obj.select_set(True)
|
||||||
|
|
||||||
@@ -729,6 +736,8 @@ def nothing_happens():
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@given(parsers.parse('the object "{name}" exists'))
|
||||||
|
@when(parsers.parse('the object "{name}" exists'))
|
||||||
@then(parsers.parse('the object "{name}" exists'))
|
@then(parsers.parse('the object "{name}" exists'))
|
||||||
def the_object_name_exists(name: str) -> bpy.types.Object:
|
def the_object_name_exists(name: str) -> bpy.types.Object:
|
||||||
# Some objects from linked collections may share the same name. This disambiguates them.
|
# Some objects from linked collections may share the same name. This disambiguates them.
|
||||||
@@ -1335,10 +1344,14 @@ def construction_type(relating_type_name):
|
|||||||
@when("I toggle edit mode")
|
@when("I toggle edit mode")
|
||||||
@then("I toggle edit mode")
|
@then("I toggle edit mode")
|
||||||
def i_toggle_edit_mode():
|
def i_toggle_edit_mode():
|
||||||
|
props = tool.Geometry.get_geometry_props()
|
||||||
|
print(f"Toggling from {bpy.context.mode} / {props.mode} ...")
|
||||||
|
print("Selected items:", bpy.context.active_object, bpy.context.selected_objects)
|
||||||
if bpy.context.mode == "OBJECT":
|
if bpy.context.mode == "OBJECT":
|
||||||
bpy.ops.bim.override_mode_set_edit()
|
bpy.ops.bim.override_mode_set_edit()
|
||||||
else:
|
else:
|
||||||
bpy.ops.bim.override_mode_set_object()
|
bpy.ops.bim.override_mode_set_object()
|
||||||
|
print(f"... mode is now {bpy.context.mode} / {props.mode}")
|
||||||
|
|
||||||
|
|
||||||
@when("I move the cursor to the bottom left corner")
|
@when("I move the cursor to the bottom left corner")
|
||||||
@@ -1357,8 +1370,10 @@ def prepare_undo():
|
|||||||
@when(parsers.parse("I undo"))
|
@when(parsers.parse("I undo"))
|
||||||
@then(parsers.parse("I undo"))
|
@then(parsers.parse("I undo"))
|
||||||
def hit_undo():
|
def hit_undo():
|
||||||
bpy.ops.ed.undo_push(message="UNDO STEP")
|
# bpy.ops.ed.undo_push(message="UNDO STEP")
|
||||||
bpy.ops.ed.undo()
|
override = tool.Blender.get_viewport_context()
|
||||||
|
with bpy.context.temp_override(**override):
|
||||||
|
bpy.ops.ed.undo()
|
||||||
|
|
||||||
|
|
||||||
@then(parsers.parse('the object "{obj_name1}" has a connection with "{obj_name2}"'))
|
@then(parsers.parse('the object "{obj_name1}" has a connection with "{obj_name2}"'))
|
||||||
|
|||||||
Reference in New Issue
Block a user