كتابة اختبارات القبول واختبارات المكونات لكود Ember في Discourse

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

لحسن الحظ، أصبح من السهل جدًا في هذه الأيام إضافة اختبارات أساسية إلى تعليمات Ember البرمجية الخاصة بك!

اختبارات المكونات (Component Tests)

في البرنامج التعليمي السابق في هذه السلسلة، أضفنا مكونًا يسمى fancy-snack لعرض الوجبة الخفيفة الخاصة بنا بخلفية متلاشية. لنكتب اختبارًا له. أنشئ الملف التالي:

test/javascripts/components/snack-test.js

import componentTest from "helpers/component-test";

moduleForComponent("fancy-snack", { integration: true });

componentTest("test the rendering", {
  template: "{{fancy-snack snack=testSnack}}",

  setup() {
    this.set("testSnack", {
      name: "Potato Chips",
      description: "Now with extra trans fat!",
    });
  },

  test(assert) {
    assert.equal(this.$(".fancy-snack-title h1").text(), "Potato Chips");
    assert.equal(
      this.$(".fancy-snack-description p").text(),
      "Now with extra trans fat!"
    );
  },
});

لتشغيل الاختبار، افتح متصفحك على خادم التطوير الخاص بك على العنوان /qunit?module=component%3Afancy-snack. سيقوم متصفحك بعد ذلك بإجراء اختبارات المكونات وإخراج شيء مثل “2 assertions of 2 passed, 0 failed.” (تم اجتياز تأكيدين من أصل 2، فشل 0).

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

دعنا نمر عبر الاختبار لفهم كيفية عمله.

يشير السطر template إلى Ember كيف نود إدراج المكون الخاص بنا. إنه نفس الترميز الدقيق الذي ستستخدمه لوضع المكون في قالب handlebars لذا يجب أن يكون مألوفًا:

template: '{{fancy-snack snack=testSnack}}',

لاحظ أنه يمرر testSnack كمعامل snack. يتم تعريف ذلك في الطريقة setup():

setup() {
  this.set('testSnack', {
    name: 'Potato Chips',
    description: 'Now with extra trans fat!'
  });
},

لقد وضعت للتو بعض البيانات الوهمية. هذا كل ما نحتاجه لجعل Ember يعرض المكون. أخيرًا، لدينا زوج من التأكيدات في الطريقة test():

test(assert) {
  assert.equal(this.$('.fancy-snack-title h1').text(), 'Potato Chips');
  assert.equal(this.$('.fancy-snack-description p').text(), 'Now with extra trans fat!');
}

إذا استخدمت this.$() فإنك تحصل على إمكانية الوصول إلى محدد jQuery في القالب الخاص بك. تستخدم التأكيدات هنا هذا المحدد للحصول على قيمة عنوان الوجبة الخفيفة ووصف الوجبة الخفيفة ومقارنتها بما نتوقعه. إذا تطابقت القيم فستمر التأكيدات ويكون اختبارنا يعمل بالكامل.

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

اختبارات القبول (Acceptance Tests)

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

إليك كيف يمكننا كتابة اختبار قبول سيزور مسارنا /admin/snack ويؤكد أنه تم عرض الوجبة الخفيفة:

test/javascripts/acceptance/snack-test.js

import { acceptance } from "helpers/qunit-helpers";
acceptance("Snack");

test("Visit Page", function (assert) {
  visit("/admin/snack");
  andThen(() => {
    assert.ok(exists(".fancy-snack-title"), "the snack title is present");
  });
});

تبدو test() في هذه الحالة وكأنها قراءة باللغة الإنجليزية! يقول الأمر الأول قم بزيارة عنوان URL لـ /admin/snack. بعد ذلك، هناك طريقة andThen(). هذه الطريقة ضرورية للتأكد من اكتمال جميع الأعمال الخلفية قبل استمرار الاختبارات. نظرًا لأن Javascript و Ember code غير متزامن، نحتاج إلى التأكد من أن Ember قد انتهى من كل ما يحتاج إلى القيام به قبل تنفيذ تأكيداتنا. أخيرًا، يختبر ما إذا كان العنصر .fancy-snack-title موجودًا.

ومع ذلك، إذا قمت بتشغيل هذا الاختبار عن طريق زيارة /qunit?module=Acceptance%3A%20Snack فستجد أن الاختبار سيفشل، بسبب خطأ AJAX.

إذا تذكرت، فإن التعليمات البرمجية الخاصة بنا تتضمن جانب Rails وجانب Javascript قام بتنفيذ طلب AJAX للحصول على بياناته. قام اختبار القبول بتشغيل جانب Javascript، لكنه لم يعرف ماذا يفعل للحصول على بياناته من Rails.

لإصلاح هذا، نحتاج إلى إضافة استجابة وهمية، باستخدام مكتبة pretender الممتازة. افتح الملف test/javascripts/helpers/create-pretender.js وابحث عن السطر الذي يقول:

this.get("/admin/plugins", () => response({ plugins: [] }));

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

this.get("/admin/snack.json", () => {
  return response({ name: "snack name", description: "snack description" });
});

يمكنك قراءة التعليمات البرمجية أعلاه على أنها “لأي طلب إلى /admin/snack.json، استجب بـ response التالي.”

إذا قمت بتحديث عنوان URL /qunit?module=Acceptance%3A%20Snack، يجب أن يسترد اختبار القبول الخاص بك بياناته عبر pretender ويجب أن تمر الاختبارات.

إلى أين تذهب من هنا

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


يتم التحكم في إصدار هذه الوثيقة - اقترح تغييرات على github.

15 إعجابًا

My prior experience in writing qunit tests was based on the other howto

i.e. “acceptance” was simply

acceptance("Purple Tentacle", { loggedIn: true });

I have seen in other plugins where the test code contained “fake” JSON to test against. I wasn’t sure if that would be as good as testing against “real” data, so I wanted to avoid doing it that way.

The six tests passed, but I got a couple of rather angry looking “unhandled request” errors.

After finding an example of some “setup” code, I tried it and it solved the errors.

It works, but I’m not really sure why, nor why it’s needed for some but not for the majority of plugins I’ve seen that have qunit tests.

3 إعجابات

For a long time we weren’t great with testing plugins, so not many people followed our example and added tests.

You are right to add a response using pretender to handle AJAX calls.

4 إعجابات

ملاحظة فقط بأن المسار /qunit لم يعد مستخدماً. إنه /tests الآن. استغرق الأمر مني بعض الوقت لفهم ذلك :slight_smile:

إعجاب واحد (1)