Praktik terbaik untuk tes unit di Magento 1.9

11

Saya memelihara situs Magento 1.9 dengan beberapa modul khusus. Beberapa fungsi sangat penting bagi bisnis dan sangat memerlukan beberapa unit test. Misalnya kalkulator harga satuan.

Saya biasanya mengembangkan di Symfony dan benar-benar lebih suka untuk entah bagaimana menggunakan PHPUnit (w / Komposer) jika itu memungkinkan.

Beberapa fungsionalitas didasarkan pada data yang diimpor ke beberapa tabel basis data khusus jadi saya lebih suka memuat perlengkapan.

Jadi saya mencari pendekatan praktik terbaik untuk menulis beberapa tes unit. Saya akan senang menerima tutorial atau yang serupa. Bantuan apa pun dihargai.

Frigg
sumber

Jawaban:

10

Saya menghadapi masalah yang sama beberapa waktu lalu.

Saya mempertimbangkan untuk menggunakan modul Ecomdev PHPUnit tetapi saya merasa sulit untuk menggunakannya dan tidak terdokumentasi dengan baik (tapi saya masih suka apa yang dilakukan Ivan dan kontribusinya yang besar pada ekosistem Magento).

Jadi, dengan bantuan Vinai, saya akhirnya mengembangkan modul kerangka uji berikut: https://github.com/digitalpianism/testframework

Tujuan awal adalah untuk tes integrasi tetapi saya menggunakannya untuk tes unit juga. Anda dapat melihatnya beraksi di sini: https://github.com/digitalpianism/easytoplinks/blob/master/app/code/community/DigitalPianism/EasyToplinks/Test/Unit/Block/Page/Template/LinksTest.php

Mengenai perlengkapan, saya menggunakan kembalikan transaksi untuk menghindari membuat data sampel dalam database.

Raphael di Digital Pianism
sumber
Ini terlihat sangat menjanjikan. Saya akan mencobanya. Terima kasih.
frigg
13

Instalasi

Karena Magento 1 tidak menggunakan komposer di luar kotak, saya tidak berpikir itu membuat perbedaan besar jika Anda menginstal phpunit menggunakan komposer atau hanya mengunduh versi phar .
Jika Anda sudah menggunakan komposer untuk mengelola modul atau pustaka pihak ketiga lainnya di situs Anda, maka komposer mungkin paling masuk akal. Kecuali jika Anda menggunakan PHP7, Anda akan terbatas pada versi lama phpunit (itu sebabnya saya ditautkan ke versi 4.8 di atas).

Tes Integrasi vs / dan / atau Tes Unit

Karena Magento 1 adalah aplikasi yang sangat berat, masuk akal untuk memisahkan bootstrap phpunit menjadi satu untuk integrasi dan satu untuk pengujian unit.
Bootstrap uji unit hanya perlu menginisialisasi autoloader, sedangkan bootstrap uji integrasi perlu menginisialisasi seluruh lingkungan aplikasi termasuk memuat konfigurasi dan koneksi db.
Karena itu tes integrasi di Magento cenderung berjalan jauh lebih lambat daripada tes unit (bahkan lebih dari itu di aplikasi lain).

