0Pricing
Vue Academy · درس

اختبار تفاعلات المستخدم والأحداث

‏wrapper.trigger('click') وsetValue() وwrapper.vm.$emit() وasync flushPromises()

اختبار تفاعلات المستخدم والأحداث درس مجاني في Vue Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Vue Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Vue Academy 4 دروس في المجموع.

محاكاة سلوك المستخدم

لا ينبغي أن تقتصر الاختبارات على العرض، بل يجب أن تحاكي ما يفعله المستخدم: النقر على الأزرار، والكتابة في حقول الإدخال، وإرسال النماذج. توفّر أغلفة @vue/test-utils أساليب لإطلاق أحداث DOM وتحديث Vue بعد ذلك.

trigger لأحداث النقر

تطلق wrapper.trigger("click") حدث نقر على العنصر. ولأنها تحدّث DOM، فإنها تعيد وعدًا، لذا استخدم await معها حتى ترى التأكيدات النتيجة.

const button = wrapper.get("button")
await button.trigger("click")
expect(wrapper.text()).toContain("Clicked once")

لماذا الاختبارات غير متزامنة؟

تحدّث Vue DOM بشكل غير متزامن. بعد التفاعل، لا تظهر الحالة الجديدة حتى دورة التحديث التالية. يتيح انتظار وعد trigger استقرار DOM قبل إجراء التأكيد.

it("increments on click", async () => {
  const wrapper = mount(Counter)
  await wrapper.get("button").trigger("click")
  expect(wrapper.get(".count").text()).toBe("1")
})

setValue لحقول الإدخال

للكتابة في حقل، استخدم wrapper.setValue(value) على wrapper الخاص بحقل الإدخال. تضبط هذه الدالة القيمة وتطلق حدث input حتى يُحدّث v-model قيمته.

const input = wrapper.get("input")
await input.setValue("hello@example.com")
expect(input.element.value).toBe("hello@example.com")

خانات الاختيار والقوائم المنسدلة

تتكيف setValue مع العنصر: مرّر قيمة منطقية لخانات الاختيار، وقيمة الخيار للقائمة المنسدلة.

await wrapper.get("input[type=checkbox]").setValue(true)
await wrapper.get("select").setValue("tr")

التأكد من الأحداث المُطلقة

تتواصل المكوّنات مع المكوّنات الأعلى عبر الأحداث المُطلقة. تعيد wrapper.emitted() سجلًا بكل حدث أطلقه المكوّن، مع تجميعه حسب الاسم.

await wrapper.get("button").trigger("click")
expect(wrapper.emitted()).toHaveProperty("submit")

فحص البيانات المحمولة للأحداث المُطلقة

تعيد wrapper.emitted("name") مصفوفة من مصفوفات الوسائط لكل عملية إطلاق. وتكون الوسيطة الأولى في عملية الإطلاق الأولى هي emitted("name")[0][0].

await wrapper.get("button").trigger("click")
const events = wrapper.emitted("submit")
expect(events).toHaveLength(1)
expect(events[0][0]).toEqual({ email: "a@b.com" })

اختبار إرسال نموذج

اجمع الأجزاء معًا: املأ حقلًا، وأرسل النموذج، ثم تحقّق من البيانات المحمولة المُطلقة.

it("emits submit with the email", async () => {
  const wrapper = mount(LoginForm)
  await wrapper.get("input").setValue("a@b.com")
  await wrapper.get("form").trigger("submit.prevent")
  expect(wrapper.emitted("submit")[0][0]).toEqual({ email: "a@b.com" })
})

العمليات غير المتزامنة في المكوّنات

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

async function load() {
  loading.value = true
  data.value = await fetchData()
  loading.value = false
}

flushPromises

تحل flushPromises من Test Utils جميع المهام الدقيقة المعلّقة، أي دوال then اللاحقة. انتظرها بعد تشغيل إجراء غير متزامن حتى تُطبَّق الوعود المكتملة وتحديثات DOM الناتجة عنها.

import { flushPromises } from "@vue/test-utils"

await wrapper.get("button").trigger("click")
await flushPromises()
expect(wrapper.text()).toContain("Loaded")

جمع الاختبارات غير المتزامنة

النمط هو: التركيب، والتفاعل، ثم await flushPromises()، ثم التأكيد. اجعل دالة الاختبار async حتى تتمكن من استخدام await في جميع مراحلها.

it("shows results after fetch", async () => {
  const wrapper = mount(SearchBox)
  await wrapper.get("input").setValue("vue")
  await wrapper.get("form").trigger("submit.prevent")
  await flushPromises()
  expect(wrapper.findAll("li")).toHaveLength(2)
})

تحقق سريع

تحقق من فهمك لاختبار التفاعلات.

مراجعة

تعلمت اختبار التفاعلات والأحداث:

  • تطلق trigger("click") الأحداث؛ انتظرها لأن Vue تحدّث DOM بشكل غير متزامن.
  • تضبط setValue قيم حقول الإدخال وخانات الاختيار والقوائم المنسدلة، وتطلق أحداث input لصالح v-model.
  • يسجّل wrapper.emitted() الأحداث المُطلقة؛ وتقرأ emitted("name")[0][0] البيانات المحمولة الأولى.
  • بالنسبة إلى المعالجات غير المتزامنة، استخدم await flushPromises() قبل إجراء التأكيد.
  • اجعل الاختبارات async حتى تتمكن من استخدام await.

الأسئلة الشائعة

هل درس «اختبار تفاعلات المستخدم والأحداث» مجاني؟

نعم — نص درس «اختبار تفاعلات المستخدم والأحداث» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Vue Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Vue Academy 4 دروس في المجموع.

ماذا ستتعلم في «اختبار تفاعلات المستخدم والأحداث»؟

‏wrapper.trigger('click') وsetValue() وwrapper.vm.$emit() وasync flushPromises() تتمرن على Vue Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Vue Academy؟

لا تُشترط خبرة سابقة. Vue Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «اختبار تفاعلات المستخدم والأحداث»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Vue Academy هذا؟

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

جميع الدروس في هذه الدورة

  1. إعداد Vitest لمشاريع Vue
  2. تركيب المكوّنات والاستعلام عنها
  3. اختبار تفاعلات المستخدم والأحداث
  4. محاكاة Composables وStores وواجهات API
← العودة إلى Vue Academy