سؤال

عندما تعرفت على Mocks، شعرت أن الهدف الأساسي هو محاكاة الكائنات التي تأتي من مصادر خارجية للبيانات.بهذه الطريقة لم أضطر إلى الاحتفاظ بقاعدة بيانات اختبار اختبار الوحدة الآلية، بل كان بإمكاني فقط تزييفها.

لكنني الآن بدأت أفكر في الأمر بشكل مختلف.أتساءل عما إذا كانت Mocks أكثر فعالية في استخدامها لعزل الطريقة المختبرة تمامًا عن أي شيء خارجها.الصورة التي تتبادر إلى ذهنك باستمرار هي الخلفية التي تستخدمها عند الرسم.تريد منع الطلاء من الوصول إلى كل شيء.أنا فقط أختبر هذه الطريقة، وأريد فقط أن أعرف كيف تتفاعل مع هذه العوامل الخارجية المزيفة؟

يبدو الأمر مملاً للغاية للقيام بذلك بهذه الطريقة ولكن الميزة التي أراها هي أنه عندما يفشل الاختبار يكون ذلك بسبب إخفاقه وليس 16 طبقة.ولكن الآن لا بد لي من إجراء 16 اختبارًا للحصول على نفس تغطية الاختبار لأنه سيتم اختبار كل قطعة على حدة.بالإضافة إلى أن كل اختبار يصبح أكثر تعقيدًا وأكثر ارتباطًا بالطريقة التي يتم اختباره بها.

يبدو الأمر صحيحًا بالنسبة لي ولكنه يبدو قاسيًا أيضًا، لذا أريد أن أعرف ما يعتقده الآخرون.

هل كانت مفيدة؟

المحلول

أنصحك بإلقاء نظرة على مقال مارتن فاولر يسخر ليست بذرة للحصول على معاملة أكثر موثوقية لـ Mocks مما أستطيع أن أقدمه لك.

الغرض من المحاكاة هو اختبار الوحدة للتعليمات البرمجية الخاصة بك بمعزل عن التبعيات حتى تتمكن من اختبار جزء من التعليمات البرمجية على مستوى "الوحدة".الكود قيد الاختبار هو الصفقة الحقيقية، وكل جزء آخر من الكود الذي يعتمد عليه (عبر المعلمات أو حقن التبعية، وما إلى ذلك) هو "نموذج وهمي" (تطبيق فارغ يُرجع دائمًا القيم المتوقعة عند استدعاء إحدى طرقه.)

قد تبدو النماذج المملة مملة في البداية، لكنها تجعل اختبار الوحدات أسهل بكثير وأكثر قوة بمجرد أن تتقن استخدامها.تحتوي معظم اللغات على مكتبات وهمية تجعل السخرية أمرًا تافهًا نسبيًا.إذا كنت تستخدم Java، سأوصيك بمفضلتي الشخصية: ايزي موك.

اسمحوا لي أن أنهي هذا الفكر:أنت بحاجة إلى اختبارات التكامل أيضًا، ولكن الحصول على حجم جيد من اختبارات الوحدات يساعدك على معرفة المكون الذي يحتوي على خطأ، في حالة وجوده.

نصائح أخرى

لا تسلك الطريق المظلم يا سيد لوك.:) لا تسخر من كل شيء.يمكنك ولكن لا ينبغي عليك...هذا هو السبب.

  • إذا واصلت اختبار كل طريقة على حدة، فستكون لديك مفاجآت وأعمال مقطوعة بالنسبة لك عندما تجمعها جميعًا معًا الانفجار العظيم.نحن نبني الأشياء حتى تتمكن من العمل معًا لحل مشكلة أكبر..في حد ذاتها فهي ضئيلة.أنت بحاجة إلى معرفة ما إذا كان جميع المتعاونين يعملون كما هو متوقع.
  • يسخر جعل الاختبارات هشة من خلال تقديم الازدواجية - نعم أعلم أن هذا يبدو مثيرًا للقلق.مقابل كل عملية إعداد وهمية تتوقعها، هناك عدد n من الأماكن التي يوجد بها توقيع طريقتك.الكود الفعلي وتوقعاتك الوهمية (في اختبارات متعددة).تغيير الكود الفعلي أسهل...تحديث جميع التوقعات الوهمية أمر شاق.
  • لك أصبح الاختبار الآن مطلعاً على معلومات التنفيذ الداخلية.لذا فإن اختبارك يعتمد على الطريقة التي اخترتها لتنفيذ الحل...سيء.يجب أن تكون الاختبارات مواصفات مستقلة يمكن تلبيتها بحلول متعددة.يجب أن أتمتع بحرية الضغط على "حذف" على مجموعة من التعليمات البرمجية وإعادة التنفيذ بدون الاضطرار إلى إعادة كتابة مجموعة الاختبار ..لأن المتطلبات لا تزال كما هي.

في الختام، سأقول "إذا كانت تصر مثل البطة، وتمشي مثل البطة، فمن المحتمل أنها بطة" - إذا شعرت بالخطأ..ربما يكون كذلك.* استخدم نماذج لاستبعاد الأطفال الذين يعانون من مشكلات مثل عمليات الإدخال والإخراج وقواعد البيانات ومكونات الطرف الثالث وما شابه.مثل الملح بعضه ضروري..الكثير و :x*
هذه هي الحرب المقدسة للاختبار القائم على الدولة مقابل الاختبار القائم على التفاعل.سوف يمنحك Googling رؤية أعمق.

إيضاح:أنا أواجه بعض المقاومة w.r.t.اختبارات التكامل هنا :) لذا لتوضيح موقفي..

  • لا تظهر المحاكاة في "اختبارات القبول"/مجال التكامل.لن تجدهم إلا في عالم اختبار الوحدات..وهذا هو تركيزي هنا.
  • اختبارات القبول مختلفة وهي كذلك كثيرا اللازمة - عدم التقليل منهم.لكن اختبارات الوحدة واختبارات القبول مختلفة ويجب أن تظل مختلفة.
  • لا يحتاج جميع المتعاونين داخل المكون أو الحزمة إلى العزلة عن بعضهم البعض.مثل التحسين الجزئي الذي يعتبر مبالغة.إنهم موجودون لحل مشكلة ما معاً..تماسك.

نعم اوافق.أرى أن السخرية مؤلمة في بعض الأحيان، ولكنها ضرورية في كثير من الأحيان، حتى تصبح اختباراتك حقيقية وحدة الاختبارات، أي.فقط أصغر وحدة يمكنك إجراء اختبارك عليها هي قيد الاختبار.يتيح لك ذلك استبعاد أي عوامل أخرى قد تؤثر على نتيجة الاختبار.سينتهي بك الأمر بإجراء الكثير من الاختبارات الصغيرة، ولكن يصبح من الأسهل جدًا معرفة مكان المشكلة في التعليمات البرمجية الخاصة بك.

فلسفتي هي أنه يجب عليك كتابة تعليمات برمجية قابلة للاختبار لتناسب الاختبارات،
لا تكتب اختبارات لتناسب الكود.

أما بالنسبة للتعقيد، فإن رأيي هو أن الاختبارات يجب أن تكون سهلة الكتابة، وذلك ببساطة لأنك تكتب المزيد من الاختبارات إذا كانت كذلك.

قد أوافق على أن هذه قد تكون فكرة جيدة إذا كانت الفصول الدراسية التي تسخر منها لا تحتوي على مجموعة اختبار، لأنه إذا كان لديهم مجموعة اختبار مناسبة، فستعرف أين تكمن المشكلة دون عزل.

معظم الوقت الذي استخدمته للكائنات الوهمية هو عندما يكون الكود الذي أكتب اختبارات له مقترنًا بإحكام (اقرأ:تصميم سيء)، حيث يجب علي أن أكتب كائنات وهمية عندما لا تكون الفئات التي تعتمد عليها متاحة.بالتأكيد هناك استخدامات صالحة للكائنات الوهمية، ولكن إذا كان الكود الخاص بك يتطلب استخدامها، أود أن ألقي نظرة أخرى على التصميم.

نعم، هذا هو الجانب السلبي للاختبار مع المحاكاة.هناك الكثير من العمل الذي تحتاج إلى القيام به وهو أمر وحشي.ولكن هذا هو جوهر اختبار الوحدة.كيف يمكنك اختبار شيء ما بمعزل عن الآخرين إذا كنت لا تسخر من الموارد الخارجية؟

من ناحية أخرى، أنت تسخر من الوظائف البطيئة (مثل قواعد البيانات وعمليات الإدخال/الإخراج).إذا كانت الاختبارات تجري بشكل أسرع، فسيبقي ذلك المبرمجين سعداء.لا يوجد شيء أكثر إيلامًا من انتظار الاختبارات البطيئة حقًا، والتي تستغرق أكثر من 10 ثوانٍ حتى تنتهي من التشغيل، بينما تحاول تنفيذ ميزة واحدة.

إذا قضى كل مطور في مشروعك وقتًا في كتابة اختبارات الوحدة، فلن تمثل تلك الطبقات الـ 16 (غير المباشرة) مشكلة كبيرة.نأمل أن تحصل على تغطية الاختبار من البداية، أليس كذلك؟:)

ولا تنس أيضًا كتابة اختبار دالة/تكامل بين الكائنات بالتعاون.وإلا قد تفوت شيئا.لن يلزم إجراء هذه الاختبارات بشكل متكرر، ولكنها لا تزال مهمة.

على أحد المقاييس، نعم، تهدف المحاكاة إلى استخدامها لمحاكاة مصادر البيانات الخارجية مثل قاعدة بيانات أو خدمة ويب.على نطاق أكثر دقة، ومع ذلك، إذا كنت تصمم تعليمات برمجية مقترنة بشكل غير محكم، فيمكنك رسم خطوط في جميع أنحاء التعليمات البرمجية الخاصة بك بشكل تعسفي تقريبًا فيما يتعلق بما قد يكون في أي وقت "نظامًا خارجيًا".خذ مشروعًا أعمل عليه حاليًا:

عندما يحاول شخص ما تسجيل الوصول، فإن CheckInUi يرسل أ معلومات التحقق يعترض على أ CheckInMediator الكائن الذي يتحقق من صحته باستخدام CheckInValidator, ، إذا كان الأمر على ما يرام، فإنه يملأ كائن المجال المسمى عملية مع معلومات التحقق استخدام CheckInInfoAdapter ثم يمر عملية إلى مثال ITransactionDao.SaveTransaction() من أجل الثبات.

أنا الآن أكتب بعض الآلي اختبارات التكامل ومن الواضح أن CheckInUi و ITransactionDao هي نوافذ على الأنظمة الخارجية وهي التي ينبغي الاستهزاء بها.ومع ذلك، الذي يقول ذلك في مرحلة ما CheckInValidator لن يتم إجراء مكالمة إلى خدمة ويب؟ولهذا السبب عندما تكتب اختبارات الوحدة أنت تفترض أن كل شيء بخلاف الوظيفة المحددة لفصلك هو نظام خارجي.لذلك في اختبار الوحدة الخاص بي CheckInMediator أنا أسخر من كل الأشياء التي يتحدث إليها.

يحرر: جيشو صحيح من الناحية الفنية، وليس كل شيء يحتاج إلى السخرية، وأنا لا أسخر منه على سبيل المثال معلومات التحقق لأنه مجرد حاوية للبيانات.ومع ذلك، يجب الاستهزاء بأي شيء يمكن أن تراه كخدمة خارجية (وهو تقريبًا أي شيء يحول البيانات أو له آثار جانبية).

التشبيه الذي أحبه هو التفكير في التصميم المقترن بشكل غير محكم باعتباره حقلًا يقف حوله أشخاص يلعبون لعبة الالتقاط.عندما يتم تمرير الكرة لشخص ما، قد يرمي كرة مختلفة تمامًا إلى الشخص التالي، بل قد يرمي عدة كرات متتالية لأشخاص مختلفين أو يرمي كرة وينتظر استعادتها قبل رميها لشخص آخر.إنها لعبة غريبة.

الآن كمدربهم ومديرهم، أنت بالطبع تريد التحقق من كيفية عمل فريقك ككل بحيث يكون لديك تدريب جماعي (اختبارات التكامل) ولكن لديك أيضًا كل لاعب يتدرب بمفرده ضد الدعامات الخلفية وآلات رمي ​​الكرة (اختبارات الوحدة مع يسخر).القطعة الوحيدة التي تفتقدها هذه الصورة هي التوقعات الوهمية ولذلك فقد تم تلطيخ كراتنا بالقطران الأسود بحيث تلطخ الدعامة عندما تصطدم بها.تحتوي كل نقطة توقف على "منطقة مستهدفة" يستهدفها الشخص، وإذا لم تكن هناك علامة سوداء داخل المنطقة المستهدفة في نهاية التدريب، فأنت تعلم أن هناك خطأ ما وأن الشخص يحتاج إلى ضبط أسلوبه.

خذ الوقت الكافي لتعلمها بشكل صحيح، اليوم الذي فهمت فيه Mocks كان لحظة رائعة.ادمجها مع انعكاس حاوية التحكم ولن أعود أبدًا.

في ملاحظة جانبية، جاء أحد موظفي تكنولوجيا المعلومات لدينا وأعطاني جهاز كمبيوتر محمولًا مجانًا!

كما قال أحد الأشخاص من قبل، إذا سخرت من كل شيء لعزل المزيد من التفاصيل عن الفئة التي تختبرها، فإنك تتخلى عن فرض التماسك في التعليمات البرمجية الخاصة بك التي هي قيد الاختبار.

ضع في اعتبارك أن للسخرية ميزة أساسية وهي التحقق من السلوك.هذا شيء لا توفره بذرة وهو السبب الآخر الذي يجعل الاختبار أكثر هشاشة (ولكن يمكن أن يحسن تغطية الكود).

تم اختراع المحاكاة جزئيًا لـ اجب على السؤال:كيف يمكنك وحدة اختبار الكائنات إذا لم يكن لديهم حروف أو أدوات ضبط؟

هذه الأيام، مُستَحسَن الممارسة هي السخرية من الأدوار وليس الأشياء.استخدم Mocks كأداة تصميم للحديث عن التعاون وفصل المسؤوليات، وليس كـ "بذرة ذكية".

الكائنات الوهمية هي 1) تُستخدم غالبًا كوسيلة لعزل الكود قيد الاختبار، ولكن 2) كما أشار كيثب بالفعل، فهي مهمة لـ "التركيز على العلاقات بين الكائنات المتعاونة".تقدم هذه المقالة بعض الأفكار والتاريخ المتعلق بالموضوع: تصميم مدفوع بالمسؤولية مع كائنات وهمية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top