يعمل عداء اختبار Bun بشكل جيد مع مكتبات اختبار المكونات و DOM الموجودة، بما في ذلك React Testing Library و happy-dom.
happy-dom
لكتابة اختبارات بدون واجهة لكود الواجهة الأمامية والمكونات، نوصي بـ happy-dom. يطبق Happy DOM مجموعة كاملة من واجهات برمجة تطبيقات HTML و DOM في جافا سكريبت عادي، مما يجعل من الممكن محاكاة بيئة المتصفح بدقة عالية.
للبدء، قم بتثبيت حزمة @happy-dom/global-registrator كتبعيات تطوير.
bun add -d @happy-dom/global-registratorسنستخدم وظيفة التحميل المسبق من Bun لتسجيل globals لـ happy-dom قبل تشغيل اختباراتنا. ستجعل هذه الخطوة واجهات برمجة تطبيقات المتصفح مثل document متاحة في النطاق العام. أنشئ ملفًا يسمى happydom.ts في جذر مشروعك وأضف الكود التالي:
import { GlobalRegistrator } from "@happy-dom/global-registrator";
GlobalRegistrator.register();لتحميل هذا الملف مسبقًا قبل bun test، افتح أو أنشئ ملف bunfig.toml وأضف الأسطر التالية.
[test]
preload = ["./happydom.ts"]سيتم تنفيذ happydom.ts عند تشغيل bun test. الآن يمكنك كتابة اختبارات تستخدم واجهات برمجة تطبيقات المتصفح مثل document و window.
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 التالي إلى أعلى أي ملف اختبار.
/// <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:
bun testbun 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 بشكل طبيعي.
bun add -d @testing-library/react @testing-library/jest-dom/// <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 المتقدم
العناصر المخصصة
يمكنك اختبار العناصر المخصصة ومكونات الويب باستخدام نفس الإعداد:
/// <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 وتفاعلات المستخدم:
/// <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 الأكثر تعقيدًا، يمكنك إنشاء ملف تحميل مسبق أكثر شمولاً:
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:
[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من مكتبات الاختبار
import { afterEach } from "bun:test";
import { cleanup } from "@testing-library/react";
afterEach(() => {
cleanup();
document.body.innerHTML = "";
});