From f8a1cd8a94bf435a4b2feae8332087d629d52fd3 Mon Sep 17 00:00:00 2001 From: Edmondo Porcu Date: Sat, 28 Sep 2024 12:04:17 -0400 Subject: [PATCH 1/5] Added mention about fixtures --- docs/develop/python/testing-suite.mdx | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/develop/python/testing-suite.mdx b/docs/develop/python/testing-suite.mdx index 99023b2666..b19a2857dc 100644 --- a/docs/develop/python/testing-suite.mdx +++ b/docs/develop/python/testing-suite.mdx @@ -43,6 +43,34 @@ Some SDKs have support or examples for popular test frameworks, runners, or libr One recommended framework for testing in Python for the Temporal SDK is [pytest](https://docs.pytest.org/), which can help with fixtures to stand up and tear down test environments, provide useful test discovery, and make it easy to write parameterized tests. +### A note on pytest fixtures + +When using pytest fixtures to setup databases, application servers and common infrastructure it is not unusual to use the `session` scope to ensure the fixture is shared among multiple tests. However, with the test server it is important that each test is executed in isolation. Launching a test server per test introduce negligible overhead and ensures your test do not conflict with each other + + +```python +import pytest +import temporalio.testing.WorkflowEnvironment + + +# This might break because it will reuse the workflow environment +pytest.fixture(scope="session") +def workflow_environment(): + return WorkflowEnvironment.start_time_skipping() + +def test_1(workflow_environment): + pass + +def test_2(workflow_environment): + pass + +# Correct: if you don't specify a scope, the default scope is function, +# so a new workflow environment will be created for each test +@pytest.fixture +def workflow_environment(): + return WorkflowEnvironment.start_time_skipping() +``` + ## Testing Activities {#test-activities} An Activity can be tested with a mock Activity environment, which provides a way to mock the Activity context, listen to Heartbeats, and cancel the Activity. From 92b692edf0d006e4c5552166033663d969d4847d Mon Sep 17 00:00:00 2001 From: Edmondo Porcu Date: Mon, 2 Dec 2024 08:44:20 -0800 Subject: [PATCH 2/5] Update docs/develop/python/testing-suite.mdx Co-authored-by: Chad Retz --- docs/develop/python/testing-suite.mdx | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/docs/develop/python/testing-suite.mdx b/docs/develop/python/testing-suite.mdx index 09656da71b..186011ab2b 100644 --- a/docs/develop/python/testing-suite.mdx +++ b/docs/develop/python/testing-suite.mdx @@ -46,8 +46,10 @@ import pytest import temporalio.testing.WorkflowEnvironment -# This might break because it will reuse the workflow environment -pytest.fixture(scope="session") +# Notice how this doesn't specify a "scope" like "session" scope. If you don't +# specify a scope, the default scope is function, so a new workflow +# environment will be created for each test. +@pytest.fixture def workflow_environment(): return WorkflowEnvironment.start_time_skipping() @@ -56,12 +58,6 @@ def test_1(workflow_environment): def test_2(workflow_environment): pass - -# Correct: if you don't specify a scope, the default scope is function, -# so a new workflow environment will be created for each test -@pytest.fixture -def workflow_environment(): - return WorkflowEnvironment.start_time_skipping() ``` ## Testing Activities {#test-activities} From 089330f0b3e61f2b5df58826fdf34acea518fd53 Mon Sep 17 00:00:00 2001 From: Edmondo Porcu Date: Mon, 2 Dec 2024 08:44:31 -0800 Subject: [PATCH 3/5] Update docs/develop/python/testing-suite.mdx Co-authored-by: Chad Retz --- docs/develop/python/testing-suite.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/python/testing-suite.mdx b/docs/develop/python/testing-suite.mdx index 186011ab2b..8b8c725ab9 100644 --- a/docs/develop/python/testing-suite.mdx +++ b/docs/develop/python/testing-suite.mdx @@ -38,7 +38,7 @@ One recommended framework for testing in Python for the Temporal SDK is [pytest] ### A note on pytest fixtures -When using pytest fixtures to setup databases, application servers and common infrastructure it is not unusual to use the `session` scope to ensure the fixture is shared among multiple tests. However, with the test server it is important that each test is executed in isolation. Launching a test server per test introduce negligible overhead and ensures your test do not conflict with each other +When using pytest fixtures to setup databases, application servers and common infrastructure it is not unusual to use the `session` scope to ensure the fixture is shared among multiple tests. However, with the time-skipping test server it is important that each test is executed in isolation. Launching a test server per test introduce negligible overhead and ensures your test do not conflict with each other ```python From 0db5697254dcdd3031af6df08d10ca8b69e88c06 Mon Sep 17 00:00:00 2001 From: Edmondo Porcu Date: Tue, 3 Dec 2024 13:06:59 -0800 Subject: [PATCH 4/5] Update docs/develop/python/testing-suite.mdx Co-authored-by: Chad Retz --- docs/develop/python/testing-suite.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/python/testing-suite.mdx b/docs/develop/python/testing-suite.mdx index 8b8c725ab9..42d53f76c9 100644 --- a/docs/develop/python/testing-suite.mdx +++ b/docs/develop/python/testing-suite.mdx @@ -38,7 +38,7 @@ One recommended framework for testing in Python for the Temporal SDK is [pytest] ### A note on pytest fixtures -When using pytest fixtures to setup databases, application servers and common infrastructure it is not unusual to use the `session` scope to ensure the fixture is shared among multiple tests. However, with the time-skipping test server it is important that each test is executed in isolation. Launching a test server per test introduce negligible overhead and ensures your test do not conflict with each other +When using pytest fixtures to setup databases, application servers and common infrastructure it is not unusual to use the `session` scope to ensure the fixture is shared among multiple tests. However, with the time-skipping test server it is important that each test is executed in isolation. Launching a test server per test introduce negligible overhead and ensures your test do not conflict with each other. ```python From 45851f2827fd33381b21d7ce0ae4934840112d2e Mon Sep 17 00:00:00 2001 From: Edmondo Porcu Date: Thu, 16 Jan 2025 20:40:00 -0500 Subject: [PATCH 5/5] Implementing feedback from PR about using explicit asynchronous fixtures --- docs/develop/python/testing-suite.mdx | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/develop/python/testing-suite.mdx b/docs/develop/python/testing-suite.mdx index 42d53f76c9..dfdf4ab726 100644 --- a/docs/develop/python/testing-suite.mdx +++ b/docs/develop/python/testing-suite.mdx @@ -43,20 +43,31 @@ When using pytest fixtures to setup databases, application servers and common in ```python import pytest +import pytest_asyncio import temporalio.testing.WorkflowEnvironment # Notice how this doesn't specify a "scope" like "session" scope. If you don't # specify a scope, the default scope is function, so a new workflow # environment will be created for each test. -@pytest.fixture +@pytest_asyncio.fixture def workflow_environment(): return WorkflowEnvironment.start_time_skipping() -def test_1(workflow_environment): + +# This might break because it will reuse the workflow environment +@pytest_asyncio.fixture(scope="session") +async def workflow_environment(): + return await WorkflowEnvironment.start_time_skipping() + + +@pytest.mark.asyncio +async def test_1(workflow_environment): pass -def test_2(workflow_environment): + +@pytest.mark.asyncio +async def test_2(workflow_environment): pass ```