Skip to content

يعمل عداء اختبار Bun بشكل جيد مع مكتبات اختبار المكونات و DOM الموجودة، بما في ذلك React Testing Library و happy-dom.

happy-dom

لكتابة اختبارات بدون واجهة لكود الواجهة الأمامية والمكونات، نوصي بـ happy-dom. يطبق Happy DOM مجموعة كاملة من واجهات برمجة تطبيقات HTML و DOM في جافا سكريبت عادي، مما يجعل من الممكن محاكاة بيئة المتصفح بدقة عالية.

للبدء، قم بتثبيت حزمة @happy-dom/global-registrator كتبعيات تطوير.

bash
bun add -d @happy-dom/global-registrator

سنستخدم وظيفة التحميل المسبق من Bun لتسجيل globals لـ happy-dom قبل تشغيل اختباراتنا. ستجعل هذه الخطوة واجهات برمجة تطبيقات المتصفح مثل document متاحة في النطاق العام. أنشئ ملفًا يسمى happydom.ts في جذر مشروعك وأضف الكود التالي:

happydom.ts
ts
import { GlobalRegistrator } from "@happy-dom/global-registrator";

GlobalRegistrator.register();

لتحميل هذا الملف مسبقًا قبل bun test، افتح أو أنشئ ملف bunfig.toml وأضف الأسطر التالية.

bunfig.toml
toml
[test]
preload = ["./happydom.ts"]

سيتم تنفيذ happydom.ts عند تشغيل bun test. الآن يمكنك كتابة اختبارات تستخدم واجهات برمجة تطبيقات المتصفح مثل document و window.

dom.test.ts
ts
import { test, expect } from "bun:test";

test("اختبار dom", () => {
  document.body.innerHTML = `<button>زرّي</button>`;
  const button = document.querySelector("button");
  expect(button?.innerText).toEqual("زرّي");
});

دعم TypeScript

اعتمادًا على إعداد tsconfig.json الخاص بك، قد ترى خطأ نوع "Cannot find name 'document'" في الكود أعلاه. لـ "حقن" الأنواع لـ document وواجهات برمجة تطبيقات المتصفح الأخرى، أضف توجيه triple-slash التالي إلى أعلى أي ملف اختبار.

dom.test.ts
ts
/// <reference lib="dom" />

import { test, expect } from "bun:test";

test("اختبار dom", () => {
  document.body.innerHTML = `<button>زرّي</button>`;
  const button = document.querySelector("button");
  expect(button?.innerText).toEqual("زرّي");
});

دعنا نشغل هذا الاختبار مع bun test:

bash
bun test
bun test v1.3.3

dom.test.ts:
✓ اختبار dom [0.82ms]

 1 اجتاز
 0 فشل
 1 استدعاءات expect()
تم تشغيل 1 اختبار عبر 1 ملف. 1 إجمالي [125.00ms]

React Testing Library

يعمل Bun بسلاسة مع React Testing Library لاختبار مكونات React. بعد إعداد happy-dom كما هو موضح أعلاه، يمكنك تثبيت واستخدام React Testing Library بشكل طبيعي.

bash
bun add -d @testing-library/react @testing-library/jest-dom
component.test.tsx
ts
/// <reference lib="dom" />

import { test, expect } from 'bun:test';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';

function Button({ children }: { children: React.ReactNode }) {
  return <button>{children}</button>;
}

test('يعرض الزر', () => {
  render(<Button>انقرني</Button>);
  expect(screen.getByRole('button')).toHaveTextContent('انقرني');
});

اختبار DOM المتقدم

العناصر المخصصة

يمكنك اختبار العناصر المخصصة ومكونات الويب باستخدام نفس الإعداد:

custom-element.test.ts
ts
/// <reference lib="dom" />

import { test, expect } from "bun:test";

test("عنصر مخصص", () => {
  // تعريف عنصر مخصص
  class MyElement extends HTMLElement {
    constructor() {
      super();
      this.innerHTML = "<p>محتوى العنصر المخصص</p>";
    }
  }

  customElements.define("my-element", MyElement);

  // استخدامه في الاختبارات
  document.body.innerHTML = "<my-element></my-element>";
  const element = document.querySelector("my-element");
  expect(element?.innerHTML).toBe("<p>محتوى العنصر المخصص</p>");
});

اختبار الأحداث

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

events.test.ts
ts
/// <reference lib="dom" />

import { test, expect } from "bun:test";

test("حدث نقر الزر", () => {
  let clicked = false;

  document.body.innerHTML = '<button id="test-btn">انقرني</button>';
  const button = document.getElementById("test-btn");

  button?.addEventListener("click", () => {
    clicked = true;
  });

  button?.click();
  expect(clicked).toBe(true);
});

نصائح التكوين

الإعداد العام

لإعدادات اختبار DOM الأكثر تعقيدًا، يمكنك إنشاء ملف تحميل مسبق أكثر شمولاً:

test-setup.ts
ts
import { GlobalRegistrator } from "@happy-dom/global-registrator";
import "@testing-library/jest-dom";

// تسجيل globals لـ happy-dom
GlobalRegistrator.register();

// أضف أي تكوين اختبار عام هنا
global.ResizeObserver = class ResizeObserver {
  observe() {}
  unobserve() {}
  disconnect() {}
};

// محاكاة واجهات برمجة التطبيقات الأخرى حسب الحاجة
Object.defineProperty(window, "matchMedia", {
  writable: true,
  value: jest.fn().mockImplementation(query => ({
    matches: false,
    media: query,
    onchange: null,
    addListener: jest.fn(),
    removeListener: jest.fn(),
    addEventListener: jest.fn(),
    removeEventListener: jest.fn(),
    dispatchEvent: jest.fn(),
  })),
});

ثم قم بتحديث bunfig.toml:

bunfig.toml
toml
[test]
preload = ["./test-setup.ts"]

استكشاف الأخطاء

المشاكل الشائعة

أخطاء TypeScript لواجهات برمجة تطبيقات DOM: تأكد من تضمين توجيه /// <reference lib="dom" /> في أعلى ملفات الاختبار الخاصة بك.

globals مفقودة: تأكد من استيراد @happy-dom/global-registrator وتسجيله بشكل صحيح في ملف التحميل المسبق الخاص بك.

مشاكل عرض مكونات React: تأكد من تثبيت @testing-library/react وإعداد happy-dom بشكل صحيح.

اعتبارات الأداء

Happy-dom سريع، ولكن لمجموعات الاختبار الكبيرة جدًا، قد ترغب في:

  • استخدام beforeEach لإعادة تعيين حالة DOM بين الاختبارات
  • تجنب إنشاء الكثير من عناصر DOM في اختبار واحد
  • التفكير في استخدام دوال cleanup من مكتبات الاختبار
test-setup.ts
ts
import { afterEach } from "bun:test";
import { cleanup } from "@testing-library/react";

afterEach(() => {
  cleanup();
  document.body.innerHTML = "";
});

Bun بواسطة www.bunjs.com.cn تحرير