إشعار
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تسجيل الدخول أو تغيير الدلائل.
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تغيير الدلائل.
يعد اختبار الوحدة جزءا مهما من ممارسات تطوير البرامج الحديثة. تتحقق اختبارات الوحدة من سلوك منطق العمل وتحمي من إدخال تغييرات كسرية غير ملاحظتها في المستقبل. يمكن أن تنمو Durable Functions بسهولة في التعقيد، لذا فإن إدخال اختبارات الوحدة يساعد على تجنب كسر التغييرات. تشرح الأقسام التالية كيفية اختبار الوحدة أنواع الوظائف الثلاثة - عميل التزامن والمنسق ووظائف الكيان.
ملاحظة
ينطبق هذا الدليل فقط على تطبيقات Durable Functions المكتوبة في نموذج برمجة Python v2.
المتطلبات الأساسية
تتطلب الأمثلة الواردة في هذه المقالة معرفة المفاهيم والأطر التالية:
- اختبار الوحدة
- وظائف دائمة
- Python unittest
- unittest.mock
إعداد بيئة الاختبار
لاختبار Durable Functions، من الضروري إعداد بيئة اختبار مناسبة. يتضمن ذلك إنشاء دليل اختبار وتثبيت وحدة Python unittest في بيئة Python الخاصة بك. لمزيد من المعلومات، راجع نظرة عامة على اختبار وحدة Azure Functions Python.
وظائف مشغل اختبار الوحدة
وظائف المشغل، التي يشار إليها غالبا باسم وظائف العميل ، تبدأ التنسيقات والأحداث الخارجية. لاختبار هذه الدالات:
- محاكاة
DurableOrchestrationClientلمحاكاة تنفيذ التزامن وإدارة الحالة. - تعيين
DurableOrchestrationClientأساليب مثلstart_newأوget_statusأوraise_eventباستخدام دالات وهمية ترجع القيم المتوقعة. - استدعاء دالة العميل مباشرة مع عميل وهمية والمدخلات الضرورية الأخرى مثل
req(كائن طلب HTTP) لوظائف عميل مشغل HTTP. - استخدم التأكيدات والأدوات
unittest.mockللتحقق من سلوك بدء التنسيق المتوقع والمعلمات واستجابات HTTP.
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")
وظائف منسق اختبار الوحدة
تدير دوال المنسق تنفيذ وظائف نشاط متعددة. لاختبار منسق:
- وهمية
DurableOrchestrationContextللتحكم في تنفيذ الدالة. - استبدل
DurableOrchestrationContextالأساليب المطلوبة لتنفيذ المنسق مثلcall_activityأوcreate_timerبوظائف وهمية. عادة ما ترجع هذه الدالات كائنات من نوع TaskBase بخاصيةresult. - استدعاء المنسق بشكل متكرر، وتمرير نتيجة المهمة التي تم إنشاؤها بواسطة عبارة العائد السابقة إلى التالي.
- تحقق من نتيجة المنسق باستخدام النتائج التي تم إرجاعها من المنسق و
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!"])
وظائف كيان اختبار الوحدة
تدير وظائف الكيان الكائنات ذات الحالة باستخدام العمليات. لاختبار دالة كيان:
-
DurableEntityContextوهمية لمحاكاة الحالة الداخلية للكيان ومدخلات العملية. - استبدل
DurableEntityContextأساليب مثلget_stateوset_stateو بأحرفoperation_nameوهمية ترجع القيم الخاضعة للرقابة. - استدعاء دالة الكيان مباشرة مع السياق الوهمي.
- استخدم التأكيدات للتحقق من تغييرات الحالة والقيم التي تم إرجاعها، جنبا إلى جنب مع
unittest.mockالأدوات المساعدة.
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)
وظائف نشاط اختبار الوحدة
لا تتطلب وظائف النشاط أي تعديلات دائمة خاصة ليتم اختبارها. الإرشادات الموجودة في نظرة عامة على اختبار وحدة Azure Functions Python كافية لاختبار هذه الدالات.