الاختبارات في بايثون: جميع المقاربات والإيجابيات والسلبيات الرئيسية. تقرير ياندكس

أمامك تقرير ماريا زيلينوفا زيلما- مطور في Foodil. في غضون ساعة ، أخبر ماشا ما هي برامج الاختبار ، وما هي الاختبارات ، ولماذا كتابتها. باستخدام أمثلة بسيطة ، يمكنك التعرف على المكتبات لاختبار كود Python (unittest ، pytest ، mock) ، وكيف تعمل والاختلافات بينها.





- مساء الخير اسمي ماشا اعمل بقسم اديلا لتحليل البيانات واليوم لدينا محاضرة عن الاختبار معك.







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







أود أن أبدأ بمثال. سأحاول أن أشرح بأمثلة مخيفة للغاية سبب أهمية كتابة الاختبارات.



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



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



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



  • . , . , . , .
  • C . THERAC , — , . . , , , - , - — .


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







هناك مثال آخر على أن كتابة الاختبارات في بعض المواقف يمكن أن توفر لك الكثير من المال. هذا هو Mars Climate Orbiter - جهاز كان من المفترض أن يقيس الغلاف الجوي في الغلاف الجوي للمريخ ، لمعرفة ما كان يحدث هناك مع المناخ.



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



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



سأتحدث الآن عن المزيد من الأسباب المبتذلة التي تجعلك تكتب الاختبارات. لنتحدث عن كل عنصر على حدة:



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



    , - , — , - . , . , , . , , , git blame, , , , .
  • . , . , . , , . - - , - - . , , , . - .
  • , . ? , , , , : , . 500 -, . . .
  • : — . , , . , , .



    , , , . , , .
  • . — , . , , . , .



    : - . , , . , , , - , .


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



تنقسم عملية الاختبار إلى اختبار الصندوق الأسود ، والاختبار الأبيض والرمادي.







اختبار الصندوق الأسود هو عملية عندما لا يعرف المُختبِر شيئًا عما بداخله. إنه ، مثل المستخدم العادي ، يفعل شيئًا دون معرفة أي تفاصيل عن التنفيذ.



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



اختبار الصندوق الرمادي هو شيء بينهما. هذا عندما تعرف بعض تفاصيل التنفيذ ، لكن ليس كل شيء.



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



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



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



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



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



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







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



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



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



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



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



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



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



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



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



مع النظرية ، كل شيء ، سأتحدث عن ما هو في بايثون.







فيما يلي قائمة ببعض المكتبات. لن أخوض في التفاصيل حولهم جميعًا ، لكني سأتحدث عن معظمهم. بالطبع ، سوف نتحدث عن غير مألوف وفاسد. هذه مكتبات تُستخدم مباشرةً في كتابة الاختبارات. Mock هي مكتبة مساعدة لإنشاء كائنات وهمية. سنتحدث عنها أيضا. Dictest هو وحدة لاختبار التوثيق ، flake8 هو linter ، وسوف ننظر إليها أيضًا. لن أتحدث عن البيراما والسموم. إذا كنت مهتمًا ، يمكنك أن ترى بنفسك. Pylama هو أيضًا لينتر ، حتى لوحدة معدنية ، فهو يجمع بين عدة حزم ، مريحة جدًا وجيدة. وهناك حاجة إلى مكتبة Tox إذا كنت بحاجة إلى اختبار التعليمات البرمجية الخاصة بك في بيئات مختلفة - على سبيل المثال ، مع إصدارات مختلفة من Python أو مع إصدارات مختلفة من المكتبات. يساعد Tox كثيرًا في هذا المعنى.



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







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



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



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







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



كيف تبدو؟ يبحث Doctest عن أشجار عيد الميلاد هذه في وثائق ، ثم ينفذها ويقارن ما تم الحصول عليه.







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





ارتباط من الشريحة



