Vitest 5 vs Jest مقارنة

مُشغّل اختبارات native لـ ESM/TS بسرعة Vite نفسها

VS
Jest

ناضج منذ 13 عامًا، وهو الخيار الافتراضي في React Native

17 دقائق للقراءةالأدوات

الحكم السريع

في مشروع جديد مبني على Vite أو Nuxt، يجب أن يكون Vitest هو الخيار الافتراضي: فأنت تشارك نفس ملف `vite.config.js`. في Next.js يبقى الإعداد منفصلاً (مترجمه ليس Vite)، لكنك تحصل على دعم native لـ ESM/TypeScript دون تثبيت حزمة تحويل إضافية. لكن إذا كانت لديك مجموعة اختبارات Jest كبيرة وتعمل بشكل جيد، خصوصًا إذا كنت تعتمد على React Native/Metro، فقد تتجاوز تكلفة الترحيل فائدته. اختر الطريق الثالث: اكتب الاختبارات الجديدة بـ Vitest، واترك المجموعة الحالية في Jest — يمكن للاثنين التعايش في نفس المونوريبو.

Vitest 5Jest
اقرأ الخلاصة كاملة

مقارنة الدرجات

جارٍ تحميل الرسم البياني...

التقييم التفصيلي

التقييم التفصيلي: Vitest 5 و Jest — درجات كل فئة من 10
الفئةVitest 5Jest
الأداء
9/10
7/10
سهولة التعلّم
7/10
7/10
النظام البيئي
6/10
9/10
المجتمع
6/10
9/10
سوق العمل
6/10
8/10
الاستدامة المستقبلية
9/10
6/10

الإيجابيات والسلبيات

Vitest 5

الإيجابيات

  • يشارك نفس ملف vite.config.js مع التطبيق، دون الحاجة إلى طبقة تحويل منفصلة
  • حزمة native ESM ("type": "module")، دون الحاجة إلى علامة تجريبية
  • مكاسب سرعة تتراوح بين 8%-53% حسب السيناريو في القياسات الرسمية لـ Vitest 5 (الفرق ±3% في بعض الإعدادات)
  • وضع متصفح (Browser Mode) أصلي + عرض Trace View جديد في Vitest 5
  • واجهة برمجية للـ mocking تشبه Jest (vi.fn/vi.mock) + دالة vi.when الجديدة للـ mock الشرطي
  • دعم أكثر دقة للمونوريبو عبر وراثة المشاريع المتداخلة (nested project inheritance)
  • مشروع ينمو بسرعة بأكثر من 790 مساهمًا، ويدعمه فريق Vite

السلبيات

  • يتطلب Node 22.12+ / 24.x / 26+ إلزاميًا — الإصدارات الوسيطة (23.x، 25.x) غير مدعومة
  • في Yarn أصبح vite الآن peer dependency، وإذا لم يُثبَّت يدويًا لا يمكن حل الحزمة
  • لا يوجد دعم أصلي (first-party) لـ React Native/Metro
  • عدد نجوم GitHub (17,151) يقارب ثلث عدد نجوم Jest — النظام البيئي أحدث عمرًا
  • تغييرات السلوك في Vitest 5 (clearMocks، إلزامية vi.mock على المستوى الأعلى) قد تسبب أعطالًا صامتة

الأنسب لـ

مشاريع الويب الجديدة المبنية على Vite أو Next.js أو Nuxtالفرق التي تكتب اختبارات على مستوى المكوّنات/المتصفحالمونوريبو التي تريد مشاركة إعداد Vite نفسهالمشاريع التي يكون فيها وضع watch السريع/زمن CI أمرًا بالغ الأهميةقواعد الأكواد التي تعتمد بشكل كبير على native ESM + TypeScript

Jest

الإيجابيات

  • تغطية (coverage) دون حاجة لإعداد إضافي، بعلامة واحدة فقط --coverage
  • دعم واسع لإصدارات Node (بدءًا من ^18.14)
  • إطار الاختبار المُضمَّن في القالب الافتراضي لـ React Native؛ ووجود إعداد jest-expo الرسمي في Expo
  • نظام بيئي أكبر بنحو 2.65 مرة من Vitest بـ45,467 نجمة على GitHub
  • دعم المونوريبو متعدد الحزم عبر علامة --projects
  • معمارية ناضجة توازي الاختبارات كلٌّ في عملية (process) خاصة بها
  • بدأ في الإصدار 30.5.2 بتقليل عبء التحويل عبر دعم TS-strip المدمج في Node

السلبيات

  • دعم ESM ما زال رسميًا "تجريبيًا" — يتطلب علامة إضافية وإعداد تحويل يدوي
  • يجب تثبيت حزم تحويل منفصلة (babel-jest/ts-jest) لـ TypeScript/JS الحديث
  • لا يشارك إعداد Vite — في المشروع المبني على Vite يوجد إعدادان منفصلان
  • لا توجد ميزة وضع متصفح أو اختبار مكوّنات أصلية (first-party)

الأنسب لـ

تطبيقات React Native / Expoالمشاريع التي لديها مجموعة اختبارات Jest كبيرة وقائمة وتعمل بشكل جيدبيئات CI المثبّتة على إصدار Node قديمقواعد الأكواد المعتمدة على سلسلة Babel/transformer مخصصةالفرق التي تهتم بالاستدامة المؤسسية تحت مظلة OpenJS Foundation

