Phpunit: يتم تنفيذ موفري البيانات قبل setupBeforeClass

تم إنشاؤها على ٢١ فبراير ٢٠١٣  ·  21تعليقات  ·  مصدر: sebastianbergmann/phpunit

يتم استدعاء موفري البيانات قبل تنفيذ setupBeforeClass الثابت. إذا كنت تعتقد أنه يجب أن يكون العكس.

حالة الاستخدام:

  • لدينا قائمة من المحولات. بعض المحولات مدعومة فقط في بعض البيئات (مثل Linux مقابل Win) ،
  • أرغب في تهيئة قائمة المحولات المدعومة مرة واحدة وتمريرها إلى جميع الاختبارات من خلال مزود البيانات ،
  • أنظف طريقة يمكنني تخيلها هي تهيئة خاصية ثابتة في setupBeforeClass وإرجاع المزود لتلك الخاصية

تكمن المشكلة في عدم تهيئة الخاصية عند استدعاء الموفر.

تم العثور على الإصدار: 3.7.14

التعليق الأكثر فائدة

epdenouden JIT؟ هل تختبر مع JIT من أجل PHP ، أم أن هناك شيئًا لا أعرفه؟ آسف ، أنا مرتبك قليلاً ؛ هل تتحدث عن PHP7.x و PHP8.x أم PHPUnit7.x و PHPUnit8.x ؟!

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

سيعمل هذا بشكل جيد مع إصدار PHP 8 JIT القادم لأنه لا يستخدم أي ميزات صعبة للغة PHP نفسها. كل عملي في عمق PHPUnit يعيد إجراء أشياء مثل تحليل التكوين واختبار التحميل والتشغيل وما إلى ذلك.

إذا بدا أنني لا أفعل أي شيء ، فأنا أفعله بشكل صحيح. باستثناء فاتورة GCP أو AWS المخفضة. 💸

ال 21 كومينتر

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

لماذا لا تقوم فقط بتهيئة المحولات كسول؟ ثم الترتيب لا يهم على الإطلاق.

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

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

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

شكرا لردودك ، إغلاق القضية.

vicb ، سأقوم بكل سرور بدمج العلاقات العامة المتعلقة بالوثائق لهذا الغرض.

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

srosato أنا غبية (لم أستخدم العائد). هل يمكنك إعطاء مثال موجز عن كيفية القيام بذلك من فضلك؟ عبر https://gist.github.com إذا كان أحد الأمثلة هنا غير مناسب.

إذا كان @dataProvider يتطلب رمز الإعداد ولم تكن كبيرة بشكل رهيب ، فيمكنك تحديدها كسلاسل و eval في الاختبار. على سبيل المثال:

public function myProvider() {
    return [
        'new Klass("param 1", "param 2")',
        'new Klass("param 1", "param 2")',
    ];
}

/**
 * <strong i="8">@dataProvider</strong> myProvider
 */
public testMyFunction($instance_str) {
    $klass = eval("return {$instance_str};");
    # continue testing $klass ...
}

سنتى:

بدلاً من الاعتماد على مزود البيانات على خاصية ثابتة (والتي نعلم أنها غير ممكنة) ، أقوم بتعيين البيانات / الكائنات المطلوبة كأعضاء في فئة (أعضاء) فئة الاختبار في طريقة setUp() .
في tearDown() قمت بضبطها على قيمة خالية ، أو عندما تكون هناك كائنات معقدة ، أقوم بتطبيق طريقة clear() لها.

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

على وجه التحديد ، أستخدم اتصال DB كخاصية ثابتة تم تعيينها في setUpBeforeClass() وتعيين $queryBuilder ، والذي يحصل على الاتصال المحقون ، كعضو في الفصل في setUp() (بدلاً من إعادته في dataprovider).

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

شاهده في مثال:

private static function getData()
{
    static $data, $anotherData;

    if (!isset($data)) {
        $data = new TestClass();
        $anotherData = [];
    }

    return [
        $data,
        // Or: clone $data
        $anotherData,
    ];
}

public static function setUpBeforeClass()
{
    list(self::$sampleJson, self::$sampleData) = self::getData(); 
}

public function sampleProvider()
{
    $data = self::getData();

    return [
        $data
    ];
}