العقيدة لديها بعض التوجيهات المفيدة التي قد تكون في متناول اليد. لن أتحدث عنهم جميعًا ، لكن البعض الذي بدا لي هو الأكثر شيوعًا ، وضعته على الشريحة. يسمح لك توجيه SKIP بعدم إجراء اختبار على مثال محدد. يتجاهل توجيه IGNORE_EXCEPTION_DETAIL اختبار EXCEPTION. يتيح لك ELLIPSIS كتابة علامات الحذف بدلاً من أي مكان في الإخراج. توقف FAIL_FAST بعد أول اختبار فاشل. كل شيء آخر يمكن قراءته في الوثائق ، وهناك الكثير. من الأفضل أن أريكم بمثال.







يحتوي هذا المثال على توجيه ELLIPSIS وتوجيه IGNORE_EXCEPTION_DETAIL. ترى الإحصائيات الترتيبية K-th في توجيه ELLIPSIS ، ونتوقع أن يأتي شيء يبدأ بالرقم تسعة وينتهي بالرقم تسعة. يمكن أن يكون هناك أي شيء في المنتصف. مثل هذا الاختبار لن يفشل.



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







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



نقطة أخرى: الاختبارات المكتوبة بلغة unittest تعرف كيفية تشغيل pytest مباشرة خارج الصندوق. انه لا يهتم. (…)



يبدو Unittest هكذا. هناك فصل يبدأ باختبار الكلمات. في الداخل ، وظيفة تبدأ باختبار الكلمات. فئة الاختبار يرث من unittest.TestCase. يجب أن أقول على الفور أن أحد الاختبارات هنا مكتوب بشكل صحيح ، والآخر غير صحيح.



الاختبار الأعلى ، حيث يُكتب التأكيد العادي ، سيفشل ، لكنه سيبدو غريبًا. دعنا نلقي نظرة.







ابدأ الأمر. يمكنك كتابة unittest main في الكود نفسه ، ويمكنك تسميته من Python.







أجرينا هذا الاختبار ووجدنا أنه كتب خطأ AssertionError ، لكنه لم يكتب حيث وقع - على عكس الاختبار التالي الذي استخدم self.assertEqual. إنه مكتوب هنا بوضوح: ثلاثة لا يساوي اثنين.







يجب إصلاحه بالطبع. ولكن بعد ذلك لم يكن هذا الإخراج السحري مرئيًا على الشاشة.



لنلقي نظرة أخرى. في الحالة الأولى ، كتبنا التأكيد ، في الحالة الثانية ، self.assertEqual. لسوء الحظ ، هذا هو السبيل الوحيد غير المريح. هناك وظائف خاصة - self.assertEqual و self.assertnotEqual و 100500 وظيفة أخرى تحتاج إلى استخدامها إذا كنت تريد رؤية رسالة خطأ مناسبة.



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



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







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



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







Unittest له طرق خاصة setUp و tearDown لكتابة تركيبات. لماذا لا تزال غير مكتوبة وفقًا لـ PEP8 هو لغز كبير بالنسبة لي. (...)



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



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



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



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







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



أولاً ، سأحاول إخبارك لماذا يكون pytest مناسبًا.





الارتباط من الشريحة



النقطة الأولى: في pytest ، يؤكد عادةً أنه يعمل ، وتلك التي اعتدت عليها ، ويقدمون معلومات خطأ عادية. ثانيًا: هناك توثيق جيد لـ pytest ، حيث يتم تفكيك مجموعة من الأمثلة ، ويمكن رؤية أي شيء تريده ، كل ما لا تفهمه.



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



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







دعونا نرى مثالا. هكذا تبدو الاختبارات المكتوبة في pytest. المعنى هو نفسه في unittest ، إلا أنه يبدو أكثر إيجازًا. الاختبار الأول يتكون بشكل عام من سطرين.







قم بتشغيل الأمر python -m pytest. ممتاز. تم اجتياز اختبارين ، كل شيء على ما يرام ، يمكننا أن نرى ما اجتازوه وفي أي وقت.







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



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



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



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







