Skip to content

Commit e1ff161

Browse files
chore: add parallel test execution
- Add pytest-xdist to dev dependencies - Make server tests use a different port - Add parallel test execution on the CI - Update contributing doc
1 parent 0b4a88f commit e1ff161

6 files changed

Lines changed: 24 additions & 23 deletions

File tree

.github/workflows/test_and_merge.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ jobs:
7070
pip install .[dev]
7171
playwright install
7272
playwright install-deps
73-
pytest -s ./tests --cov=trame_slicer --cov-report=json --cov-report=term-missing
73+
pytest -s ./tests -n auto --cov=trame_slicer --cov-report=json --cov-report=term-missing
7474
7575
- name: Upload Coverage to Codecov
7676
uses: codecov/codecov-action@v4

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ environment :
2323
1. Install playwright browsers using the `playwright install` command
2424
1. [Linux] Install playwright dependencies using the `playwright install-deps`
2525
command
26-
1. Run the tests using the pytest module `python -m pytest tests`
26+
1. Run the tests using the pytest module `python -m pytest tests -n auto`
2727

2828
Test coverage is automatically generated and available in the CI / codecov when
2929
creating pull requests.

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ dev = [
5757
"pytest-asyncio",
5858
"pytest-cov",
5959
"pytest-playwright",
60+
"pytest-xdist",
6061
"pytest-xprocess",
6162
]
6263

tests/examples/test_medical_viewer_layout.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ def test_can_be_displayed(a_server, a_server_port):
1313
VLabel("Drawer content")
1414
VSlider()
1515

16-
a_server.start(a_server_port)
16+
a_server.start(port=a_server_port)

tests/test_layout_grid.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class EmptyView:
2323
singleton_tag: str
2424

2525

26-
def test_layout_component_can_display_server_configured_templates(a_server):
26+
def test_layout_component_can_display_server_configured_templates(a_server, a_server_port):
2727
with ViewLayout(a_server, "red_view"):
2828
Div(style="background-color: red;", classes="fill-height")
2929

@@ -50,10 +50,10 @@ def test_layout_component_can_display_server_configured_templates(a_server):
5050
)
5151
)
5252

53-
a_server.start()
53+
a_server.start(port=a_server_port)
5454

5555

56-
def test_layout_component_is_compatible_with_size(a_server):
56+
def test_layout_component_is_compatible_with_size(a_server, a_server_port):
5757
with ViewLayout(a_server, "red_view"):
5858
Div(style="background-color: red;", classes="fill-height")
5959

@@ -86,7 +86,7 @@ def test_layout_component_is_compatible_with_size(a_server):
8686
)
8787
)
8888

89-
a_server.start()
89+
a_server.start(port=a_server_port)
9090

9191

9292
@pytest.fixture

tests/test_view_manager.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ def test_view_manager_with_default_factories_created_nodes_are_added_to_slicer_s
105105
a_2d_view,
106106
a_3d_view,
107107
a_server,
108+
a_server_port,
108109
):
109110
a_view_manager.register_factory(RemoteSliceViewFactory(a_server))
110111
a_view_manager.register_factory(RemoteThreeDViewFactory(a_server))
@@ -119,22 +120,18 @@ def test_view_manager_with_default_factories_created_nodes_are_added_to_slicer_s
119120
threed_nodes: vtkCollection = a_slicer_app.scene.GetNodesByClass("vtkMRMLViewNode")
120121
assert threed_nodes.GetNumberOfItems() == 1
121122
assert threed_nodes.GetItemAsObject(0) == threed_view.get_view_node()
122-
a_server.start()
123+
a_server.start(port=a_server_port)
123124

124125

125-
def test_view_manager_created_views_are_added_to_template(
126-
a_view_manager,
127-
a_3d_view,
128-
a_server,
129-
):
126+
def test_view_manager_created_views_are_added_to_template(a_view_manager, a_3d_view, a_server, a_server_port):
130127
a_view_manager.register_factory(RemoteThreeDViewFactory(a_server))
131128

132129
view = a_view_manager.create_view(a_3d_view)
133130
view.render_window().Render()
134131
with VAppLayout(a_server):
135132
client.ServerTemplate(name=a_3d_view.singleton_tag)
136133

137-
a_server.start()
134+
a_server.start(port=a_server_port)
138135

139136

140137
def test_a_2d_view_factory_creates_views_with_the_right_properties(
@@ -159,6 +156,7 @@ def test_2d_factory_views_have_sliders_and_reset_camera_connected_to_slicer(
159156
a_server,
160157
a_2d_view,
161158
a_volume_node,
159+
a_server_port,
162160
):
163161
factory = RemoteSliceViewFactory(a_server, populate_view_ui_f=create_vertical_slice_view_gutter_ui)
164162
a_view_manager.register_factory(factory)
@@ -188,21 +186,17 @@ def test_2d_factory_views_have_sliders_and_reset_camera_connected_to_slicer(
188186
view.set_slice_value(42)
189187
assert slider_state.data.value == 42.0
190188

191-
a_server.start()
189+
a_server.start(port=a_server_port)
192190

193191

194-
def test_3d_view_factory_has_reset_camera_button(
195-
a_view_manager,
196-
a_server,
197-
a_3d_view,
198-
):
192+
def test_3d_view_factory_has_reset_camera_button(a_view_manager, a_server, a_3d_view, a_server_port):
199193
factory = RemoteThreeDViewFactory(a_server, populate_view_ui_f=create_vertical_view_gutter_ui)
200194
a_view_manager.register_factory(factory)
201195
a_view_manager.create_view(a_3d_view)
202196
view = factory.get_factory_view(a_3d_view.singleton_tag)
203197
vuetify_view_str = str(view.vuetify_view)
204198
assert "VBtn" in vuetify_view_str
205-
a_server.start()
199+
a_server.start(port=a_server_port)
206200

207201

208202
@pytest.mark.parametrize(
@@ -275,7 +269,13 @@ def custom_view_layout_configuration() -> dict[str, Layout]:
275269
}
276270

277271

278-
def test_view_manager_is_compatible_with_non_slicer_views(a_view_manager, a_server, a_slicer_app, a_volume_node):
272+
def test_view_manager_is_compatible_with_non_slicer_views(
273+
a_view_manager,
274+
a_server,
275+
a_slicer_app,
276+
a_volume_node,
277+
a_server_port,
278+
):
279279
# Register view factories
280280
a_view_manager.register_factory(RemoteSliceViewFactory(a_server))
281281
a_view_manager.register_factory(RemoteThreeDViewFactory(a_server))
@@ -300,7 +300,7 @@ def test_view_manager_is_compatible_with_non_slicer_views(a_view_manager, a_serv
300300
display_manager.show_volume(a_volume_node)
301301

302302
# Start server
303-
a_server.start()
303+
a_server.start(port=a_server_port)
304304

305305

306306
def test_get_view_is_compatible_with_view_node_instance(a_view_manager, a_server, a_2d_view):

0 commit comments

Comments
 (0)