Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Enhetstestning är en viktig del av moderna metoder för programvaruutveckling. Enhetstester verifierar affärslogikens beteende och skyddar mot att introducera oavsiktliga förändringar som kan bryta befintlig funktionalitet i framtiden. Durable Functions kan enkelt växa i komplexitet, så att introducera enhetstester hjälper till att undvika icke-bakåtkompatibla ändringar. I följande avsnitt beskrivs hur du enhetstestar de tre funktionstyperna – Orchestration-klienten, orchestrator- och entitetsfunktionerna.
Anmärkning
Den här guiden gäller endast för Durable Functions-appar som skrivits i python v2-programmeringsmodellen.
Förutsättningar
Exemplen i den här artikeln kräver kunskap om följande begrepp och ramverk:
- Enhetstestning
- Varaktiga funktioner
- Python unittest
- unittest.mock
Konfigurera testmiljön
För att testa Durable Functions är det viktigt att konfigurera en korrekt testmiljö. Detta inkluderar att skapa en testkatalog och installera Python-modulen unittest i din Python-miljö. Mer information finns i översikten över Azure Functions Python-enhetstestning.
Utlösarfunktioner för enhetstestning
Utlösarfunktioner, som ofta kallas klientfunktioner , initierar orkestreringar och externa händelser. Så här testar du följande funktioner:
- 
              DurableOrchestrationClientSimulera orkestreringskörning och statushantering.
- Tilldela DurableOrchestrationClientmetoder somstart_new,get_statusellerraise_eventmed falska funktioner som returnerar förväntade värden.
- Anropa klientfunktionen direkt med en mockad klient och andra nödvändiga indata, till exempel ett req(HTTP-begärandeobjekt) för HTTP-trigger klientfunktioner.
- Använd påståenden och unittest.mock-verktyg för att verifiera förväntat beteende vid orkestreringsstart, parametrar och HTTP-svar.
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")
Enhetstestning av orkestreringsfunktioner
Orchestrator-funktioner hanterar exekveringen av flera aktivitetsfunktioner. Så här testar du en orkestrerare:
- Simulera DurableOrchestrationContextför att kontrollera funktionskörningen.
- Ersätt DurableOrchestrationContextmetoder som behövs för att köra orkestrering, såsomcall_activityellercreate_timer, med mockfunktioner. Dessa funktioner returnerar vanligtvis objekt av typen TaskBase med enresultegenskap.
- Anropa orchestratorn rekursivt och skicka resultatet av den Uppgift som genererades av föregående yield-sats till nästa.
- Kontrollera orchestrator-resultatet med hjälp av resultaten som returneras från orchestrator och 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!"])
Enhetstestning av entitetsfunktioner
Entitetsfunktioner hanterar tillståndskänsliga objekt med åtgärder. Så här testar du en entitetsfunktion:
- 
              DurableEntityContextSimulera entitetens interna tillstånd och indata för åtgärden.
- Ersätt DurableEntityContextmetoder somget_state,set_stateochoperation_namemed modeller som returnerar kontrollerade värden.
- Anropa entitetsfunktionen direkt med den simulerade kontexten.
- Använd påståenden för att verifiera tillståndsändringar och returnerade värden, tillsammans med unittest.mockverktyg.
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)
Aktivitetsfunktioner för enhetstestning
Aktivitetsfunktioner kräver inga Durable-specifika ändringar för att testas. Den vägledning som finns i översikten över Azure Functions Python-enhetstestning räcker för att testa dessa funktioner.