دعونا نرى كيف تبدو المباريات في pytest. إذا كان من الضروري كتابة setUp و tearDown ، فقم هنا باستدعاء الوظيفة المعتادة كما تريد. لقد كتبنا ديكور pytest.fixture في الأعلى - رائع ، إنه عنصر أساسي.



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



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







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



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



أيضًا في المباريات ، من الممكن تحديد autouse = True وسيطة ، وبعد ذلك سيتم استدعاء المباراة بغض النظر عما إذا كنت قد طلبت ذلك أم لا. يبدو أنه لا ينبغي استخدام هذا الخيار مطلقًا ، أو ينبغي استخدامه ، ولكن بحذر شديد ، لأنه أمر ضمني. من الأفضل تجنب الضمني.







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



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



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



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







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



هنا لدينا الاختبار الأول ، اختبار واحد ، والذي يعتمد على نادر _dependency_for_test_one ، حيث تعتمد هذه المباراة على تركيبات أخرى - وواحدة أخرى. دعونا نرى ما يحدث في العادم.







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



لدى Pytest ملف تكوين خاص conftest.py حيث يمكنك وضع جميع التركيبات ، وهو أمر جيد إذا وضعته: عادةً ، عندما ينظر شخص ما إلى رمز شخص آخر ، فإنه عادة ما يذهب للنظر في التركيبات في Conftest.



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







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







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



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







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



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



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



شيء مفيد آخر هو skipif. هناك فقط تخطي لن يتم إجراء الاختبارات. وهناك تخطي. إذا علقت هذا المصمم ، فلن يتم الاختبار في ظل ظروف معينة.



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







لنبدأ. رأينا الحرف X ، ورأينا الحرف S. X هنا يشير إلى xfail ، و S - إلى skipif. وهذا يعني أن pytest يُظهر الاختبار الذي فقدناه تمامًا والذي أجريناه ، لكننا لا ننظر إلى النتيجة.







هناك العديد من الخيارات المفيدة المختلفة في pytest نفسها. أنا ، بالطبع ، لن أتمكن من عرضها هنا ، يمكنك رؤيتها في الوثائق. لكني سأخبرك عن القليل.



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



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



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



-v هو خيار الإسهاب القياسي ، زيادة الإسهاب.



--lf، --last-failure هو خيار يسمح لك بإعادة تشغيل الاختبارات التي فشلت في آخر مرة. --sw، - خطوة بخطوة هي أيضًا وظائف مفيدة مثل -k. إذا قمت بإصلاح الاختبارات بالتسلسل ، فعندئذٍ تقوم بإجراء - خطوة بخطوة ، يمر عبر الاختبارات الخضراء ، وبمجرد أن يرى الاختبار الفاشل ، يتوقف. وعندما تقوم بتشغيل --sw مرة أخرى ، يبدأ هذا الاختبار الذي انهار. إذا سقط مرة أخرى ، فسيتوقف مرة أخرى ؛ وإذا لم يسقط ، فسوف يستمر حتى الخريف التالي.





رابط من الشريحة



في pytest يوجد ملف تكوين رئيسي pytest.ini. في ذلك ، يمكنك تغيير السلوك الافتراضي لـ pytest. لقد قدمت هنا الخيارات التي غالبًا ما توجد في ملف التكوين.



ممرات الاختبار هي المسارات التي سيبحث عنها pytest عن الاختبارات. addopts هو ما يضاف إلى سطر الأوامر عند بدء التشغيل. لقد أضفت هنا إضافات flake8 والتغطية للإضافات. سوف ننظر إليهم بعد قليل.





رابط من الشريحة



هناك الكثير من المكونات الإضافية المختلفة في pytest. لقد كتبت تلك التي ، مرة أخرى ، تستخدم في كل مكان. flake8 هو linter ، والتغطية هي تغطية رمز عن طريق الاختبارات. ثم هناك مجموعة كاملة من المكونات الإضافية التي تسهل العمل مع أطر معينة: pytest-flask ، pytest-django ، pytest-twisted ، pytest-tornado. ربما هناك شيء آخر.



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







