هل تبحث عن طريقة لإجراء الاختبارات بطريقة أسهل؟ نحن معك! راجع المقال التالي وتعرف على كيفية جعل ذلك ممكناً.
يعتمد تطوير التطبيقات الحديثة على قاعدة واحدة بسيطة:
استخدام التركيب
نحن نؤلف الفئات والوظائف والخدمات في أجزاء أكبر من البرمجيات. هذا العنصر الأخير هو أساس الخدمات المصغرة و بنية سداسية الشكل. نرغب في استخدام الحلول الحالية ودمجها مع برنامجنا والانتقال مباشرة إلى السوق.
هل تريد التعامل مع تسجيل الحساب وتخزين بيانات المستخدم؟ يمكنك اختيار إحدى خدمات OAuth. ربما يقدم تطبيقك نوعًا من الاشتراك أو الدفع؟ هناك العديد من الخدمات التي يمكن أن تساعدك في التعامل مع هذا الأمر. هل تحتاج إلى بعض التحليلات على موقع الويب الخاص بك، ولكنك لا تفهم اللائحة العامة لحماية البيانات؟ لا تتردد في اختيار أحد الحلول الجاهزة.
الشيء الذي يجعل التطوير سهلاً للغاية من وجهة نظر العمل يمكن أن يسبب لك صداعًا - اللحظة التي تحتاج فيها إلى كتابة اختبار بسيط.
الوحوش الرائعة قوائم الانتظار وقواعد البيانات وكيفية اختبارها
اختبار الوحدة بسيط جدًا. إذا اتبعت القواعد فقط، فإن بيئة الاختبار الخاصة بك و الكود صحية. ما هي هذه القواعد؟
سهولة الكتابة - يجب أن يكون اختبار الوحدة سهل الكتابة لأنك تكتب الكثير منها. جهد أقل يعني كتابة المزيد من الاختبارات.
قابل للقراءة - يجب أن يكون رمز الاختبار سهل القراءة. الاختبار عبارة عن قصة. فهو يصف سلوك البرنامج ويمكن استخدامه كاختصار للوثائق. يساعدك اختبار الوحدة الجيد على إصلاح الأخطاء دون الحاجة إلى تصحيح الشيفرة البرمجية.
موثوقة - يجب أن يفشل الاختبار فقط في حالة وجود خطأ في النظام الذي يتم اختباره. واضح؟ ليس دائمًا. أحيانًا تنجح الاختبارات إذا قمت بتشغيلها واحدًا تلو الآخر ولكنها تفشل عند تشغيلها كمجموعة. تنجح على جهازك، ولكنها تفشل على CI (يعمل على جهازي). اختبار الوحدة الجيد له سبب واحد فقط للفشل.
سريع - يجب أن تكون الاختبارات سريعة. يجب أن يكون التحضير للتشغيل والبدء وتنفيذ الاختبار نفسه سريعًا جدًا. وإلا فإنك ستكتبها ولا تقوم بتشغيلها. الاختبارات البطيئة تعني فقدان التركيز. تنتظر وتنظر إلى شريط التقدم.
مستقل - وأخيراً، يجب أن يكون الاختبار مستقلاً. تنبع هذه القاعدة من القواعد السابقة. فقط الاختبارات المستقلة حقاً يمكن أن تصبح وحدة. فهي لا تتداخل مع بعضها البعض، ويمكن تشغيلها بأي ترتيب، ولا يعتمد الفشل المحتمل على نتائج الاختبارات الأخرى. الاستقلالية تعني أيضًا عدم الاعتماد على أي موارد خارجية مثل قواعد البيانات أو خدمات المراسلة أو نظام الملفات. إذا كنت بحاجة إلى التواصل مع مصادر خارجية، يمكنك استخدام النماذج أو البدائل أو الدمى.
يصبح كل شيء معقدًا عندما نريد كتابة بعض اختبارات التكامل. ليس الأمر سيئًا إذا أردنا اختبار بعض الخدمات معًا. ولكن عندما نحتاج إلى اختبار الخدمات التي تستخدم موارد خارجية مثل قواعد البيانات أو خدمات المراسلة، فإننا نطلب المتاعب.
لتشغيل الاختبار، تحتاج إلى تثبيت...
منذ سنوات عديدة، عندما أردنا إجراء بعض اختبارات التكامل واستخدام قواعد البيانات على سبيل المثال، كان لدينا خياران:
يمكننا تثبيت قاعدة بيانات محلياً. إعداد مخطط والاتصال من اختبارنا;
يمكننا الاتصال بمثيل موجود "في مكان ما في الفضاء".
كلاهما له إيجابيات وكلاهما له سلبيات. لكن كلاهما يقدم مستويات إضافية من التعقيد. في بعض الأحيان كان تعقيدًا تقنيًا ناشئًا عن خصائص أدوات معينة، على سبيل المثال تثبيت وإدارة قاعدة بيانات Oracle على المضيف المحلي. في بعض الأحيان كان الأمر في بعض الأحيان إزعاجًا في العملية، على سبيل المثال تحتاج إلى الاتفاق مع الاختبار الفريق حول استخدام JMS... في كل مرة تريد فيها تشغيل الاختبارات.
حاويات للإنقاذ
على مدى السنوات العشر الماضية، اكتسبت فكرة استخدام الحاويات شهرة في الصناعة. لذلك، كان القرار الطبيعي هو اختيار الحاويات كحل لمشكلة اختبار التكامل لدينا. هذا حل بسيط ونظيف. ما عليك سوى تشغيل بناء العملية الخاصة بك وكل شيء يعمل! لا يمكنك تصديق ذلك؟ ألقِ نظرة على هذا التكوين البسيط لبناء مافن:
com.dkanejs.maven.plugins
docker-compose-maven-plugin
4.0.0
إعداد
اختبار التجميع
أعلى
>${المشروع.basedir}/docker-compose.yml
صحيح
أسفل</المعرف
اختبار ما بعد التكامل
أسفل
${project.basedir}/docker-compose.yml
صحيح
و docker-compose.yml يبدو الملف جميلًا جدًا أيضًا!
الإصدار: "3.5"
الخدمات:
Postgres:
اسم الحاوية: reactivedb
الصورة: Postgres:13.2
إعادة التشغيل: دائمًا
البيئة:
- POSTGRES_USER = المسؤول
- POSTGRES_PASSWORD=كلمة المرور
- POSTGRES_DB = المدن
المنافذ:
- "5432:5432"
وحدات التخزين
- Postgres_data:/data/db
pgadmin:
اسم الحاوية: pgadmin4
الصورة: dpage/pgadmin4
إعادة التشغيل: دائمًا
البيئة:
pgadmin_default_email: [email protected]
PGADMIN_DEFAULT_PASSWORD: كلمة المرور
المنافذ:
- "15050:80"
وحدات التخزين
- pgadmin_data:/data/pgadmin
وحدات التخزين:
postgres_data:
pgadmin_data:
لكن هل يمكنك تحديد المشكلة هنا؟
سفينة شحن تحجب كل شيء
المثال أعلاه بسيط للغاية. فقط قاعدة بيانات Postgres واحدة، و pgAdmin وهذا كل شيء. عند تشغيل
باش
$ mvn نظيف التحقق من $
ثم يقوم المكون الإضافي maven بتشغيل الحاويات وبعد الاختبارات يقوم بإيقاف تشغيلها. تبدأ المشاكل عندما ينمو المشروع وينمو ملف الإنشاء أيضًا. في كل مرة ستحتاج إلى بدء تشغيل جميع الحاويات، وستبقى على قيد الحياة خلال عملية الإنشاء بأكملها. يمكنك تحسين الوضع قليلًا عن طريق تغيير تكوين تنفيذ المكون الإضافي، ولكن هذا لا يكفي. في أسوأ السيناريوهات، تستنفد حاوياتك موارد النظام قبل بدء الاختبارات!
وهذه ليست المشكلة الوحيدة. لا يمكنك تشغيل اختبار تكامل واحد من IDE الخاص بك. قبل ذلك، تحتاج إلى بدء تشغيل الحاويات يدويًا. علاوة على ذلك، سيؤدي تشغيل maven التالي إلى تفكيك تلك الحاويات (ألق نظرة على لأسفل التنفيذ).
لذا فإن هذا الحل يشبه سفينة شحن كبيرة. إذا كان كل شيء يعمل بشكل جيد، فلا بأس. أي سلوك غير متوقع أو غير مألوف يقودنا إلى نوع من الكوارث.
حاويات الاختبار - تشغيل الحاويات من الاختبارات
ولكن ماذا لو استطعنا تشغيل حاوياتنا من الاختبارات؟ تبدو هذه الفكرة جيدة، ويجري تنفيذها بالفعل. حاويات الاختبار،لأننا نتحدث عن هذا المشروع، إليك حل لمشاكلنا. ليست مثالية، لكن لا أحد مثالي.
هذا هو جافا التي تدعم اختبارات JUnit وSpock، مما يوفر طرقًا خفيفة وسهلة لتشغيل حاوية Docker. دعونا نلقي نظرة عليها ونكتب بعض التعليمات البرمجية!
المتطلبات الأساسية والتكوين
قبل أن نبدأ، نحتاج إلى التحقق من التهيئة. حاويات الاختبار الحاجة:
Docker في الإصدار v17.09,
الحد الأدنى لإصدار جافا 1.8,
الوصول إلى الشبكة، وخاصةً إلى docker.hub.
يمكن العثور على المزيد حول متطلبات نظام تشغيل معين و CI في الوثائق.
والآن حان الوقت لإضافة بعض الأسطر إلى pom.xml.
أورغ.testcontainers
testcontainers-bom
${testcontainers.version}
بوم
استيراد
org.postgresql
postgresql
وقت التشغيل
org.testcontainers
postgresql
اختبار
org.testcontainers
junit-jupiter
اختبار
أستخدم حاويات الاختبار الإصدار 1.17.3، ولكن لا تتردد في استخدام الأحدث.
الاختبارات مع حاوية Postgres
الخطوة الأولى هي إعداد مثيل الحاوية. يمكنك القيام بذلك مباشرةً في الاختبار، ولكن يبدو الفصل المستقل أفضل.
عام فئة Postgres13TC العامة PostgreSQLContainer {
فئة Postgres13TC خاصة ثابتة ونهائية Postgres13TC TC = Postgres13TC() جديدة Postgres13TC();
خاص Postgres13TC() {) {
ممتاز("postgres:13.2");
}
عمومي ثابت Postgres13TC getInstance() {{
إرجاع TC;
}
@Overrride
عام باطل بدء عام() { {
super.start();
System.setProperty("DB_URL", TC.getJdbcUrl());
System.setProperty("DB_USERNAME"، TC.getUsername())؛
System.setProperty("DB_PASSWORD"، TC.getPassword())؛
}
@Overrride
إيقاف عام باطل() {{.
// لا تفعل شيئًا. هذا مثيل مشترك. دع JVM يتعامل مع هذه العملية.
}
}
في بداية الاختبارات، سننشئ مثيلًا ل Postgres13TC. يمكن لهذه الفئة التعامل مع المعلومات حول الحاوية الخاصة بنا. الأكثر أهمية هنا هي سلاسل اتصال قاعدة البيانات وبيانات الاعتماد. حان الوقت الآن لكتابة اختبار بسيط للغاية.
@ حاويات الاختبار
صنف SimpleDbTest {
@حاوية
خاص Postgres13TC ثابت = Postgres13TC.getInstance();
@اختبار
باطل testConnection() { {
افترض أن(postgres13TC.isRunning()));
var connectionProps = خصائص جديدة();
connectionProps.put("المستخدم"، postgres13TC.getUsername());
connectProps.put("كلمة المرور"، postgres13TC.getPassword())؛
محاولة (محاولة (اتصال = DriverManager.getConnection(postgres13TC.getJdbcUrl(),
connectProps)) {
var resultSet = connection.prepareStatement("حدد 1").executeQuery();
resultSet.next();
تأكيد أن(resultSet.getInt(1)).isEqualTo(1);
} التقاط (استثناء SQLEXception sqlException) {
تأكيد أن((استثناء) استثناء sqlException).doesNotThrowAnyException();
}
}
}
أستخدم JUnit 5 هنا. شرح توضيحي @Testcontainers جزء من الامتدادات التي تتحكم في الحاويات في بيئة الاختبار. يجدون جميع الحقول التي تحتوي على الحاوية @Container التعليق التوضيحي وحاويات البدء والإيقاف على التوالي.
اختبارات مع سبرينغ بوت
كما ذكرت من قبل، أستخدم Spring Boot في المشروع. في هذه الحالة، نحتاج إلى كتابة المزيد من التعليمات البرمجية. الخطوة الأولى هي إنشاء فئة تكوين إضافية.
تقوم هذه الفئة بتجاوز الخصائص الموجودة بقيم من حاوية الاختبار. الخصائص الثلاث الأولى هي خصائص الربيع القياسية. الخمسة التالية هي خصائص إضافية ومخصصة يمكن استخدامها لتهيئة الموارد والإضافات الأخرى مثل liquibase، على سبيل المثال:
@SpringBootTest(webEnvironment = RANDOM_PORT) - يضع علامة على الاختبار كاختبار ربيع بوت ويبدأ سياق الربيع.
@AutoConfigureTestDatabase(استبدال = NONE) - تقول هذه التعليقات التوضيحية أن ملحق اختبار الربيع يجب ألا يستبدل ملحق اختبار الربيع تكوين قاعدة بيانات Postgres بـ H2 في تكوين الذاكرة.
@ContextConfiguration(المُهيئات = ContainerInit.class) - سياق ربيعي إضافي حيث نقوم بإعداد الخصائص من حاويات الاختبار.
@Testcontainers - كما ذكرنا سابقًا، يتحكم هذا الشرح في دورة حياة الحاوية.
في هذا المثال، أستخدم في هذا المثال المستودعات التفاعلية ولكنها تعمل بنفس الطريقة مع مستودعات JDBC و JPA الشائعة.
يمكننا الآن تشغيل هذا الاختبار. إذا كان هذا هو التشغيل الأول، يحتاج المحرك إلى سحب الصور من docker.hub. قد يستغرق ذلك لحظة. بعد ذلك، سنرى بعد ذلك تشغيل حاويتين. إحداهما هي Postgres والأخرى هي وحدة تحكم Testcontainers. تدير هذه الحاوية الثانية الحاويات قيد التشغيل وحتى إذا توقفت JVM بشكل غير متوقع، فإنها تقوم بإيقاف تشغيل الحاويات وتنظيف البيئة.
دعونا نلخص
حاويات الاختبار هي أدوات سهلة الاستخدام للغاية تساعدنا على إنشاء اختبارات تكامل تستخدم حاويات Docker. وهذا يمنحنا المزيد من المرونة ويزيد من سرعة التطوير. يقلل الإعداد الصحيح لتهيئة الاختبار من الوقت اللازم للمطورين الجدد. فهم لا يحتاجون إلى إعداد جميع التبعيات، فقط تشغيل الاختبارات المكتوبة بملفات التكوين المحددة.