Database Non-transaksional dan Pengujian Integrasi

8

Satu masalah yang saya pikir akan saya hadapi dengan pengujian integrasi saya adalah memiliki beberapa tes mengakses database yang sama. Meskipun ini bukan masalah sekarang, saya tahu kami memiliki beberapa aplikasi di sini yang mengakses database yang sama dan saya hanya mencoba memikirkan cara untuk mencegah masalah ini sebelum terjadi.

Sebuah ide yang saya lihat banyak menggunakan transaksi. Dalam memulai Anda memulai transaksi dan kemudian dalam teardown Anda mengembalikan transaksi. Ini berarti bahwa beberapa tes mengakses tabel database yang sama dan tidak akan saling mempengaruhi yang hebat. Masalah yang saya miliki adalah bahwa dalam kasus saya, 85-95% dari tabel yang saya gunakan di MySQL adalah MyISAM yang tidak mendukung transaksi.

Apakah ada cara untuk berkeliling mesin penyimpanan yang tidak mendukung transaksi tetapi masih memungkinkan beberapa tes untuk mengakses tabel yang sama tanpa mereka saling mempengaruhi? Dari apa yang saya dengar, ruby ​​on rails testing framework menggunakan transaksi dengan cara ini, bagaimana mereka mengatasi masalah ini (atau apakah mereka)?

ryanzec
sumber
Apakah Anda menjalankan tes secara bersamaan?
JeffO
Saya bisa. Saya tidak akan menjalankan tes simultan dari proyek yang sama tetapi kami memiliki beberapa proyek mengakses database / tabel yang sama. Saya dapat melihat 2 proyek menjalankan tes mereka secara bersamaan.
ryanzec
1
+1 Lebih sulit lagi jika Anda perlu menjalankan tes secara bersamaan.
KLE

Jawaban:

4

Di perusahaan saya, ada perdebatan: ketekunan adalah masalah besar untuk pengujian.

Ada beberapa peretasan yang akan membuat Anda setengah jalan. Kami memutuskan untuk tidak kehilangan waktu bersama mereka:

  • menggunakan Transaksi yang Anda kembalikan . Itu gagal sebagai:
    • Anda kadang-kadang membuka transaksi yang terisolasi (di dalam yang lebih umum), sehingga telah ditutup sebelum kode pengujian Anda bisa menguasainya
    • Anda tidak dapat menguji ketekunan Anda yang sebenarnya. (Apa yang terjadi ketika tes menutup satu transaksi, dan menjalankan kueri kompleks yang dipengaruhi oleh data itu dalam transaksi yang berbeda; atau menyimpan data, dan memuatnya lagi nanti.)
    • Anda tidak dapat menguji kode Anda sepenuhnya (hanya lapisan di bawah tingkat transaksi; tidak cukup baik jika Anda mempertimbangkan kelemahan pengujian integrasi).
  • menggunakan Database bersih segar untuk setiap tes . Itu juga gagal sebagai:
    • ruang tes kami akan segera mencapai beberapa ribu tes (kami memiliki tim besar). Menyiapkan Database baru membutuhkan menit terbaik (karena kami memiliki banyak katalog dan parameter yang merupakan bagian dari setiap versi). Test suite kami akan segera selesai berbulan-bulan, dan kami hanya bisa menunggu beberapa hari.
    • kita membutuhkan instance database spesifik untuk setiap pengembang, atau setiap mesin, dan memiliki kebijakan untuk meluncurkan hanya satu pengujian pada satu waktu. Kita perlu menggunakan Oracle 11 untuk memeriksa pertanyaan kita baik-baik saja, itu akan terlalu mahal (lisensi Oracle).
  • hati-hati membersihkan setelah setiap tes (kerangka kerja pengujian menyediakan kait untuk menjalankan kode setelah tes). Itu gagal sebagai:
    • sangat mahal untuk mempertahankan kecocokan yang sempurna antara kode itu does, dan mengujinya undoes. Segera setelah pertandingan tidak sempurna, gejalanya tidak jelas, tes mungkin gagal saat beberapa ratus baris kemudian; atau ujian yang seharusnya gagal bisa lulus dengan keliru.
    • selalu ada kasus tepi di mana pembersihan tidak benar (mesin atau perangkat lunak rusak?). Itu meninggalkan kondisi yang tidak diketahui untuk eksekusi selanjutnya.
    • ketika tes menunjukkan kesalahan, status basis data akan menjadi informasi penting, tetapi akan hilang (karena kami membersihkan sebelum tes berikutnya, untuk menyelesaikan suite tes dan menunjukkan pengembang informasi lengkap).

