Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Komponententests sind ein wichtiger Bestandteil moderner Softwareentwicklungsmethoden. Komponententests überprüfen das Geschäftslogikverhalten und schützen sich vor der Einführung unbemerkter unmerkter Änderungen in der Zukunft. Dauerhafte Funktionen können leicht komplexer werden, sodass die Einführung von Komponententests dazu beiträgt, unterbrechungsfähige Änderungen zu vermeiden. In den folgenden Abschnitten wird erläutert, wie die drei Funktionstypen "Orchestration", "Orchestrator" und "Entitätsfunktionen" getestet werden.
Hinweis
Dieses Handbuch gilt nur für Apps mit dauerhaften Funktionen, die im Python v2-Programmiermodell geschrieben wurden.
Voraussetzungen
Die Beispiele in diesem Artikel erfordern Kenntnisse der folgenden Konzepte und Frameworks:
- Komponententests
- Dauerhafte Funktionen
- Python unittest
- unittest.mock
Einrichten der Testumgebung
Um dauerhafte Funktionen zu testen, ist es wichtig, eine richtige Testumgebung einzurichten. Dazu gehört das Erstellen eines Testverzeichnisses und das Installieren des Python-Moduls unittest
in Ihrer Python-Umgebung. Weitere Informationen finden Sie in der Übersicht über die Azure Functions Python-Komponententests.
Komponententesttriggerfunktionen
Triggerfunktionen, die häufig als Clientfunktionen bezeichnet werden, initiieren Orchestrierungen und externe Ereignisse. So testen Sie diese Funktionen:
- Simulieren Sie die
DurableOrchestrationClient
Orchestrierungsausführung und statusverwaltung. - Weisen Sie
DurableOrchestrationClient
Methoden wiestart_new
, oderget_status
raise_event
mit simulierten Funktionen zu, die erwartete Werte zurückgeben. - Rufen Sie die Clientfunktion direkt mit einem simulierten Client und anderen erforderlichen Eingaben wie einem
req
(HTTP-Anforderungsobjekt) für HTTP-Triggerclientfunktionen auf. - Verwenden Sie Assertionen und
unittest.mock
Tools, um das erwartete Startverhalten, Parameter und HTTP-Antworten zu überprüfen.
import asyncio
import unittest
import azure.functions as func
from unittest.mock import AsyncMock, Mock, patch
from function_app import start_orchestrator
class TestFunction(unittest.TestCase):
@patch('azure.durable_functions.DurableOrchestrationClient')
def test_HttpStart(self, client):
# Get the original method definition as seen in the function_app.py file
func_call = http_start.build().get_user_function().client_function
req = func.HttpRequest(method='GET',
body=b'{}',
url='/api/my_second_function',
route_params={"functionName": "my_orchestrator"})
client.start_new = AsyncMock(return_value="instance_id")
client.create_check_status_response = Mock(return_value="check_status_response")
# Execute the function code
result = asyncio.run(func_call(req, client))
client.start_new.assert_called_once_with("my_orchestrator")
client.create_check_status_response.assert_called_once_with(req, "instance_id")
self.assertEqual(result, "check_status_response")
Komponententest-Orchestratorfunktionen
Orchestrator-Funktionen verwalten die Ausführung mehrerer Aktivitätsfunktionen. So testen Sie einen Orchestrator:
- Mock the
DurableOrchestrationContext
to control function execution. - Ersetzen Sie
DurableOrchestrationContext
Methoden, die für die Orchestratorausführung wiecall_activity
odercreate_timer
durch simulierte Funktionen erforderlich sind. Diese Funktionen geben in der Regel Objekte vom Typ TaskBase mit einerresult
Eigenschaft zurück. - Rufen Sie den Orchestrator rekursiv auf, und übergeben Sie das Ergebnis der Aufgabe, die durch die vorherige Ertragsanweisung generiert wurde, an die nächste.
- Überprüfen Sie das Orchestratorergebnis mithilfe der ergebnisse, die vom Orchestrator zurückgegeben wurden, und
unittest.mock
.
import unittest
from unittest.mock import Mock, patch, call
from datetime import timedelta
from azure.durable_functions.testing import orchestrator_generator_wrapper
from function_app import my_orchestrator
class TestFunction(unittest.TestCase):
@patch('azure.durable_functions.DurableOrchestrationContext')
def test_chaining_orchestrator(self, context):
# Get the original method definition as seen in the function_app.py file
func_call = my_orchestrator.build().get_user_function().orchestrator_function
# The mock_activity method is defined above with behavior specific to your app.
# It returns a TaskBase object with the result expected from the activity call.
context.call_activity = Mock(side_effect=mock_activity)
# Create a generator using the method and mocked context
user_orchestrator = func_call(context)
# Use orchestrator_generator_wrapper to get the values from the generator.
# Processes the orchestrator in a way that is equivalent to the Durable replay logic
values = [val for val in orchestrator_generator_wrapper(user_orchestrator)]
expected_activity_calls = [call('say_hello', 'Tokyo'),
call('say_hello', 'Seattle'),
call('say_hello', 'London')]
self.assertEqual(context.call_activity.call_count, 3)
self.assertEqual(context.call_activity.call_args_list, expected_activity_calls)
self.assertEqual(values[3], ["Hello Tokyo!", "Hello Seattle!", "Hello London!"])
Komponententestentitätsfunktionen
Entitätsfunktionen verwalten zustandsbehaftete Objekte mit Vorgängen. So testen Sie eine Entitätsfunktion:
- Simulieren Sie den
DurableEntityContext
internen Zustand und die Betriebseingaben der Entität. - Ersetzen Sie
DurableEntityContext
Methoden wieget_state
,set_state
undoperation_name
durch Modelle, die kontrollierte Werte zurückgeben. - Rufen Sie die Entitätsfunktion direkt mit dem simulierten Kontext auf.
- Verwenden Sie Assertionen, um Zustandsänderungen und zurückgegebene Werte zusammen mit
unittest.mock
Hilfsprogrammen zu überprüfen.
import unittest
from unittest.mock import Mock, patch
from function_app import Counter
class TestEntityFunction(unittest.TestCase):
@patch('azure.durable_functions.DurableEntityContext')
def test_entity_add_operation(self, context_mock):
# Get the original method definition as seen in function_app.py
func_call = Counter.build().get_user_function().entity_function
# Setup mock context behavior
state = 0
result = None
def set_state(new_state):
nonlocal state
state = new_state
def set_result(new_result):
nonlocal result
result = new_result
context_mock.get_state = Mock(return_value=state)
context_mock.set_state = Mock(side_effect=set_state)
context_mock.operation_name = "add"
context_mock.get_input = Mock(return_value=5)
context_mock.set_result = Mock(side_effect=lambda x: set_result)
# Call the entity function with the mocked context
func_call(context_mock)
# Verify the state was updated correctly
context_mock.set_state.assert_called_once_with(5)
self.assertEqual(state, 5)
self.assertEqual(result, None)
Komponententestaktivitätsfunktionen
Aktivitätsfunktionen erfordern keine langlebigen Änderungen, die getestet werden müssen. Die Anleitung in der Übersicht über die Azure Functions Python-Komponententests reicht aus, um diese Funktionen zu testen.