دعنا نلقي نظرة. أضفت تغطية و flake8 إلى pytest.ini. أعطتني التغطية تقريرًا ، ولدي ملف به اختبارات هناك ، ولم يتم الاتصال بشيء منه ، لكن هذا جيد :)



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



في الواقع ، التغطية عادة لا تكون مائة بالمائة ، وعلاوة على ذلك ، لا ينبغي تحقيقها بكل الوسائل. بشكل ذاتي ، يبدو أن تغطية الاختبار بنسبة 60-70 ٪ كافية وطبيعية للعمل.



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



في pytest.ini قمت بتوصيل مكون إضافي واحد. هنا يمكنك أن ترى - flake8 ، هذا هو اللينت الذي يظهر أخطاء أسلوبي ، وبعضها الآخر ، ليس من PEP8 ، ولكن من البيرفلاكس.







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







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







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







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



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







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







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







يظهر هنا بوضوح. لقد قمنا باستيراده ، ونقول إن م وهمية. دعا مرة أخرى وهمية. قالوا أن m لديها طريقة f. دعا مرة أخرى وهمية. قالوا أن m هي السمة is_alive. عظيم ، عودة وهمية أخرى. ونلاحظ أنه تم استدعاء m و f ​​مرة واحدة. أي أنه كائن صعب ، حيث يتم إعادة كتابة طريقة getattr.







دعنا نلقي نظرة على مثال أوضح. دعنا نقول أن هناك AliveChecker. إنه يستخدم نوعًا من http_session ، ويحتاج إلى هدف ، ولديه وظيفة do_check تُرجع صواب أو خطأ ، اعتمادًا على ما حصل عليه: 200 أم لا 200. هذا مثال مصطنع قليلاً. لكن لنفترض أنه في الداخل ، يمكنك التحقق من المنطق المعقد.



لنفترض أننا لا نريد اختبار أي شيء عن الجلسة ، ولا نريد معرفة أي شيء عن طريقة get. نريد فقط اختبار do_check. رائع ، دعنا نختبرها.







يمكنك القيام بذلك على هذا النحو. http_session وهمية ، هنا يسمى pseudo_client. نحن نسخر من طريقة الحصول عليها ، ونقول أن get هو محاكاة ترجع 200. نطلق ، وننشئ AliveChecker من هذا ، ونطلقه. سيعمل هذا الاختبار.



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







مثال آخر. إنه مشابه جدًا للسابق. الشيء الوحيد هنا هو side_effect بدلاً من return_value. لكن هذا شيء تفعله السخرية. في هذه الحالة ، يطرح استثناء. تم تغيير سطر التأكيد لتأكيد عدم AliveChecker.do_check (). أي أننا نرى أن الشيك لن يمر.



هذان مثالان على كيفية اختبار وظيفة do_check دون معرفة أي شيء عما جاء بها من أعلى ، وما جاء في هذه الفئة.







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







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



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







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







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



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



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



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







كمثال - لقطة شاشة من TeamCity ، أحد CIs. يوجد تجميع ، تم الانتهاء منه بنجاح. كان هناك العديد من التغييرات فيه ، فقد تم إطلاقه على وكيل كذا وكذا في وقت كذا وكذا. هذا مثال عندما يكون كل شيء جيدًا ويمكنك أن تتدفق.



هناك العديد من أنظمة CI المختلفة. لقد كتبت قائمة ، إذا كنت مهتمًا ، فقم بإلقاء نظرة: AppVeyor ، و Jenkins ، و Travis ، و CircleCI ، و GoCD ، و Buildbot. شكر.






المحاضرات الأخرى لدورة الفيديو حول بايثون موجودة في منشور على حبري .



All Articles