MAChitgarha بفضل تعليقك بالأمس اكتشفت هذه التذكرة. :)

أنا أعمل على إعادة هيكلة منطق موفر البيانات في # 3736 والذي سيحل بعض المشكلات الشائعة:

  • لم يعد هناك هذا الارتفاع الهائل في النشاط في بداية التشغيل حيث يتم تحميل جميع مزودي البيانات
  • يمكن لموفري البيانات العمل بعد التركيبات setUpBeforeClass و setUp
  • يصبح مقدمو البيانات غير الثابتة ممكنًا
  • ستكون المولدات أكثر كفاءة

@ epdenouden سعيد سماع ذلك! ؛) العنصر الثاني في قائمتك هو عنصر جيد. في انتظار ذلك.

يصبح مقدمو البيانات غير الثابتة ممكنًا

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

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

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

private static function getDataFromDataProviderAnnotation($allTheParameters): ?iterable
    // code for locating the data provider
    // [...]
                if ($dataProviderMethod->isStatic()) {
                    $object = null;
                } else {
                    $object = $dataProviderClass->newInstance();
                }

    // code for preparing returned data rows
    // [...]
}

إذن هذا هو السر الصغير القذر:

  • يمكنك استخدام موفري البيانات غير الثابتة و
  • سيتم استدعاؤهم على instanceof لكن ...
  • إنه _ليس نفس المثال_ الذي يتم استخدامه للتركيبات والاختبارات

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

@ epdenouden لكني لا أحصل على أي إخفاقات! في PHPUnit 7.5.13 ، لا يولد التأكيد أي أخطاء. كيف تحصل على هذا الخطأ؟ عدم التوافق مع الإصدارات السابقة ، تقصد؟

هذا في فرع مزود بيانات التحميل البطيء الذي أعمل عليه والذي يعتمد على 8.2. سوف أتحقق من 7.5.x بعد ذلك ، شكرًا على التنبيه.

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

على أي حال: لقد ألهم تعليقك بالفعل اختبارًا مفيدًا للغاية :)

و MAChitgarha نعم سيكون هذا فاصل قبل الميلاد

@ epdenouden سأنتظر ذلك. لبعض الأسباب ، في مشروعي ، أستخدم PHPUnit 7.5.13 ؛ لكنني سأقوم بتحديثه إلى 8.2. * قريبًا. والخبر السار ، إذا كان من الممكن إصلاح فاصل BC. لا أعرف بنية PHPUnit نفسها ، لذلك لا أعرف ما الذي قمت بتغييره ، لكن أعتقد أنه من الممكن إصلاحه. ومع ذلك ، فإن الأمر كله متروك لك! :)

والخبر السار ، إذا كان من الممكن إصلاح فاصل BC. لا أعرف بنية PHPUnit نفسها ، لذلك لا أعرف ما الذي قمت بتغييره ، لكن أعتقد أنه من الممكن إصلاحه. ومع ذلك ، فإن الأمر كله متروك لك! :)

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

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

حقيقة ممتعة: الاختبار أعلاه يعمل بالفعل على كلا الإصدارين 7.x و 8.x وفشل في نموذج JIT الأولي.

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

epdenouden JIT؟ هل تختبر مع JIT من أجل PHP ، أم أن هناك شيئًا لا أعرفه؟ آسف ، أنا مرتبك قليلاً ؛ هل تتحدث عن PHP7.x و PHP8.x أم PHPUnit7.x و PHPUnit8.x ؟!

epdenouden JIT؟ هل تختبر مع JIT من أجل PHP ، أم أن هناك شيئًا لا أعرفه؟ آسف ، أنا مرتبك قليلاً ؛ هل تتحدث عن PHP7.x و PHP8.x أم PHPUnit7.x و PHPUnit8.x ؟!

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

سيعمل هذا بشكل جيد مع إصدار PHP 8 JIT القادم لأنه لا يستخدم أي ميزات صعبة للغة PHP نفسها. كل عملي في عمق PHPUnit يعيد إجراء أشياء مثل تحليل التكوين واختبار التحميل والتشغيل وما إلى ذلك.

إذا بدا أنني لا أفعل أي شيء ، فأنا أفعله بشكل صحيح. باستثناء فاتورة GCP أو AWS المخفضة. 💸

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات