كيف يمكنك اختبار/تغيير التعليمات البرمجية غير المختبرة وغير القابلة للاختبار؟

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

سؤال

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

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

المحلول

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

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

public class MyClass {
    public MyClass() {
        // undesirable DB logic
    }
}

يصبح

public class MyClass {
    public MyClass() {
        loadFromDB();
    }

    protected void loadFromDB() {
        // undesirable DB logic
    }
}

ومن ثم يبدو الاختبار الخاص بك كما يلي:

public class MyClassTest {
    public void testSomething() {
        MyClass myClass = new MyClassWrapper();
        // test it
    }

    private static class MyClassWrapper extends MyClass {
        @Override
        protected void loadFromDB() {
            // some mock logic
        }
    }
}

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

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

إنه نوع من الاختراق، لكنني وجدته مفيدًا جدًا.

نصائح أخرى

@فالترز

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

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

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

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

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

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

إذا كنت تكتب Java (هناك احتمالات)، فراجع ذلك http://www.easymock.org/ - قد يكون مفيدًا لتقليل الاقتران لأغراض الاختبار.

لقد قرأت العمل بفعالية مع Legacy Code، وأوافق على أنه مفيد جدًا للتعامل مع التعليمات البرمجية "غير القابلة للاختبار".

تنطبق بعض التقنيات فقط على اللغات المجمعة (أنا أعمل على تطبيقات PHP "القديمة")، لكنني أود أن أقول إن معظم الكتاب قابل للتطبيق على أي لغة.

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

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

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