سؤال

لدي زميل في العمل يكتب اختبارات الوحدة للكائنات التي تملأ حقولها ببيانات عشوائية.والسبب في ذلك هو أنه يوفر نطاقًا أوسع من الاختبارات، لأنه سيختبر الكثير من القيم المختلفة، في حين أن الاختبار العادي يستخدم فقط قيمة ثابتة واحدة.

لقد قدمت له عددًا من الأسباب المختلفة ضد ذلك، أهمها:

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

وأضاف زميل آخر في العمل:

  • إذا كنت أقوم باختبار استثناء، فلن تضمن القيم العشوائية وصول الاختبار إلى الحالة المتوقعة
  • يتم استخدام البيانات العشوائية لطرد النظام واختبار التحميل، وليس لاختبارات الوحدة

هل يمكن لأي شخص آخر إضافة أسباب إضافية يمكنني تقديمها له لحمله على التوقف عن القيام بذلك؟

(أو بدلاً من ذلك، هل هذه طريقة مقبولة لكتابة اختبارات الوحدة، وأنا وزملائي الآخرون في العمل مخطئون؟)

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

المحلول

هناك حل وسط.زميلك في العمل في الواقع يخطط لشيء ما، لكني أعتقد أنه يفعل ذلك بشكل خاطئ.لست متأكدًا من أن الاختبار العشوائي تمامًا مفيد جدًا، ولكنه بالتأكيد ليس غير صالح.

مواصفات البرنامج (أو الوحدة) هي فرضية بوجود برنامج ما يلبي هذه المواصفات.ثم يعد البرنامج نفسه دليلاً على هذه الفرضية.ما يجب أن يكون عليه اختبار الوحدة هو محاولة تقديم أدلة مضادة لدحض أن البرنامج يعمل وفقًا للمواصفات.

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

لا أعرف ما هي اللغة التي تستخدمها، ولكن انظر هنا:

جافاhttp://functionaljava.org/

سكالا (أو جافا)http://github.com/rickynils/scalacheck

هاسكلhttp://www.cs.chalmers.se/~rjmh/QuickCheck/

.شبكة:http://blogs.msdn.com/dsyme/archive/2008/08/09/fscheck-0-2.aspx

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

اختبار سعيد!

نصائح أخرى

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

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

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

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

في هذا الكتاب كود جميل, ، هناك فصل بعنوان "الاختبارات الجميلة"، حيث يتناول استراتيجية اختبار لـ بحث ثنائي خوارزمية.تسمى فقرة واحدة "أعمال الاختبار العشوائية"، حيث يقوم بإنشاء مصفوفات عشوائية لاختبار الخوارزمية بدقة.يمكنك قراءة بعض من هذا عبر الإنترنت في Google Books، الصفحة 95, ، لكنه كتاب عظيم يستحق الحصول عليه.

يوضح هذا بشكل أساسي أن إنشاء بيانات عشوائية للاختبار يعد خيارًا قابلاً للتطبيق.

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

إذا كنت تقوم بـ TDD فأنا أزعم أن البيانات العشوائية هي طريقة ممتازة.إذا كان اختبارك مكتوبًا بالثوابت، فيمكنك ضمان أن الكود الخاص بك يعمل فقط للقيمة المحددة.إذا فشل اختبارك بشكل عشوائي في خادم البناء، فمن المحتمل أن تكون هناك مشكلة في كيفية كتابة الاختبار.

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

أنا أبالغ لكنني أفضل إدخال بيانات عشوائية في الاختبار الخاص بي كإشارة إلى أن "قيمة هذا المتغير لا ينبغي أن تؤثر على نتيجة هذا الاختبار".

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

  • إذا كانت قيمة عشوائية وفشل الاختبار، فنحن بحاجة إلى أ) إصلاح الكائن و ب) إجبار أنفسنا على اختبار هذه القيمة في كل مرة، حتى نعرف أنها تعمل، ولكن نظرًا لأنها عشوائية، فإننا لا نعرف ما هي القيمة

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

زميلك في العمل يفعل اختبار الزغب, ، رغم أنه لا يعلم بذلك.إنها ذات قيمة خاصة في أنظمة الخادم.

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

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

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

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

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

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

هناك الكثير مما يمكن قوله عن الاختبارات العشوائية، خاصة تلك المكتوبة بشكل جيد، لذا لا تتسرع في رفضها!

هل يمكنك توليد بعض البيانات العشوائية مرة واحدة (أعني مرة واحدة بالضبط، وليس مرة واحدة لكل اختبار تشغيل)، ثم استخدامها في جميع الاختبارات بعد ذلك؟

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

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

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

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

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

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

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

هل ما زال التأهل عشوائيا؟دعونا نتحدث على البيرة.:-)

يمكنني تصور ثلاثة حلول لمشكلة بيانات الاختبار:

  • اختبار مع البيانات الثابتة
  • اختبار مع بيانات عشوائية
  • توليد بيانات عشوائية مرة واحدة, ، ثم استخدمها كبياناتك الثابتة

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

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

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

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

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

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