مرحبا بالجميع! تبدأ دورة
JavaScript Developer هذا الخميس. في هذا الصدد ، قررنا مشاركة ترجمة مواد أخرى مثيرة للاهتمام. هل لديك قراءة جيدة.

لقد كان
Jest دائمًا أداة اختبار الوحدة التي لا غنى عنها. يمكن الاعتماد عليها لدرجة أنني بدأت أفكر في أني لم أستخدمها بشكل كافٍ. على الرغم من أن الاختبارات قد نجحت ، إلا أنني مع مرور الوقت أعيد بناؤها هنا وهناك ، لأنني لم أكن أعرف أن Jest يمكنه فعل ذلك. في كل مرة يكون هذا رمزًا جديدًا عندما أتحقق من وثائق Jest.
لذا ، سأشارك بعضًا من خدع Jest المفضلة التي قد يعرفها بعضكم بالفعل لأنك قرأت الوثائق وليس مثلي (العار) ، ولكني آمل أن يساعد ذلك أولئك الذين مروا بها بسرعة !
بالمناسبة ، أستخدم Jest v24.8.0 كمواد مرجعية ، لذا كن حذراً ، قد لا تعمل بعض الأشياء على إصدار Jest الذي تستخدمه حاليًا. بالإضافة إلى ذلك ، لا تمثل الأمثلة رمز الاختبار الفعلي ، إنها مجرد عرض توضيحي.
# 1 .toBe مقابل .toEqual
في البداية ، بدا كل هذه العبارات طبيعية بالنسبة لي:
expect('foo').toEqual('foo') expect(1).toEqual(1) expect(['foo']).toEqual(['foo'])
استنادًا إلى استخدام
chai في بيانات المساواة (to.equal) ، هذا أمر طبيعي تمامًا. في الواقع ، Jest لن يشكو ، وهذه التصريحات تمر كالمعتاد.
ومع ذلك ، فإن Jest له. toBe و. toEqual. يتم استخدام الأول لتأكيد المساواة باستخدام
Object.is ، والثاني هو توفير مقارنة عميقة بين الكائنات والصفائف. .toEqual لديه احتياطي لاستخدام
Object.is إذا اتضح أنك لا تحتاج إلى مقارنة عميقة ، مثل تأكيد المساواة في القيم البدائية ، وهو ما يفسر السبب في أن المثال السابق سار بشكل جيد للغاية.
expect('foo').toBe('foo') expect(1).toBe(1) expect(['foo']).toEqual(['foo'])
وبهذه الطريقة ، يمكنك تخطي كل
if-else
.toEqual
في
.toEqual
باستخدام
.toBe
إذا كنت تعرف بالفعل القيم التي
.toBe
.
الخطأ الشائع هو أنك سوف تستخدم.
.toBe
لتأكيد المساواة في القيم البدائية.
expect(['foo']).toBe(['foo'])
إذا نظرت إلى
الكود المصدري عند تعطل .toBe ، فستحاول تحديد ما إذا كنت قد ارتكبت بالفعل هذا الخطأ عن طريق
استدعاء الوظيفة التي يستخدمها .toEqual. يمكن أن يكون هذا عنق الزجاجة عند تحسين الاختبار.
إذا كنت متأكدًا من أنك تستخدم قيمًا بدائية ، فيمكن إعادة تنظيم الكود الخاص بك على هذا النحو لأغراض التحسين:
expect(Object.is('foo', 'foo')).toBe(true)
مزيد من التفاصيل في
الوثائق .
# 2 مقارنات أكثر ملاءمة
من الناحية الفنية ، يمكنك استخدام
.toBe
للتحقق من صحة أي قيم. مع Jest ، يمكنك استخدام أدوات مقارنة معينة لجعل الاختبار أكثر قابلية للقراءة (وفي بعض الحالات أقصر).
هذه ليست سوى بعض من تلك التي اخترتها من قائمة طويلة من المجمعين Jest في الوثائق ، يمكنك إلقاء نظرة على بقية نفسك.
# 3 اختبار لقطة على عناصر بدون واجهة مستخدم
ربما تكون قد سمعت عن
اختبار اللقطة في Jest ، حيث يساعد في تعقب التغييرات في عناصر واجهة المستخدم الخاصة بك. لكن الاختبار باستخدام لقطات لا يقتصر على هذا.
النظر في هذا المثال:
const allEmployees = getEmployees() const happyEmployees = giveIncrementByPosition(allEmployees) expect(happyEmployees[0].nextMonthPaycheck).toBe(1000) expect(happyEmployees[1].nextMonthPaycheck).toBe(5000) expect(happyEmployees[2].nextMonthPaycheck).toBe(4000)
سيكون متعبًا إذا طالبت بمزيد من الموظفين. بالإضافة إلى ذلك ، إذا تبين أن هناك حاجة إلى المزيد من المطالبات لكل موظف ، اضرب عدد المطالبات الجديدة بعدد الموظفين وستحصل على فكرة.
مع اختبار لقطة ، كل هذا يمكن القيام به ببساطة مثل هذا:
const allEmployees = getEmployees() const happyEmployees = giveIncrementByPosition(allEmployees) expect(happyEmployees).toMatchSnapshot()
عندما تحدث الانحدارات ، ستعرف بالضبط أي شجرة في العقدة لا تتطابق مع الصورة.
لكن الراحة تأتي بثمن: هذه الطريقة أكثر عرضة للخطأ. هناك احتمال ألا تعرف أن الصورة غير صحيحة بالفعل ، وفي النهاية ستلتقطها على أي حال. لذا ، تحقق من لقطة سريعة كما لو كانت رمز الموافقة الخاص بك (لأنها كذلك).
بالطبع ، لا يقتصر الاختبار على لقطات. قراءة
الوثائق كاملة.
# 4 يصف كل اختبار
هل سبق لك أن كتبت اختبار مشابه إلى حد ما لهذا؟
describe('When I am a supervisor', () => { test('I should have a supervisor badge', () => { const employee = new Employee({ level: 'supervisor' }) expect(employee.badges).toContain('badge-supervisor') }) test('I should have a supervisor level', () => { const employee = new Employee({ level: 'supervisor' }) expect(employee.level).toBe('supervisor') }) }) describe('When I am a manager', () => { test('I should have a manager badge', () => { const employee = new Employee({ level: 'manager' }) expect(employee.badges).toContain('badge-manager') }) test('I should have a manager level', () => { const employee = new Employee({ level: 'manager' }) expect(employee.level).toBe('manager') }) })
هذا رتابة وروتينية ، أليس كذلك؟ تخيل القيام بذلك مع الكثير من الحالات.
مع
description.each
و
test.each
يمكنك ضغط الكود على النحو التالي:
const levels = [['manager'], ['supervisor']] const privileges = [['badges', 'toContain', 'badge-'], ['level', 'toBe', '']] describe.each(levels)('When I am a %s', (level) => { test.each(privileges)(`I should have a ${level} %s`, (kind, assert, prefix) => { const employee = new Employee({ level }) expect(employee[kind])[assert](`${prefix}${level}`) }) })
ومع ذلك ، لم أقم بعد باستخدام هذا في الاختبار الخاص بي ، حيث أفضل أن يكون اختباري مفصلاً ، لكني اعتقدت أنه سيكون خدعة مثيرة للاهتمام.
راجع
الوثائق لمزيد من التفاصيل حول الوسائط (المفسد: بناء جملة الجدول رائع حقًا).
# 5 تقليد واحد من الوظائف العالمية
في مرحلة ما ، سيتعين عليك اختبار شيء يعتمد على الوظائف العالمية في حالة اختبار معينة. على سبيل المثال ، دالة تتلقى معلومات حول التاريخ الحالي باستخدام كائن javascript Date ، أو مكتبة تعتمد عليه. تكمن الصعوبة في أنه عندما يتعلق الأمر بالتاريخ الحالي ، فلن تتمكن أبدًا من الحصول على العبارة الصحيحة.
function foo () { return Date.now() } expect(foo()).toBe(Date.now())
في النهاية ، سيكون عليك إعادة تعريف كائن التاريخ العام بحيث يكون متسقًا ويمكن التحكم فيه:
function foo () { return Date.now() } Date.now = () => 1234567890123 expect(foo()).toBe(1234567890123)
ومع ذلك ، يعتبر هذا ممارسة سيئة ، حيث يتم الحفاظ على إعادة التعريف بين الاختبارات. لن تلاحظ هذا إذا لم يكن هناك اختبار آخر يعتمد على Date.now ، لكنه سيتسرب أيضًا.
test('First test', () => { function foo () { return Date.now() Date.now = () => 1234567890123 expect(foo()).toBe(1234567890123)
اعتدت على "كسرها" حتى لا تتسرب:
test('First test', () => { function foo () { return Date.now() const oriDateNow = Date.now Date.now = () => 1234567890123 expect(foo()).toBe(1234567890123)
ومع ذلك ، هناك طريقة أفضل وأقل للقراصنة للقيام بذلك:
test('First test', () => { function foo () { return Date.now() jest.spyOn(Date, 'now').mockImplementationOnce(() => 1234567890123) expect(foo()).toBe(1234567890123)
وبالتالي ، يتبع
jest.spyOn
كائن التاريخ العمومي ، فهو يحاكي تطبيق الدالة الآن لمكالمة واحدة فقط. هذا بدوره سوف يترك Date.now سليمة لبقية الاختبارات.
هناك بالتأكيد مزيد من المعلومات حول بذرة في Jest. انظر
الوثائق الكاملة لمزيد من التفاصيل.
هذا المقال يحصل على مدة كافية ، لذلك أعتقد أن هذا كله الآن. يؤثر هذا على جزء صغير فقط من قدرات Jest ، وأبرز فقط مفضلاتي. إذا كان لديك حقائق أخرى مثيرة للاهتمام ، اسمحوا لي أن أعرف.
أيضًا ، إذا كنت تستخدم Jest غالبًا ، فتعرف على
Majestic ، وهو عبارة عن واجهة المستخدم الرسومية الخالية من واجهة المستخدم الرسومية لـ Jest ، وهو بديل جيد حقًا لإخراج محطة طرفية مملة. لست متأكدًا مما إذا كان المؤلف في حالة تطور ، لكن مع ذلك احترام هذا الشخص.
كما هو الحال دائما ، شكرا لاهتمامكم!
هذا كل شيء. أراك في الدورة.