يمكن الاختبار الثابت استبدال اختبار الوحدة؟

StackOverflow https://stackoverflow.com/questions/766867

  •  12-09-2019
  •  | 
  •  

سؤال

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

في الآونة الأخيرة، كنت ألعب مع Haskell، وهي مكتبة اختبار المقيمين، Quickcheck. بشكل مختلف بشكل مختلف عن TDD، فإن QuickCheck لديه التركيز على اختبار ثابتة من التعليمات البرمجية، أي بعض الخصائص التي تمسك جميع المدخلات (أو المجموعات الفرعية الفنية) من المدخلات. مثال سريع: يجب أن تعطي خوارزمية فرز مستقرة نفس الإجابة إذا كنا نركزها مرتين، فيجب أن يكون لها إخراج متزايد، يجب أن يكون لها إذن من الإدخال، إلخ. ثم، يولد QuickCheck مجموعة متنوعة من البيانات العشوائية من أجل اختبار هذه الثبات.

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

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

هل ذهبت مجنونا، أو أنا على شيء ما؟

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

المحلول

بعد عام، أعتقد الآن أن لدي إجابة على هذا السؤال: رقم! على وجه الخصوص، ستكون اختبارات الوحدات ضرورية دائما ومفيدة لاختبارات الانحدار، حيث يتم إرفاق اختبار بتقرير علة وحياة في CodeBase لمنع هذا الخطأ من أي وقت مضى.

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

نصائح أخرى

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

أعتقد أن هذا هو السبب في أنه لن يحل محل اختبار الوحدة: لا يناسب القانون الحتمي بسهولة.

مشكوك فيه

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

نتائج مضللة

لقد سمعت اختبارات مثل:

  • reverse(reverse(list)) يجب أن يساوي list
  • unzip(zip(data)) يجب أن يساوي data

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

يبدو لي أنك تريد التحقق من ذلك، على سبيل المثال، reverse([1 2 3]) تساوي [3 2 1] لإثبات السلوك الصحيح في حالة واحدة على الأقل، ثم يضيف بعض الاختبارات مع البيانات العشوائية.

اختبار تعقيد

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

اختبار الوحدة الجيد، على النقيض من ذلك، سهل البرغي أو سوء فهم كقارئ. فقط خطأ يمكن أن يخلق خطأ في "توقع reverse([1 2 3]) لتساوي [3 2 1]".

ما كتبته في منصبك الأصلي، ذكرني بهذه المشكلة، وهو سؤال مفتوح فيما يتعلق بما هو ثابت حلقة إثبات حلقة صحيحة ...

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

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