Saya benar-benar bingung ketika saya melihat banyak implementasi database dalam-memori yang digunakan untuk pengujian, karena saya juga mendengar banyak dari pengujian integrasi praktik terbaik bahwa lingkungan yang menjalankan pengujian harus semirip mungkin dengan lingkungan produksi, termasuk sistem operasi , perpustakaan, mesin basis data, dll.
Apa yang kulewatkan di sini?
Jawaban:
Dalam situasi pengembangan perangkat lunak yang khas, tes digunakan pada dua titik: selama pengembangan, dan sebelum memindahkan produk di sepanjang rantai pengembangan.
Situasi pertama, menjalankan tes selama pengembangan, melayani tujuan jangka pendek: mendefinisikan tugas (seperti dalam TDD: menulis tes gagal, lalu lulus), mencegah regresi, memastikan perubahan Anda tidak merusak hal lain, dll. Seperti tes harus sangat cepat: idealnya, seluruh rangkaian tes Anda berjalan dalam waktu kurang dari 5 detik, dan Anda bisa menjalankannya dalam satu lingkaran di sebelah IDE atau editor teks saat Anda membuat kode. Setiap regresi yang Anda perkenalkan akan muncul dalam hitungan detik. Menjalankan tes cepat lebih penting dalam fase ini daripada menangkap 100% regresi dan bug, dan karena tidak praktis (atau tidak mungkin) untuk mengembangkan salinan sistem produksi yang tepat, upaya yang diperlukan untuk mencapai pengujian sempurna di sini tidak layak Itu. Menggunakan basis data dalam memori adalah pertukaran: mereka bukan salinan persis dari sistem produksi, tetapi mereka membantu menjalankan tes di bawah batas 5 detik; jika pilihannya adalah antara pengaturan basis data yang sedikit berbeda untuk pengujian terkait database saya, dan tidak ada pengujian sama sekali, saya tahu apa yang saya pilih.
Situasi kedua, memindahkan kode sepanjang rantai pengembangan, bagaimanapun, tidak memerlukan pengujian ekstensif. Karena kita dapat (dan harus) mengotomatiskan bagian dari proses pengembangan ini, kita dapat melakukan banyak tes yang lebih lambat - bahkan jika uji coba penuh membutuhkan waktu berjam-jam, menjadwalkan pembuatan malam masih berarti kita selalu memiliki gambaran akurat tentang basis kode kemarin. Mensimulasikan lingkungan produksi seakurat mungkin adalah penting sekarang, tetapi kita dapat membelinya. Jadi kami tidak melakukan trade-in-memory-database: kami menginstal versi yang sama persis dari DBMS yang sama persis dengan sistem produksi, dan jika mungkin, kami mengisinya dengan data produksi aktual sebelum pengujian dimulai.
sumber
Saya kira ini adalah trade-off speed / pencocokan lingkungan. Tes harus sering dijalankan, dan itu berarti mereka harus cepat. Terutama tes unit, yang seharusnya tidak lebih dari beberapa detik.
Tes integrasi akan berjalan lebih lambat, tetapi ketika mereka cepat Anda dapat menjalankannya lebih sering. Misalnya, sebelum setiap komit. Tentu saja, ini tidak selengkap lingkungan penuh, tetapi setidaknya Anda menguji lapisan pemetaan, SQL yang dihasilkan, bagaimana bagian berbicara satu sama lain, dll. Dalam kasus database mahal Anda juga memastikan bahwa Anda tidak tidak perlu membeli lisensi untuk semua orang. Anda mungkin menemukan lebih banyak kesalahan yang mencakup 90% kode dengan tes berjalan sekali per jam daripada mencakup 100% pengujian kode sekali per hari atau terburuk, seminggu.
Yang sedang berkata, tentu saja Anda perlu tes dengan database nyata dan lingkungan yang sepenuhnya terintegrasi. Anda mungkin tidak menjalankan tes itu sesering mungkin, tetapi karena tes sebelumnya sudah memberi Anda kepercayaan diri, yang tersisa hanyalah bug khusus platform aneh.
sumber
Untuk melakukan tes sederhana, mengejek lapisan akses basis data sangat dapat diterima. Anda menyebut
getName()
, itu menyebut DAO yang telah diejek dan mengembalikan "John" untuk nama depan dan "Smith" untuk nama belakang, mengumpulkan mereka dan semuanya sempurna. Tidak perlu benar-benar menguji unit database di sana.Banyak hal menjadi lebih ketika logika menjadi sedikit lebih kompleks. Bagaimana jika Anda memiliki metode "createOrUpdateUser (...)". Jika Anda mengolok-olok database Anda dapat memverifikasi bahwa metode yang diberikan telah dipanggil sekali dengan parameter tertentu ketika tiruan itu tidak mengembalikan objek dan metode yang berbeda dipanggil pada database ketika itu mengembalikan kembali objek yang sudah ada. Ini mulai sampai ke garis fuzzy di mana mungkin lebih mudah (terutama jika sudah ada di sana) untuk memutar spesialisasi dalam database memori dan menguji kode itu dengan data yang telah dikonfigurasi.
Dalam beberapa kode aktual yang saya kerjakan (point of sales), kami memiliki
resumeSuspededTransaction(...)
metode. Ini akan menarik transaksi dari database ke objek (dan komponennya) dan memperbarui database. Kami telah mengejek dan bug mengintai di suatu tempat kode dengan serialisasi dan deserialisasi data pergi ke database (kami mengubah jenis yang diserialisasi berbeda pada database).Mock tidak menunjukkan bug kepada kami karena ia mengembalikan jalannya yang bahagia - membuat serial transaksi, menyimpannya di mock, membatalkan deserialisasi dari mock, menguji bahwa mereka sama. Namun, ketika Anda membuat cerita bersambung suatu objek dengan nol di depan untuk basis data, ia menjatuhkannya lalu menggabungkannya kembali ke string tanpa nol. Kami menangkap bug tanpa database melalui pemecahan masalah (tidak sulit dikenali begitu kami tahu ada di sana).
Kemudian, kami menempatkan database di sana dan menyadari bahwa bug tidak akan pernah bisa melalui tes junit jika kami malah pergi ke dalam database memori.
Dalam database memori memiliki kelebihan:
sumber
Ini sangat tergantung pada sistem database yang Anda gunakan. Ketika sistem db Anda memberi Anda sebuah alternatif dalam memori yang hampir 100% API dan perilaku kompatibel dengan konfigurasi basis data berbasis disk (kecuali untuk kecepatan dan beeing failafe, atau tentu saja), maka menggunakan varian dalam memori jelas baik-baik saja .
Namun, jika sistem DB Anda memiliki perbedaan yang signifikan antara konfigurasi dalam memori dan penggunaan non-dalam-memori, Anda benar: dalam hal ini tes integrasi memiliki risiko lebih tinggi membayangi bug. Tetapi meskipun begitu, Anda mungkin dapat "memisahkan perbedaan itu" sendiri, mengingat Anda mengenal sistem DB Anda dengan baik dan perbedaannya.
sumber
Dalam kata-kata awam:
Mengejek bagian-bagian penting dari arsitektur adalah OK (dan harus) untuk pengujian unit .
Tetapi untuk pengujian integrasi, saya sangat setuju dengan Anda. Mengejek tidak boleh dilakukan dan lingkungan yang semirip mungkin dengan yang asli harus disediakan.
Lagi pula, tes integrasi adalah tentang menguji bagaimana berbagai bagian arsitektur berperilaku bersama.
sumber