تسمية اختبار للقراءة في JS والنمط السلوكي

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


Disklemer


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



TDD للمبتدئين


بناءً على طلب الزملاء الذين لا يشعرون بالراحة عند قراءة الكتيبات الإنجليزية ، قررت ترجمة وتجميع الكتيبات باللغة الإنجليزية.


من المترجم


أخذت هاتين المادتين كأساس للمقال:



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


التفضيل الشخصي هو أن كل شيء في الكود يجب أن يكون باللغة الإنجليزية.


تسمية الاختبارات


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


مثال سيء :


describe('discoveryService => initDiscoveries', () => { it(' discoveries ( ,    ..)', () => { // ... }); }); describe('MyGallery', () => { it('init      ( , - )', () => { }); // ... }); 

من الأمثلة أعلاه ، يصعب فهم الإجراء (الإجراءات) المحددة التي يتم تنفيذها والنتيجة المحددة التي يجب أن يؤدي إليها الإجراء.


مثال جيد :


 describe('discoveryService => initDiscoveries', () => { it('   discoveries', () => { // ... }); it('     discoveries', () => { // ... }); }); describe(' Gallery', () => { it('       ', () => { }); it('       ', () => { }); // ... }); 

تقريبا. العابرة. # 1: لاحظ أن كتلة النص في ذلك تبدأ بحرف كبير ، مثل هو استمرار الجملة التي بدأت في descibe .


تقريبا. العابرة. # 2: في الأمثلة أعلاه ، يتم تقسيم "discoveryService => initDiscoveries" بشكل صحيح إلى كتلتين descibe (إحداها متداخلة في الأخرى).


تقريبا. العابرة. # 3: لاحظ أنه في الأمثلة حول الاكتشاف أعلاه ، لا يوجد جزء ثانٍ من وصف حالة الاختبار ؛ أنه يتضمن نصًا للنموذج "عند الاحتجاج به" ، وهو ليس جيدًا من ناحية المظهر ؛ في حالات بسيطة ، فإن نسخ اللصق "عندما يطلق عليه" ليس مربحًا بشكل خاص ، IMHO.


في كتلة الوصف ، عادةً ما يتم وضع وصف للعمل الأولي (وحدة العمل ، UoW). يجب أن تستمر الصياغة في الكتلة بنمط " وحدة العمل - السيناريو / السياق - السلوك المتوقع " الذي بدأ في وصف:
[ ] [ / ] ( | ) [ ]


أو كرمز:


 describe('[unit of work]', () => { it(' [ ] / [/]', () => { }); }); 

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


 describe('[unit of work]', () => { describe('// [scenario/context]', () => { it('/ [expected behaviour]', () => { }); }); }); describe(' Gallery', () => { describe(' ', () => { it('    ', () => { }); it('    ', () => { }); }); // ... }); 

اختبار واحد - مشكلة واحدة


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


مثال سيء :


 describe('isUndefined function', ()=> { it('  true or false    undefined', () => { expect(isUndefined(undefined)).toEqual(true); expect(isUndefined(true)).toEqual(false); }); }); 

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


مثال جيد :


 describe('isUndefined function', ()=> { it('  true,    undefined', () => { expect(isUndefined(undefined)).toEqual(true); }); it('  false      ', () => { expect(isUndefined(true)).toEqual(false); }); }); 

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


اختبار السلوك


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


مثال سيء :


 it('   discovery  ', () => { discoveriesCache.addDiscovery('57463', 'John'); expect(discoveriesCache._discoveries[0].id).toBe('57463'); expect(discoveriesCache._discoveries[0].name).toBe('John'); }); 

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


مثال جيد :


 it('   discovery  ', () => { discoveriesCache.addDiscovery('57463', 'John'); expect(discoveriesCache.isDiscoveryExist('57463', 'John')).toBe(true); }); 

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


خاتمة من المترجم


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


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


كان يعني أنه يجب اختبار السلوك ، وليس وحدات الكود. واللغة النصية يجب أن يكون لها نمط سلوكي. أي "يجب أن يتصرف الكيان" أ "بهذه الطريقة وبهذه الطريقة في ظل هذه الظروف وكذا". سلسلة النموذج تصف [- صف ] - تتوقع - يجب أن تتحول إلى صيغة قابلة للطي.


شكرا لاهتمامكم!

Source: https://habr.com/ru/post/ar454884/


All Articles