Bootstrap Magento ke phpunit

  • Autoloader Magento tidak sesuai dengan PSR-0 karena melempar pengecualian jika tidak dapat menemukan file tempat kelas berada. Ini memecah beberapa penggunaan class_existsdi phpunit. Ada beberapa kemungkinan solusi (jika diretas):

    • Batalkan registrasi autoloader Magento, bungkus \Varien_Autoload::autoload()dengan dekorator dengan mengabaikan pengecualian yang dimasukkan, dan daftarkan bungkusnya sebagai autoloader baru. Ini memiliki kemungkinan konflik yang rendah dengan perpustakaan pihak ketiga yang mendaftar autoloaders dan bergantung pada urutan autoloader tertentu.
    • Gunakan penangan kesalahan khusus yang membungkus yang dibangun ke Magento 1. Penangan kesalahan khusus menelan kesalahan yang dipicu oleh autoloader Magento. Ini adalah solusi yang menggunakan kerangka uji Raphael . Tampaknya ini yang paling kompatibel dengan ekstensi pihak ketiga lainnya.
    • Gunakan hack jalur sertakan untuk mengganti \Varien_Autoload::autoload()agar tidak membuang kesalahan jika file tidak ada. Namun ini bertentangan dengan beberapa modul yang juga menimpa kelas yang sama. Saya tidak menggunakan pendekatan ini sendiri.
  • Untuk menghindari kesalahan dari sesi yang dimulai selama tes cukup atur $_SESSON = []di bootstrap.

  • Tetapkan objek respons khusus melalui Mage::app()->setResponse($testResponse)yang meluas yang asli tetapi tidak mengirim output atau header.

  • Untuk menginisialisasi ulang Magento antara tes integrasi yang sepenuhnya mengubah status runtime, gunakan Mage::reset(); Mage::app(). Perhatikan bahwa setelah itu penangan kesalahan harus didekorasi ulang.

Perlengkapan

Untuk DB fixture saya cenderung menggunakan model reguler dalam metode fixture untuk membuat fixture, misalnya createSimpleProduct($sku). Seperti yang dikatakan Raphael, gunakan setUp()dan tearDown()bungkus tes dalam transaksi yang dibatalkan setelah ujian (misalnya Mage::getSingleton('core/resource')->getConnection('default_setup')->beginTransaction()).

Untuk perlengkapan konfigurasi toko, saya cenderung mengatur perlengkapan yang hanya menggunakan memori Mage::app()->getStore()->setConfig($path, $value).

The EcomDev_PHPUnitekstensi juga menyediakan pilihan untuk membuat DB perlengkapan menggunakan file YAML, tapi untuk diriku sendiri aku menemukan orang-orang sulit untuk mempertahankan dibandingkan dengan perlengkapan dibuat menggunakan kelas model. YMMV.

Uji Ganda

Registri dapat digunakan untuk menyuntikkan tes ganda untuk objek yang dibuat melalui Mage::getSingleton(), Mage::getResourceSingleton()dan Mage::helper().
Beberapa objek pusat lainnya dapat diaktifkan Mage::app()(mis. Permintaan).
Untuk mengganti kelas yang dibuat melalui Mage::getModel()atau Mage::getResourceModel()dengan tes ganda, pembungkus objek konfigurasi kustom harus digunakan. Lihat contoh ini dalam kerangka uji Raphael bagaimana hal itu dapat dicapai.

Ringkasan

Setelah Magento di-bootstrap, hampir semuanya dapat diuji dengan baik. Bersiaplah untuk membuat tiruan yang dalam karena banyaknya metode chaining yang menggunakan kode inti.
Meskipun pengaturannya adalah peretasan, itu berfungsi dengan baik dan saya menemukan tes memberi saya banyak kepercayaan dan nilai, cukup sebanding dengan test suite untuk aplikasi Symphony.

Vinai
sumber
Saya tidak pernah mencobanya tetapi mengapa tidak menggunakan Magento Test Framework? ( docs.magento.com/m1/ce/user_guide/magento/… )
Fra
3
Ya saya sudah mencobanya, tapi ini pengujian fungsional (bukan unit atau integrasi), lambat, kompleks dan tes cenderung rapuh dan rapuh. Secara keseluruhan, saya menganggap waktu yang saya habiskan dengan itu sia-sia.
Vinai
@Vinai Saya tahu itu sudah terlambat, tetapi secara umum di controller ada panggilan untuk model dan koleksi, yang saat pengujian kita tidak perlu. Saya menggunakan kerangka Pengujian Anda (DigitalPianism), dan di sana kami dapat TestDouble model tetapi saat membuat permintaan untuk tindakan pengontrol yang pada gilirannya menggunakan model, bagaimana saya bisa mengejek model / panggilan koleksi?
arqam