Saya mungkin bisa memberi Anda pengalaman kami ketika kami mulai melihat unit menguji proses tingkat menengah kami yang mencakup satu ton operasi "logika bisnis" sql.
Kami pertama kali membuat lapisan abstraksi yang memungkinkan kami untuk "memasukkan" koneksi database yang masuk akal (dalam kasus kami, kami hanya mendukung koneksi tipe ODBC tunggal).
Setelah ini di tempat, kami kemudian dapat melakukan sesuatu seperti ini dalam kode kami (kami bekerja di C ++, tapi saya yakin Anda mendapatkan idenya):
GetDatabase (). ExecuteSQL ("INSERT INTO foo (blah, blah)")
Pada waktu normal, GetDatabase () akan mengembalikan objek yang mengumpankan semua sql kami (termasuk kueri), melalui ODBC langsung ke database.
Kami kemudian mulai mencari di dalam memori database - yang terbaik tampaknya SQLite. ( http://www.sqlite.org/index.html ). Ini sangat sederhana untuk diatur dan digunakan, dan memungkinkan kami subkelas dan menimpa GetDatabase () untuk meneruskan sql ke basis data dalam memori yang dibuat dan dihancurkan untuk setiap pengujian yang dilakukan.
Kami masih dalam tahap awal ini, tapi sejauh ini terlihat bagus, namun kami harus memastikan kami membuat tabel apa saja yang diperlukan dan mengisinya dengan data uji - namun kami telah mengurangi beban kerja di sini dengan membuat satu set fungsi pembantu umum yang dapat melakukan banyak hal untuk kita.
Secara keseluruhan, ini sangat membantu proses TDD kami, karena membuat perubahan yang tampaknya tidak berbahaya untuk memperbaiki bug tertentu dapat memiliki dampak yang cukup aneh pada area lain (sulit dideteksi) pada sistem Anda - karena sifat sql / database.
Jelas, pengalaman kami berpusat di sekitar lingkungan pengembangan C ++, namun saya yakin Anda mungkin bisa mendapatkan pekerjaan serupa di bawah PHP / Python.
Semoga ini membantu.