كارثة الاختبار الواضحة... أعتقد أنه يمكنك ترك الجزء -db- إذا كنت تريد كلمة أقصر قليلاً وتشعر بالميل الشديد.
Test-DB-Acle هي مكتبة PHP لتسهيل كتابة اختبارات سهلة وموجزة لطبقة قاعدة البيانات.
في اعتقادي أن اختبارات الكتابة يجب أن تكون سهلة قدر الإمكان بالنسبة للمطور، ويجب أيضًا أن تكون سهلة القراءة قدر الإمكان حتى يتمكن المطورون الآخرون من التقاطها.
وهذا يعني أن أي بيانات اختبار في الاختبار يجب أن تكون ذات صلة بسيناريو الاختبار فقط. ومع ذلك، تحتوي معظم جداول قاعدة البيانات على أعمدة غير فارغة تتطلب منك إدخال بيانات وهمية تؤدي فقط إلى إدخال ضوضاء معرفية للاختبار.
يهدف Test-Db-Acle إلى رفع هذا العبء عن المطور. لا يقدم إطار الاختبار أي افتراضات حول كيفية عمل فئات طبقة قاعدة البيانات الخاصة بك، إذا كانوا يستخدمون ORM مثل Doctrine أو الإجراءات المخزنة أو SQL المستقيمة، فإن المبدأ هو نفسه دائمًا، وفي مرحلة ما يتفاعل الكود مع البيانات الموجودة في جداول قاعدة البيانات ، ونحن بحاجة لاختبار هذا.
التثبيت عن طريق الملحن
تعطيل عمليات فحص المفاتيح الخارجية في قاعدة البيانات
يتعامل تلقائيًا مع الأعمدة غير الفارغة
يقوم تلقائيًا بقص أعمدة التاريخ/الوقت في mysql عند تأكيد القيم في جداول db - وهو مفيد للطوابع الزمنية المدرجة (في Sqlite يجب تحديد هذه الأعمدة)
يمكن استبدال جميع المكونات تقريبًا واستبدالها بأصناف مخصصة
يدعم Mysql وSqlite في الوقت الحاضر
نظرًا لأنه لا يعرف إطار العمل، فإنه لا يفترض ما إذا تم استخدام ORMs على سبيل المثال ويجب أن تكون قابلة للتكيف بسهولة مع أطر اختبار الوحدة الأخرى.
قواعد البيانات المدعومة، في الوقت الحاضر، هي MySql (وبالتبعية MariaDB) وSqlite.
يجب أن تسمح البنية بإضافة المزيد من قواعد البيانات.
يمكن استخدام هذه المكتبة خارج الصندوق مع PHPUnit. يجب أن يكون من السهل إلى حد ما استخدامه مع أطر الاختبار الأخرى باستخدام السمات المتوفرة وتفويض أسلوب "assertEquals" إلى الطريقة المكافئة (على سبيل المثال، أتذكر أنه كان "assertEqual" في SimpleTest)
لقد قدمت TestDbAclePhpUnitAbstractTestCase بسيطًا بالإضافة إلى TestDbAclePhpUnitTraitsDatabaseHelperTrait إذا كنت تستخدم PHP 5.4 ولا تمانع في استخدام السمات.
حسنًا، لكي نكون منصفين حقًا، يعد اختبار طبقة قاعدة البيانات أمرًا مكلفًا ويبطئ الاختبارات، وحيثما أمكن، يجب الاستهزاء بأي تبعيات على قاعدة البيانات. لكن في بعض الأحيان يتعين علينا فقط القيام بذلك، ونأمل أن يتم تقليل هذا إلى الحد الأدنى في تطبيق جيد التنظيم.
هناك العديد من الأدوات والأساليب المتاحة (على سبيل المثال DBUnit أو استخدام أساليب المصنع في اختبارات الوحدة الخاصة بك) للمساعدة في اختبار قاعدة البيانات، ولكل منها نقاط قوتها الخاصة، وهذا الأسلوب يناسبني لأنه:
لا داعي للقلق بشأن الأعمدة الفارغة أو قيود المفاتيح الخارجية
أقدم مجموعة بيانات بسيطة لاختباراتي
يمكنني رؤية بيانات الاختبار بتنسيق يشبه الشبكة أعلى الاختبارات ومرة أخرى عند تأكيد البيانات في قاعدة البيانات.
لذلك قمت بإعداد الحل الخاص بي.
###فكيف يعمل وكيف يبدو؟ أرني مثالاً!###
تتمثل الفكرة في استخدام سلسلة نصية "قيم مفصولة بالأنابيب"، دعنا نسميها PSV - كما هو الحال في ملف CSV، ولكن مع الأنابيب - لإعداد تركيبات اختبار مثل هذا:
(تنسيق PSV مشابه جدًا للتنسيق الذي يستخدمه إطار عمل Behat BDD الممتاز (https://github.com/Behat/Behat))
$dbTablesToSetup="[table_name]id |date |name |value |dependent_table_id10 |2001-01-01 |foo |900 |60[dependent_table]id |name20 |Bar60 |Baz";// استخدم هذا إذا كنت لا تريد ذلك استخدم السمات المتوفرة أو حالات الاختبار المجردة$testDbAcle = TestDbAcleTestDbAcle::create($pdo);$testDbAcle->runCommand(new TestDbAcleCommandsSetupTablesCommand($dbTablesToSetup));// استخدم هذا إذا قمت بتوسيع حالة الاختبار الخاصة بك من TestDbAclePhpUnitAbstractTestCase أو كنت تستخدم TestDbAclePhpUnitTraitsDatabaseHelperTrait:$this->setupTables($dbTablesToSetup);
يعرف إطار العمل نفسه الأعمدة غير القابلة للقيمة NULL في الجدول ويقوم بإدراج القيم الافتراضية... في الواقع، لنفترض أن الجدول table_name يحتوي على 30 عمودًا جميعها غير فارغة....
أيضًا، قد تكون هناك قيود مختلفة على المفاتيح الخارجية تحدث في الخلفية. يقوم Test-Db-Acle بتعطيل عمليات التحقق من المفاتيح الخارجية مؤقتًا، لذلك لا داعي للقلق بشأن هذا الأمر، أو بالترتيب الذي ندرج به بيانات الاختبار.
###ماذا عن الاختبار الفعلي.....؟### أولاً، إذا كنت تستخدم PHP5.4، فيمكنك استخدام إصدار السمات:
يمتد الفصل exampleTest PHPUnit_Framework_TestCase وينفذ TestDbAclePhpUnitAbstractTestCaseInterface {استخدام TestDbAclePhpUnitTraitsDatabaseHelperTrait؛ /** * يجب تنفيذ هذه الطريقة، ويجب أن تُرجع كائن PDO الذي سيتم استخدامه في تركيبات قاعدة البيانات * * @return Pdo */public function ProvidePdo() {return new Pdo("mysql:dbname=my_db_tests;host=localhost",'myTestUser', 'myTestPassword'); } /* * اختبار مثال */ الوظيفة العامة test_AddressService() {$this->setupTables(" [address] Address_id |company 1 |me 3 |أنت [user] user_id |name 10 |John 20 |Mary "); $this->setAutoIncrement('address', 100); $this->addressService->addEntry("them");$this->assertTableStateContains(" [address] Address_id |company 1 |me 3 |you 100 |them [user] user_id |name 10 |John 20 |Mary ", array()، "الأشياء تعمل"); } }
إذا كنت لا تستخدم السمات، فيمكنك استخدام AbstractTestCase
، ومع ذلك لن تتمكن من استخدام فئات الاختبار الأساسية الخاصة بك في هذه الحالة.
يمتد Class exampleTest إلى TestDbAclePhpUnitAbstractTestCase { protected $addressService;function Setup(){parent::Setup();$this->addressService = new ServicesAddressService(); }/** * يجب تنفيذ هذه الطريقة، ويجب أن تُرجع كائن PDO الذي سيتم استخدامه في تركيبات قاعدة البيانات * * @return Pdo */public function ProvidePdo() {return new Pdo("mysql:dbname=my_db_tests;host=localhost",'myTestUser', 'myTestPassword'); }وظيفة test_AddressService() {$this->setupTables(" [address] Address_id |company 1 |me 3 |أنت [user] user_id |name 10 |John 20 |Mary "); $this->setAutoIncrement('address', 100); $this->addressService->addEntry("them");$this->assertTableStateContains(" [address] Address_id |company 1 |me 3 |you 100 |them [user] user_id |name 10 |John 20 |Mary ", array()، "الأشياء تعمل"); } }
حسنًا، من الواضح أن ServicesAddressService غير موجودة هنا (مرحبًا، إنها للاختبار أولاً، أليس كذلك؟) والمثال بسيط للغاية.
في الحياة الواقعية، أود أن أضع طريقة getPdo في فئة اختبار أساسية مشتركة للمشروع وقد يتم الحصول عليها بشكل مختلف تمامًا عن هنا. لكن، حسنًا، هذا مثال.
كما ترون، يمكن لـ setupTables إعداد عدة جداول في وقت واحد ويمكن لـ AcceptTableStateContains التحقق من حالة الجداول المختلفة في نفس الوقت أيضًا.
على نحو مشابه لكيفية قيام setupTables بإعداد الجداول التي تحتوي على عدد أكبر من الأعمدة من تلك المحددة، يقوم AcceptTableStateContains فقط بمقارنة قيم الأعمدة المحددة وتأكيدها أيضًا.
أسهل طريقة لتثبيت Test-Db-Acle هي باستخدام الملحن ( اقرأ المزيد هنا: http://packagist.org )، وأنا أوصي بشدة باستخدام هذا الأسلوب، على الرغم من أنه يمكنك أيضًا فك ضغط الحزمة في مجلد وتمكين التحميل التلقائي لـ يتم ذلك يدويًا بأي شكل تريده (يستخدم اصطلاح التسمية psr-0)
لاستخدامه مع الملحن، أضف هذا إلى ملف الملحن.json الخاص بك:
"require": { "test-db-acle/test-db-acle" : "dev-master" }, "repositories" : [ { "type": "git", "url": "https://github.com/malteriesch/test-db-acle.git" } ]
يمكنك أيضًا استخدام https://packagist.org/packages/test-db-acle/test-db-acle إذا كنت تفضل ذلك.
المساهمات (والانتقادات) هي موضع ترحيب كبير...!
###كيفية تشغيل اختبارات Test-Db-Acle### لتشغيل الاختبارات، ستحتاج إلى إنشاء قاعدة بيانات فارغة على خادم MySql من اختيارك، ونسخ الاختبارات/Functional/config.php.dist إلى الاختبارات/ Functional/config.php وملء تفاصيل قاعدة البيانات الخاصة بك. وبعد ذلك، نأمل أن يتم إجراء جميع الاختبارات. (قاعدة البيانات مطلوبة في الواقع فقط لاختبار الدخان الوظيفي)
بناء الجملة ايندهوفن
AbstractTestCase
توسيع وتخصيص TestDbAcle
سجل التغيير