دليل عملي لاختبار تطبيقات التفاعل مع Jest
نشرت: 2022-03-10في هذه المقالة ، سأقدم لك أداة اختبار React المسماة Jest ، جنبًا إلى جنب مع مكتبة Enzyme الشهيرة ، المصممة لاختبار مكونات React. سأقدم لك تقنيات اختبار Jest ، بما في ذلك: إجراء الاختبارات ، واختبار مكونات React ، واختبار اللقطة ، والسخرية. إذا كنت جديدًا في الاختبار وتتساءل عن كيفية البدء ، فستجد هذا البرنامج التعليمي مفيدًا لأننا سنبدأ بمقدمة عن الاختبار. في النهاية ، ستكون جاهزًا للعمل ، وستختبر تطبيقات React باستخدام Jest و Enzyme. يجب أن تكون على دراية بـ React لتتبع هذا البرنامج التعليمي.
مقدمة موجزة للاختبار
الاختبار عبارة عن مراجعة تفصيلية لكيفية تنفيذ التعليمات البرمجية الخاصة بك. تشتمل مجموعة الاختبارات الخاصة بتطبيق ما على أجزاء مختلفة من التعليمات البرمجية للتحقق مما إذا كان التطبيق يتم تنفيذه بنجاح وبدون أخطاء. يكون الاختبار مفيدًا أيضًا عند إجراء التحديثات على الكود. بعد تحديث جزء من التعليمات البرمجية ، يمكنك إجراء اختبار للتأكد من أن التحديث لا يكسر الوظائف الموجودة بالفعل في التطبيق.
لماذا تختبر؟
من الجيد أن نفهم سبب قيامنا بشيء ما قبل القيام به. فلماذا الاختبار وما هو الغرض منه؟
- الغرض الأول من الاختبار هو منع الانحدار. الانحدار هو ظهور خطأ تم إصلاحه سابقًا. فهو يجعل الميزة تتوقف عن العمل على النحو المنشود بعد وقوع حدث معين.
- يضمن الاختبار وظائف المكونات المعقدة والتطبيقات المعيارية.
- الاختبار مطلوب لتحقيق الأداء الفعال لتطبيق أو منتج برمجي.
يجعل الاختبار التطبيق أكثر قوة وأقل عرضة للخطأ. إنها طريقة للتحقق من أن شفرتك تقوم بما تريد أن تفعله وأن تطبيقك يعمل على النحو المنشود لمستخدميك.
دعنا نتعرف على أنواع الاختبارات وماذا تفعل.
اختبار الوحدة
في هذا النوع من الاختبارات ، يتم اختبار الوحدات الفردية أو مكونات البرنامج. قد تكون الوحدة وظيفة فردية أو طريقة أو إجراء أو وحدة نمطية أو كائن. يعزل اختبار الوحدة قسمًا من الكود ويتحقق من صحته ، من أجل التحقق من أن كل وحدة من كود البرنامج تعمل على النحو المتوقع.
في اختبار الوحدة ، يتم اختبار الإجراءات أو الوظائف الفردية لضمان أنها تعمل بشكل صحيح ، ويتم اختبار جميع المكونات بشكل فردي. على سبيل المثال ، اختبار دالة أو ما إذا كانت عبارة أو حلقة في برنامج ما تعمل بشكل صحيح تقع ضمن نطاق اختبار الوحدة.
اختبار المكون
يتحقق اختبار المكون من وظائف جزء فردي من التطبيق. يتم إجراء الاختبارات على كل مكون بمعزل عن المكونات الأخرى. بشكل عام ، تتكون تطبيقات React من عدة مكونات ، لذلك يتعامل اختبار المكونات مع اختبار هذه المكونات بشكل فردي.
على سبيل المثال ، ضع في اعتبارك موقع ويب يحتوي على صفحات ويب مختلفة بها العديد من المكونات. سيكون لكل مكون مكوناته الفرعية. يُشار إلى اختبار كل وحدة دون التفكير في التكامل مع المكونات الأخرى باختبار المكونات.
يتطلب اختبار مثل هذا في React أدوات أكثر تعقيدًا. لذلك ، سنحتاج إلى أدوات Jest وأحيانًا أكثر تعقيدًا ، مثل Enzyme ، والتي سنناقشها لفترة وجيزة لاحقًا.
اختبار لقطة
يتأكد اختبار اللقطة من أن واجهة المستخدم (UI) لتطبيق الويب لا تتغير بشكل غير متوقع. إنه يلتقط رمز المكون في وقت ما ، حتى نتمكن من مقارنة المكون في حالة واحدة مع أي حالة أخرى محتملة قد يستغرقها.
سنتعرف على اختبار اللقطة في قسم لاحق.
مزايا وعيوب الاختبار
الاختبار رائع ويجب إجراؤه ، لكن له مزايا وعيوب.
مزايا
- يمنع الانحدار غير المتوقع.
- يسمح للمطور بالتركيز على المهمة الحالية ، بدلاً من القلق بشأن الماضي.
- يسمح بالبناء المعياري لتطبيق ما كان من الصعب بناؤه بطريقة أخرى.
- يقلل من الحاجة إلى التحقق اليدوي.
سلبيات
- تحتاج إلى كتابة المزيد من التعليمات البرمجية ، وكذلك التصحيح والصيانة.
- قد تؤدي حالات فشل الاختبار غير الحرجة إلى رفض التطبيق من حيث التكامل المستمر.
مقدمة في Jest
Jest هو إطار عمل اختبار JavaScript ممتع مع التركيز على البساطة. يمكن تثبيته مع npm أو الغزل. تتناسب Jest مع فئة أوسع من الأدوات المساعدة المعروفة باسم عداء الاختبار. إنه يعمل بشكل رائع مع تطبيقات React ، ولكنه يعمل أيضًا بشكل رائع خارج تطبيقات React.
Enzyme هي مكتبة تُستخدم لاختبار تطبيقات React. إنه مصمم لاختبار المكونات ، كما أنه يجعل من الممكن كتابة تأكيدات تحاكي الإجراءات التي تؤكد ما إذا كانت واجهة المستخدم تعمل بشكل صحيح.
تكمل Jest و Enzyme بعضهما البعض جيدًا ، لذلك في هذه المقالة سنستخدم كليهما.
عملية إجراء اختبار مازح
في هذا القسم ، سنقوم بتثبيت اختبارات Jest والكتابة. إذا كنت مستخدمًا جديدًا لـ React ، فأنا أوصي باستخدام تطبيق Create React ، لأنه جاهز للاستخدام ويتم شحنه مع Jest.
npm init react-app my-app
نحن بحاجة إلى تثبيت Enzyme **** و enzyme-adapter-react-16
مع react-test-renderer
(يجب أن يعتمد الرقم على إصدار React الذي تستخدمه).
npm install --save-dev enzyme enzyme-adapter-react-16 react-test-renderer
الآن وقد أنشأنا مشروعنا باستخدام كل من Jest و Enzyme ، نحتاج إلى إنشاء ملف setupTest.js
في مجلد src
الخاص بالمشروع. يجب أن يبدو الملف كالتالي:
import { configure } from "enzyme"; import Adapter from "enzyme-adapter-react-16"; configure({ adapter: new Adapter() });
يقوم هذا باستيراد الإنزيم وإعداد المحول لإجراء اختباراتنا.
قبل المتابعة ، دعنا نتعلم بعض الأساسيات. يتم استخدام بعض الأشياء الأساسية كثيرًا في هذه المقالة ، وستحتاج إلى فهمها.
- أو
test
يمكنك تمرير وظيفة إلىit
الطريقة ، وسيقوم عداء الاختبار بتنفيذ هذه الوظيفة ككتلة من الاختبارات. -
describe
هذه الطريقة الاختيارية لتجميع أي عددit
أو عباراتtest
. -
expect
هذا هو الشرط الذي يجب أن يجتاز الاختبار. يقارن المعلمة المستلمة بالمطابق. كما يتيح لك الوصول إلى عدد من المطابقات التي تتيح لك التحقق من صحة أشياء مختلفة. يمكنك قراءة المزيد عنها في الوثائق. -
mount
هذه الطريقة تعرض DOM الكامل ، بما في ذلك المكونات الفرعية للمكوِّن الرئيسي ، حيث نجري الاختبارات. -
shallow
هذا يجعل فقط المكونات الفردية التي نقوم باختبارها. لا تجعل المكونات التابعة. هذا يمكننا من اختبار المكونات بمعزل عن غيرها.
إنشاء ملف اختبار
كيف يعرف Jest ما هو ملف الاختبار وما هو ليس كذلك؟ القاعدة الأولى هي أن أي ملفات موجودة في أي دليل باسم __test__
تعتبر بمثابة اختبار. إذا قمت بوضع ملف JavaScript في أحد هذه المجلدات ، فسيحاول Jest تشغيله عند استدعاء Jest ، للأفضل أو للأسوأ. القاعدة الثانية هي أن Jest سيتعرف على أي ملف له اللاحقة .spec.js
أو .test.js
. سيبحث في أسماء جميع المجلدات وجميع الملفات في المستودع بأكمله.
لنقم بإنشاء اختبارنا الأول لتطبيق React المصغر الذي تم إنشاؤه لهذا البرنامج التعليمي. يمكنك استنساخه على GitHub. قم بتشغيل npm install
كافة الحزم ، ثم npm start
في تشغيل التطبيق. تحقق من ملف README.md
لمزيد من المعلومات.
App.test.js
لكتابة اختبارنا الأول. أولاً ، تحقق مما إذا كان مكون التطبيق الخاص بنا يتم عرضه بشكل صحيح وما إذا كنا قد حددنا ناتجًا:
it("renders without crashing", () => { shallow(<App />); }); it("renders Account header", () => { const wrapper = shallow(<App />); const welcome = <h1>Display Active Users Account Details</h1>; expect(wrapper.contains(welcome)).toEqual(true); });
في الاختبار أعلاه ، يتحقق الاختبار الأول ، ذو shallow
، لمعرفة ما إذا كان مكون التطبيق الخاص بنا يتم عرضه بشكل صحيح دون تعطل. تذكر أن الطريقة shallow
تقدم مكونًا واحدًا فقط ، بدون مكونات فرعية.
يتحقق الاختبار الثاني مما إذا كنا قد حددنا إخراج علامة h1
لـ "عرض حساب المستخدم النشط" في مكون التطبيق لدينا ، مع مطابقة Jest لـ toEqual
.
الآن ، قم بإجراء الاختبار:
npm run test /* OR */ npm test
يجب أن يكون الإخراج في جهازك كما يلي:
PASS src/App.test.js √ renders without crashing (34ms) √ renders Account header (13ms) Test Suites: 1 passed, 1 total Tests: 2 passed, 2 total Snapshots: 0 total Time: 11.239s, estimated 16s Ran all test suites related to changed files. Watch Usage: Press w to show more.
كما ترون ، اجتاز اختبارنا. يظهر أن لدينا مجموعة اختبار واحدة تسمى App.test.js
، مع اختبارين ناجحين عند تشغيل Jest. سنتحدث عن اختبار اللقطة لاحقًا ، وستحصل أيضًا على مثال على اختبار فاشل.
تخطي أو عزل اختبار
يعني تخطي الاختبار أو عزله أنه عند تشغيل Jest ، لا يتم تشغيل اختبار محدد محدد.
it.skip("renders without crashing", () => { shallow(<App />); }); it("renders Account header", () => { const wrapper = shallow(<App />); const header = <h1>Display Active Users Account Details</h1>; expect(wrapper.contains(header)).toEqual(true); });
سيتم تخطي اختبارنا الأول لأننا استخدمنا طريقة skip
لعزل الاختبار. لذلك ، لن يتم تشغيله أو إجراء أي تغييرات على اختبارنا عند تشغيل Jest. سيتم تشغيل الثانية فقط. يمكنك أيضًا استخدامه it.only()
.
من المحبط بعض الشيء إجراء تغييرات على ملف اختبار ثم npm test
يدويًا مرة أخرى. لدى Jest ميزة لطيفة تسمى وضع المشاهدة ، والتي تراقب تغييرات الملف وتجري الاختبارات وفقًا لذلك. لتشغيل Jest في وضع المشاهدة ، يمكنك تشغيل npm test -- --watch
أو jest --watch
. أوصي أيضًا بترك Jest قيد التشغيل في نافذة المحطة الطرفية لبقية هذا البرنامج التعليمي.
وظيفة الاستهزاء
المحاكاة هي نسخة مكررة مقنعة لكائن أو وحدة بدون أي أعمال داخلية حقيقية. قد يكون لديها القليل من الوظائف ، ولكن بالمقارنة مع الشيء الحقيقي ، فهي وهمية. يمكن إنشاؤه تلقائيًا بواسطة Jest أو يدويًا.
لماذا يجب أن نسخر؟ يقلل الاستهزاء من عدد التبعيات - أي عدد الملفات ذات الصلة التي يجب تحميلها وتحليلها عند تشغيل الاختبار. لذلك ، فإن استخدام الكثير من النماذج يجعل الاختبارات يتم تنفيذها بسرعة أكبر.
تُعرف الوظائف الوهمية أيضًا باسم "الجواسيس" ، لأنها تتيح لك التجسس على سلوك الوظيفة التي يتم استدعاؤها مباشرة من خلال بعض التعليمات البرمجية الأخرى ، بدلاً من اختبار المخرجات فقط.
هناك طريقتان للاستهزاء بوظيفة ما: إما عن طريق إنشاء دالة وهمية لاستخدامها في كود الاختبار ، أو عن طريق كتابة نموذج يدوي لتجاوز تبعية الوحدة النمطية.
تُستخدم النماذج اليدوية **** لإخراج الوظائف ببيانات وهمية. على سبيل المثال ، بدلاً من الوصول إلى مورد بعيد ، مثل موقع ويب أو قاعدة بيانات ، قد ترغب في إنشاء نموذج يدوي يسمح لك باستخدام بيانات مزيفة.
سنستخدم دالة وهمية في القسم التالي.
اختبار مكونات التفاعل
سيجمع القسم كل المعارف التي اكتسبناها حتى الآن في فهم كيفية اختبار مكونات React. يتضمن الاختبار التأكد من أن إخراج أحد المكونات لم يتغير بشكل غير متوقع إلى شيء آخر. يعد بناء المكونات بالطريقة الصحيحة الطريقة الأكثر فاعلية لضمان نجاح الاختبار.
شيء واحد يمكننا القيام به هو اختبار دعائم المكونات - على وجه التحديد ، اختبار ما إذا كانت الدعائم من أحد المكونات يتم تمريرها إلى آخر. تسمح لنا Jest و Enzyme API بإنشاء وظيفة وهمية لمحاكاة ما إذا كان يتم تمرير الدعائم بين المكونات.
يتعين علينا تمرير خصائص حساب المستخدم من مكون App
الرئيسي إلى مكون Account
. نحتاج إلى إعطاء تفاصيل حساب المستخدم Account
من أجل تقديم الحساب النشط للمستخدمين. هذا هو المكان الذي يكون فيه الاستهزاء مفيدًا ، مما يمكننا من اختبار مكوناتنا ببيانات مزيفة.
لنقم بإنشاء محاكاة لدعائم user
:
const user = { name: "Adeneye David", email: "[email protected]", username: "Dave", };
لقد أنشأنا وظيفة محاكاة يدوية في ملف الاختبار الخاص بنا ولفناها حول المكونات. لنفترض أننا نختبر قاعدة بيانات كبيرة للمستخدمين. لا يُنصح بالوصول إلى قاعدة البيانات مباشرة من ملف الاختبار الخاص بنا. بدلاً من ذلك ، نقوم بإنشاء وظيفة وهمية ، والتي تمكننا من استخدام البيانات المزيفة لاختبار المكون الخاص بنا.
describe(" ", () => { it("accepts user account props", () => { const wrapper = mount(<Account user={user} />); expect(wrapper.props().user).toEqual(user); }); it("contains users account email", () => { const wrapper = mount(<Account user={user} />); const value = wrapper.find("p").text(); expect(value).toEqual("[email protected]"); }); });
describe(" ", () => { it("accepts user account props", () => { const wrapper = mount(<Account user={user} />); expect(wrapper.props().user).toEqual(user); }); it("contains users account email", () => { const wrapper = mount(<Account user={user} />); const value = wrapper.find("p").text(); expect(value).toEqual("[email protected]"); }); });
لدينا اختباران أعلاه ، ونستخدم طبقة describe
، والتي تأخذ المكون قيد الاختبار. من خلال تحديد الخاصيات والقيم التي نتوقع أن يجتازها الاختبار ، يمكننا المضي قدمًا.
في الاختبار الأول ، نتحقق مما إذا كانت الدعائم التي مررناها إلى المكون المركب تساوي الدعائم الوهمية التي أنشأناها أعلاه.
بالنسبة للاختبار الثاني ، نقوم بتمرير خاصيات المستخدم إلى مكون Account
الموصول. بعد ذلك ، نتحقق مما إذا كان بإمكاننا العثور على العنصر <p>
الذي يتوافق مع ما لدينا في مكون Account
. عندما نقوم بتشغيل مجموعة الاختبار ، سترى أن الاختبار يعمل بنجاح.
يمكننا أيضًا اختبار حالة المكون الخاص بنا. دعنا نتحقق مما إذا كانت حالة رسالة الخطأ تساوي قيمة خالية:
it("renders correctly with no error message", () => { const wrapper = mount( ); expect(wrapper.state("error")).toEqual(null); });
it("renders correctly with no error message", () => { const wrapper = mount( ); expect(wrapper.state("error")).toEqual(null); });
في هذا الاختبار ، نتحقق مما إذا كانت حالة خطأ المكون لدينا تساوي قيمة خالية ، باستخدام مطابقة toEqual()
. إذا كانت هناك رسالة خطأ في تطبيقنا ، فسيفشل الاختبار عند التشغيل.
في القسم التالي ، سنتعرف على كيفية اختبار مكونات React باختبار اللقطة ، وهي تقنية أخرى رائعة.
اختبار لقطة
يلتقط اختبار اللقطة رمز أحد المكونات في وقت ما ، من أجل مقارنته بملف لقطة مرجعي مخزن بجانب الاختبار. يتم استخدامه لتتبع التغييرات في واجهة المستخدم للتطبيق.
تمثيل الكود الفعلي للقطة هو ملف JSON ، ويحتوي ملف JSON هذا على سجل لما بدا عليه المكون عند عمل اللقطة. أثناء الاختبار ، يقارن Jest محتويات ملف JSON هذا بإخراج المكون أثناء الاختبار. إذا تطابقت ، ينجح الاختبار ؛ إذا لم يفعلوا ذلك ، يفشل الاختبار.
لتحويل غلاف إنزيم إلى تنسيق متوافق مع اختبار لقطة Jest ، يتعين علينا تثبيت enzyme-to-json
:
npm install --save-dev enzyme-to-json
لنقم بإنشاء اختبار لقطة لدينا. عندما نقوم بتشغيله في المرة الأولى ، سيتم تكوين لقطة من رمز هذا المكون وحفظها في مجلد __snapshots__
جديد في دليل src
.
it("renders correctly", () => { const tree = shallow(<App />); expect(toJson(tree)).toMatchSnapshot(); });
عند تشغيل الاختبار أعلاه بنجاح ، ستتم مقارنة مكون واجهة المستخدم الحالي بالمكون الموجود.
الآن ، دعنا نجري الاختبار:
npm run test
عند تشغيل مجموعة الاختبار ، سيتم إنشاء لقطة جديدة وحفظها في المجلد __snapshots__
. عندما نجري اختبارًا لاحقًا ، سيتحقق Jest مما إذا كانت المكونات تتطابق مع اللقطة.
كما هو موضح في القسم السابق ، تُستخدم هذه الطريقة shallow
من حزمة الإنزيم لتقديم مكون واحد ولا شيء آخر. لا يجعل المكونات الفرعية. بدلاً من ذلك ، يمنحنا طريقة لطيفة لعزل الكود والحصول على معلومات أفضل عند تصحيح الأخطاء. يتم استخدام طريقة أخرى ، تسمى mount
، لعرض DOM الكامل ، بما في ذلك المكونات الفرعية للمكوِّن الرئيسي ، حيث نجري الاختبارات.
يمكننا أيضًا تحديث اللقطة ، فلنقم بإجراء بعض التغييرات على المكون الخاص بنا من أجل فشل اختبارنا ، والذي سيحدث لأن المكون لم يعد يتوافق مع ما لدينا في ملف اللقطة. للقيام بذلك ، دعنا نغير العلامة <h3>
في المكون الخاص بنا من <h3> Loading...</h3>
إلى <h3>Fetching Users...</h3>
. عند إجراء الاختبار ، هذا ما سنحصل عليه في الجهاز:
FAIL src/App.test.js (30.696s) × renders correctly (44ms) ● renders correctly expect(received).toMatchSnapshot() Snapshot name: `renders correctly 1 - Snapshot + Received
7 | فإنه ("يتم عرضه بشكل صحيح"، () => { 8 | غلاف const = ضحل ( FAIL src/App.test.js (30.696s) × renders correctly (44ms) ● renders correctly expect(received).toMatchSnapshot() Snapshot name: `renders correctly 1 - Snapshot + Received
عرض تفاصيل حساب المستخدمين النشطين
- جار التحميل... + جلب المستخدمين ...
) ؛ > 9 | توقع (toJson (المجمع)). toMatchSnapshot () ؛ | ^ 10 | }) ؛ 11 | 12 | / * it ("يتم العرض بدون تعطل"، () => { في الكائن. (src / App.test.js: 9:27) ›1 فشل لقطة. ملخص لقطة ›فشلت لقطة واحدة من مجموعة اختبار واحدة. افحص تغييرات التعليمات البرمجية أو اضغط على "u" لتحديثها. مجموعات الاختبار: فشل 1 ، إجمالي 1 الاختبارات: فشل 1 ، إجمالي 1 اللقطات: فشل 1 ، إجمالي 1 الوقت: 92.274 ثانية تشغيل جميع مجموعات الاختبار المتعلقة بالملفات التي تم تغييرها. مشاهدة الاستخدام: اضغط على w لإظهار المزيد.
إذا أردنا اجتياز الاختبار ، فسنقوم إما بتغيير الاختبار إلى حالته السابقة أو تحديث ملف اللقطة. في سطر الأوامر ، يوفر Jest إرشادات حول كيفية تحديث اللقطة. أولاً ، اضغط على w
في سطر الأوامر لإظهار المزيد ، ثم اضغط على u
لتحديث اللقطة.
› Press u to update failing snapshots.
عندما نضغط على u
لتحديث اللقطة ، سينتقل الاختبار.
خاتمة
أتمنى أن تكون قد استمتعت بالعمل من خلال هذا البرنامج التعليمي. لقد تعلمنا بعض تقنيات اختبار الدعابة باستخدام مكتبة اختبار الإنزيم. لقد عرّفتك أيضًا على عملية إجراء اختبار ، واختبار مكونات React ، والسخرية ، واختبار اللقطة. إذا كانت لديك أي أسئلة ، فيمكنك تركها في قسم التعليقات أدناه ، وسيسعدني الإجابة على كل سؤال والعمل على حل أي مشكلات معك.
الموارد وقراءات أخرى
- وثائق الدعابة
- توثيق الإنزيم
- "كيفية اختبار مكونات التفاعل: الدليل الكامل" ، محمد إقبال ، freeCodeCamp
- "اختبار التفاعل مع الدعابة والإنزيم" ، دومينيك فريزر ، CodeClan