Jadi kami pindah ke kebijakan yang kami tahu valid:

  • memiliki Tes Unit otomatis untuk persyaratan kami :
    • jika diperlukan, akses database tiruan (tapi kita biasanya tidak membutuhkan JMock, saya bisa menjelaskan desain kami jika diminta).
    • tes dijalankan dengan kecepatan lebih dari 100 per detik
    • tes cepat untuk menulis, singkat dan jelas untuk dibaca.
    • tes tidak tergantung pada keadaan persisten, sehingga mereka sepenuhnya terisolasi satu sama lain secara alami (tidak diperlukan mekanisme yang kompleks)
  • uji mengintegrasikan dengan database secara terpisah (yaitu, permintaan dengan permintaan, tidak terintegrasi dengan logika aplikasi).
    • kami mempertimbangkan untuk mengotomatiskan tugas itu, tetapi tampaknya terlalu mahal (lihat bagian sebelumnya dari pos saya)
    • jadi kami menyimpan tes ini secara manual: setiap pengembang yang memodifikasi kueri diharapkan akan mengujinya lagi di basis data (yang biasanya merupakan bagian dari tes ujung ke ujung melalui antarmuka pengguna).
KLE
sumber
2

Bahkan jika Anda tidak memiliki "transaksi", dalam pengertian T-SQL, Anda harus tetap berusaha untuk melakukan transaksi Anda (dalam pengertian umum istilah) atom. Tes tidak harus bergantung pada satu sama lain dan harus dapat dibalik. Jika Anda tidak memiliki rollback resmi atau ruang lingkup transaksi, maka Anda mungkin ingin membuatnya sendiri. Misalnya, Anda bisa meminta unit test Anda melakukan pembersihan, di mana mereka menghapus semua catatan yang dibuat dalam tes.

Morgan Herlocker
sumber
Itu sudah terjadi tanpa transaksi (pada akhirnya, tabel hanya dikosongkan karena saya selalu memulai tes saya dengan tabel kosong) tetapi itu tidak menyelesaikan masalah beberapa tes yang berjalan pada saat yang sama. Jika saya menjalankan tes integrasi untuk aplikasi A dan aplikasi B pada saat yang sama dan mereka berdua memasukkan 10 catatan ke database.table_a, jika saya memiliki tes untuk memastikan bahwa 10 catatan ada dalam tabel tetapi saya mendapatkan hasil 10, tes akan gagal meskipun tes itu berhasil. Inilah kasus yang saya coba hindari.
ryanzec
@ryanzec - Saya tidak cukup ikuti. Jika Anda memiliki tes untuk memastikan bahwa 10 catatan ada di tabel dan Anda mendapatkan hasil 10, maka tampaknya tes akan lulus.
Morgan Herlocker
@ryanzec - Saya pikir saya mungkin melihat apa yang Anda maksud. Jika aplikasi A membutuhkan 10 catatan dalam tabel untuk lulus, tetapi aplikasi B memasukkan beberapa tambahan pada saat yang sama, sehingga uji A gagal. Dalam hal ini, Anda harus menulis tes Anda secara berbeda. Saya akan memberikan semacam nomor transaksi, sehingga saya tidak mencari 10 catatan dalam tabel untuk ujian, tetapi 10 catatan dengan nomor transaksi yang terkait.
Morgan Herlocker
0

Hanya memiliki setiap pengguna atau setiap run menimpa database yang digunakan. Itu yang kami lakukan di tempat kerja. Maka Anda tidak pernah memiliki masalah dengan 2 tes simultan yang saling mengganggu.

Kami meminta setiap uji coba membangun db dengan migrasi, mengisi db dengan fiting, dan kemudian merobohkannya kembali di akhir.

Jika DBMS mendukung transaksi, kami menggunakannya sebagai optimisasi untuk pengaturan awal dan pembongkaran. Mereka opsional, meskipun pengujian Anda dapat berjalan agak lama tanpanya. Seperti biasa YYMV.

Tanpa ribut, tidak ada muss.

dietbuddha
sumber