Skip to content

Commit a98dbcd

Browse files
authored
Test free threading with pytest-run-parallel (#435)
* Test free threading with pytest-run-parallel https://py-free-threading.github.io/testing --> https://github.com/Quansight-Labs/pytest-run-parallel * @pytest.mark.iterations(1) * @pytest.mark.test_threads(1)
1 parent 3645ff0 commit a98dbcd

File tree

3 files changed

+30
-1
lines changed

3 files changed

+30
-1
lines changed

.github/workflows/python_publish.yml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ jobs:
3636
include:
3737
- os: macos-26
3838
python-version: '3.x'
39+
3940
runs-on: ${{ matrix.os }}
4041
steps:
4142
- if: runner.os == 'Linux'
@@ -63,11 +64,22 @@ jobs:
6364
- name: Install dependencies
6465
run: |
6566
pip install --upgrade pip
66-
pip install pytest
67+
pip install pytest pytest-run-parallel
6768
pip install --editable .
6869
6970
- timeout-minutes: 15 # Save resources while our pytests are hanging
7071
run: pytest --full-trace -s -vvv --strict
72+
- if: runner.os == 'Linux'
73+
timeout-minutes: 15 # Save resources while our pytests are hanging
74+
run: pytest --full-trace --iterations=8 -s --strict
75+
#- timeout-minutes: 15 # Save resources while our pytests are hanging
76+
# env:
77+
# PYTEST_RUN_PARALLEL_VERBOSE: 1
78+
# run: pytest --full-trace --parallel-threads=auto --strict tests/test_engines.py || true
79+
#- timeout-minutes: 15 # Save resources while our pytests are hanging
80+
# env:
81+
# PYTEST_RUN_PARALLEL_VERBOSE: 1
82+
# run: pytest --full-trace --parallel-threads=auto --strict tests/test_pyttsx3.py || true
7183

7284
build:
7385
runs-on: ubuntu-latest

tests/test_engines.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111

1212
@pytest.mark.parametrize("driver_name", pyttsx3.engine.engines_by_sys_platform())
13+
@pytest.mark.parallel_threads(1)
1314
def test_engine_name(driver_name) -> None:
1415
engine = pyttsx3.init(driver_name)
1516
assert engine.driver_name == driver_name
@@ -21,6 +22,7 @@ def test_engine_name(driver_name) -> None:
2122
@pytest.mark.skipif(
2223
sys.platform == "win32", reason="TODO: Make this test pass on eSpeak-NG on Windows"
2324
)
25+
@pytest.mark.parallel_threads(1)
2426
@pytest.mark.parametrize("driver_name", pyttsx3.engine.engines_by_sys_platform())
2527
def test_speaking_text(driver_name) -> None:
2628
engine = pyttsx3.init(driver_name)
@@ -32,6 +34,7 @@ def test_speaking_text(driver_name) -> None:
3234
engine.stop()
3335

3436

37+
@pytest.mark.parallel_threads(1)
3538
@pytest.mark.parametrize("driver_name", pyttsx3.engine.engines_by_sys_platform())
3639
def test_espeak_voices(driver_name) -> None:
3740
if driver_name != "espeak":
@@ -93,6 +96,7 @@ def test_espeak_voices(driver_name) -> None:
9396
engine.runAndWait()
9497

9598

99+
@pytest.mark.parallel_threads(1)
96100
@pytest.mark.parametrize("driver_name", pyttsx3.engine.engines_by_sys_platform())
97101
def test_apple_nsss_voices(driver_name) -> None:
98102
if driver_name != "nsss":

tests/test_pyttsx3.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ def engine(driver_name: str | None = None) -> pyttsx3.engine.Engine:
2323
engine.stop() # Ensure the engine stops after tests
2424

2525

26+
@pytest.mark.parallel_threads(1)
2627
def test_engine_name(engine) -> None:
2728
expected = pyttsx3.engine.default_engine_by_sys_platform()
2829
assert engine.driver_name == expected
@@ -31,6 +32,7 @@ def test_engine_name(engine) -> None:
3132

3233

3334
@pytest.mark.skipif(sys.platform == "win32", reason="TODO: Fix this test to pass on Windows")
35+
# @pytest.mark.parallel_threads(1)
3436
def test_speaking_text(engine) -> None:
3537
engine.say("Sally sells seashells by the seashore.")
3638
engine.say(quick_brown_fox)
@@ -39,6 +41,7 @@ def test_speaking_text(engine) -> None:
3941

4042

4143
@pytest.mark.skipif(sys.platform not in ("darwin", "ios"), reason="Testing only on macOS and iOS")
44+
@pytest.mark.parallel_threads(1)
4245
def test_apple_avspeech_voices(engine):
4346
import platform # noqa: PLC0415 # Only needed on macOS and iOS
4447

@@ -80,6 +83,7 @@ def test_apple_avspeech_voices(engine):
8083

8184

8285
@pytest.mark.skipif(sys.platform not in ("darwin", "ios"), reason="Testing only on macOS and iOS")
86+
@pytest.mark.parallel_threads(1)
8387
def test_apple_nsss_voices(engine):
8488
import platform # noqa: PLC0415 # Only needed on macOS and iOS
8589

@@ -117,6 +121,7 @@ def test_apple_nsss_voices(engine):
117121
engine.setProperty("voice", voice) # Reset voice to original value
118122

119123

124+
@pytest.mark.parallel_threads(1)
120125
def test_saving_to_file(engine, tmp_path: Path) -> None:
121126
"""
122127
Apple writes .aiff, not .wav. https://github.com/nateshmbhat/pyttsx3/issues/361
@@ -144,6 +149,7 @@ def test_saving_to_file(engine, tmp_path: Path) -> None:
144149

145150

146151
@pytest.mark.skipif(sys.platform == "win32", reason="TODO: Fix this test to pass on Windows")
152+
@pytest.mark.parallel_threads(1)
147153
def test_listening_for_events(engine) -> None:
148154
onStart = mock.Mock()
149155
onWord = mock.Mock()
@@ -166,6 +172,7 @@ def test_listening_for_events(engine) -> None:
166172
sys.platform in ("linux", "win32"),
167173
reason="TODO: Fix this test to pass on Linux and Windows",
168174
)
175+
@pytest.mark.parallel_threads(1)
169176
def test_interrupting_utterance(engine) -> None:
170177
def onWord(name, location, length) -> None:
171178
if location > 10:
@@ -181,6 +188,7 @@ def onWord(name, location, length) -> None:
181188

182189

183190
@pytest.mark.skipif(sys.platform == "win32", reason="TODO: Fix this test to pass on Windows")
191+
@pytest.mark.parallel_threads(1)
184192
def test_changing_speech_rate(engine) -> None:
185193
rate = engine.getProperty("rate")
186194
rate_plus_fifty = rate + 50
@@ -191,6 +199,7 @@ def test_changing_speech_rate(engine) -> None:
191199

192200

193201
@pytest.mark.skipif(sys.platform == "win32", reason="TODO: Fix this test to pass on Windows")
202+
@pytest.mark.parallel_threads(1)
194203
def test_changing_volume(engine) -> None:
195204
volume = engine.getProperty("volume")
196205
volume_minus_a_quarter = volume - 0.25
@@ -201,6 +210,7 @@ def test_changing_volume(engine) -> None:
201210

202211

203212
@pytest.mark.skipif(sys.platform == "win32", reason="TODO: Fix this test to pass on Windows")
213+
@pytest.mark.parallel_threads(1)
204214
def test_changing_voices(engine) -> None:
205215
voices = engine.getProperty("voices")
206216
for voice in voices: # TODO: This could be lots of voices! (e.g. 177 on macOS v15.x)
@@ -210,6 +220,8 @@ def test_changing_voices(engine) -> None:
210220

211221

212222
@pytest.mark.skipif(sys.platform == "win32", reason="TODO: Fix this test to pass on Windows")
223+
@pytest.mark.iterations(1)
224+
@pytest.mark.parallel_threads(1)
213225
def test_running_driver_event_loop(engine) -> None:
214226
def onStart(name) -> None:
215227
print("starting", name)
@@ -234,6 +246,7 @@ def onEnd(name, completed) -> None:
234246
sys.platform in ("linux", "win32"),
235247
reason="TODO: Fix this test to pass on Linux and Windows",
236248
)
249+
@pytest.mark.parallel_threads(1)
237250
def test_external_event_loop(engine) -> None:
238251
def externalLoop() -> None:
239252
for _ in range(5):

0 commit comments

Comments
 (0)