مقارنة الكود

Vitest 5
// Vitest 5 - اختبار الدالة التي تحسب إجمالي السلة
// vitest.config.ts يشارك vite.config.ts؛ لا حاجة لطبقة تحويل إضافية
import { describe, it, expect, vi } from 'vitest'
import { calculateCartTotal } from './cart'
import { fetchDiscount } from './discount-api'

vi.mock('./discount-api')

describe('calculateCartTotal', () => {
  // Vitest 5: clearMocks افتراضيًا true، لا حاجة لاستدعاء تنظيف إضافي
  it('indirim kodu olmadan ara toplami dogru hesaplar', () => {
    const items = [
      { price: 129.9, qty: 2 },
      { price: 49.5, qty: 1 },
    ]
    expect(calculateCartTotal(items)).toBeCloseTo(309.3, 2)
  })

  it('gecerli indirim kodunda vi.when ile kosullu mock kullanir', async () => {
    // Vitest 5 API جديد: سلوك mock مختلف حسب الوسيطة (argument)
    vi.when(fetchDiscount).calledWith('SEPET10').thenResolve({ percent: 10 })
    vi.when(fetchDiscount).calledWith('GECERSIZ').thenReject(new Error('invalid code'))

    const items = [{ price: 100, qty: 1 }]
    const total = await calculateCartTotal(items, 'SEPET10')

    expect(total).toBeCloseTo(90, 2)
    expect(fetchDiscount).toHaveBeenCalledWith('SEPET10')
  })

  it('gecersiz kod hata firlatir', async () => {
    vi.when(fetchDiscount).calledWith('GECERSIZ').thenReject(new Error('invalid code'))
    const items = [{ price: 100, qty: 1 }]

    await expect(calculateCartTotal(items, 'GECERSIZ')).rejects.toThrow('invalid code')
  })
})

// Monorepo: vitest -p web --coverage (فقط مشروع 'web' + تقرير التغطية)
Jest
// Jest 30 - اختبار الدالة التي تحسب إجمالي السلة
// يجب أن تكون سلسلة تحويل babel.config.js أو ts-jest مُعدة مسبقًا
const { calculateCartTotal } = require('./cart')
const { fetchDiscount } = require('./discount-api')

jest.mock('./discount-api')

describe('calculateCartTotal', () => {
  afterEach(() => {
    jest.clearAllMocks() // ليست افتراضية في Jest، تُستدعى يدويًا
  })

  it('indirim kodu olmadan ara toplami dogru hesaplar', () => {
    const items = [
      { price: 129.9, qty: 2 },
      { price: 49.5, qty: 1 },
    ]
    expect(calculateCartTotal(items)).toBeCloseTo(309.3, 2)
  })

  it('gecerli indirim kodunda mockResolvedValue kullanir', async () => {
    fetchDiscount.mockImplementation((code) => {
      if (code === 'SEPET10') return Promise.resolve({ percent: 10 })
      return Promise.reject(new Error('invalid code'))
    })

    const items = [{ price: 100, qty: 1 }]
    const total = await calculateCartTotal(items, 'SEPET10')

    expect(total).toBeCloseTo(90, 2)
    expect(fetchDiscount).toHaveBeenCalledWith('SEPET10')
  })

  it('gecersiz kod hata firlatir', async () => {
    fetchDiscount.mockRejectedValue(new Error('invalid code'))
    const items = [{ price: 100, qty: 1 }]

    await expect(calculateCartTotal(items, 'GECERSIZ')).rejects.toThrow('invalid code')
  })
})

// شغّل حزمة 'web' فقط في المونوريبو باستخدام jest --projects packages/web --coverage

الخلاصة

في مشروع جديد مبني على Vite أو Nuxt، يجب أن يكون Vitest هو الخيار الافتراضي: فأنت تشارك نفس ملف `vite.config.js`. في Next.js يبقى الإعداد منفصلاً (مترجمه ليس Vite)، لكنك تحصل على دعم native لـ ESM/TypeScript دون تثبيت حزمة تحويل إضافية. لكن إذا كانت لديك مجموعة اختبارات Jest كبيرة وتعمل بشكل جيد، خصوصًا إذا كنت تعتمد على React Native/Metro، فقد تتجاوز تكلفة الترحيل فائدته. اختر الطريق الثالث: اكتب الاختبارات الجديدة بـ Vitest، واترك المجموعة الحالية في Jest — يمكن للاثنين التعايش في نفس المونوريبو.

احصل على استشارة مجانية
الأسئلة الشائعة

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

لا، لا يحل محله تمامًا. كلاهما قيد التطوير النشط في سبتمبر 2026: Vitest 5.0 (3 سبتمبر 2026) وJest 30.5.2 (18 سبتمبر 2026). في المشاريع المبنية على Vite وNuxt، يكون عبء الإعداد أقل في Vitest لأنه يعيد استخدام خط تحويل التطبيق نفسه؛ بينما يستمر Jest خصوصًا في React Native/Metro وقواعد الأكواد الكبيرة القائمة.

مقالات مدونة ذات صلة

عرض جميع المقالات

مشاريع ذات صلة

عرض جميع المشاريع
جميع المقارنات