Tes unit adalah bagian penting dari setiap proyek yang cukup besar. Saya ingin berbagi dengan Anda kisah detektif kecil terkait dengan kejatuhan massal mereka yang tidak jelas.
Ini dimulai dengan fakta bahwa sebagai akibat dari komitmen tidak berbahaya tertentu, sekitar 150 tes jatuh dalam proyek, sementara serangkaian uji jatuh tidak stabil. Tes tidak saling berhubungan, tes dilakukan berurutan. Database h2 dalam memori digunakan sebagai sumber data untuk pengujian. Jatuhnya sebagian besar dari 150 tes ini disertai dengan kesalahan dalam log: "Tidak bisa mendapatkan koneksi, kesalahan pool Timeout menunggu objek menganggur". Harus dikatakan bahwa ukuran kumpulan koneksi saat melakukan tes dalam proyek adalah 1.
Penyimpangan liris kecil: dalam kode proyek, transaksi terputus dari aliran secara berkala, kemudian kode dieksekusi dalam transaksi terpisah dan, akhirnya, transaksi di-backlink. Untuk kasus-kasus seperti itu, kelas pembantu telah ditulis, penggunaannya terlihat seperti ini:
TransactionRunner.run(dbDataManager(), new MethodTransaction() { @Override public ExecutionResult runInTransaction() throws Exception {
Sebagai hasil dari analisis, terungkap bahwa kesalahan mulai muncul setelah tes gagal yang berisi panggilan kode dalam transaksi:
TransactionRunner.run(dbDataManager(), new MethodTransaction() { @Override public ExecutionResult runInTransaction() throws Exception {
Lihatlah di dalam kelas TransactionRunner, panggilan metode mengarah ke kode berikut:
protected ExecutionResult run() throws CommonException { Transaction outerTr = getThreadTransaction(); bindThreadTransaction(null); try { beginTransaction(); try { setResult(transactionCode.runInTransaction()); } catch (Exception e) { dbDataManager().rollbackTransaction(); if (transaction.onException(this, e)) throw e; } dbDataManager().commitTransaction(); return getResult(); } catch (Exception e) { throw ExceptionUtil.createCommonException(e); } finally { bindThreadTransaction(outerTr); } }
Jadi apa masalahnya di sini? Dan masalahnya adalah bahwa AssertionError yang muncul sebagai akibat dari eksekusi kode tes tidak diwarisi dari Pengecualian, yang berarti bahwa transaksi bersarang tidak dibatalkan atau dilakukan. Karena ukuran kumpulan koneksi sama dengan satu, kami mendapatkan kesalahan yang sama "Tidak bisa mendapatkan koneksi, kesalahan pool Timeout menunggu objek idle" ketika mencoba untuk mendapatkan objek Koneksi dengan tes berikutnya.
Moral: perlu untuk menempatkan pernyataan dalam tes dengan hati-hati, dan dalam kasus yang tidak jelas dan, khususnya, crash massal, salah satu solusi adalah untuk memeriksa apakah penanganan pengecualian memperhitungkan objek akun yang tidak diwarisi dari Pengecualian.
Baginya bagiku layak fiksasi, mungkin pengalaman ini bermanfaat bagi seseorang.