Ich kann Ihnen vielleicht einen Vorgeschmack auf unsere Erfahrungen geben, als wir uns mit Unit-Tests für unseren Middle-Tier-Prozess befassten, der eine Menge SQL-Operationen mit "Geschäftslogik" umfasste.
Wir haben zuerst eine Abstraktionsschicht erstellt, mit der wir jede vernünftige Datenbankverbindung "einstecken" konnten (in unserem Fall haben wir einfach eine einzelne ODBC-Verbindung unterstützt).
Sobald dies geschehen war, konnten wir so etwas in unserem Code tun (wir arbeiten in C ++, aber ich bin sicher, Sie haben die Idee):
GetDatabase (). ExecuteSQL ("INSERT INTO foo (bla, bla)")
Zur normalen Laufzeit würde GetDatabase () ein Objekt, das alle unsere SQL-Daten (einschließlich Abfragen) über ODBC eingespeist hat, direkt an die Datenbank zurückgeben.
Wir haben uns dann mit In-Memory-Datenbanken befasst - das mit Abstand beste scheint SQLite zu sein. ( http://www.sqlite.org/index.html ). Es ist bemerkenswert einfach einzurichten und zu verwenden und ermöglicht es uns, GetDatabase () in Unterklassen zu überschreiben und zu überschreiben, um SQL an eine speicherinterne Datenbank weiterzuleiten, die für jeden durchgeführten Test erstellt und zerstört wurde.
Wir befinden uns noch im Anfangsstadium, aber es sieht bisher gut aus. Wir müssen jedoch sicherstellen, dass wir alle erforderlichen Tabellen erstellen und sie mit Testdaten füllen. Wir haben jedoch die Arbeitslast hier durch Erstellen etwas reduziert Ein allgemeiner Satz von Hilfsfunktionen, die all dies für uns erledigen können.
Insgesamt hat dies bei unserem TDD-Prozess immens geholfen, da das Vornehmen von scheinbar harmlosen Änderungen zur Behebung bestimmter Fehler seltsame Auswirkungen auf andere (schwer zu erkennende) Bereiche Ihres Systems haben kann - aufgrund der Natur von SQL / Datenbanken.
Natürlich haben sich unsere Erfahrungen auf eine C ++ - Entwicklungsumgebung konzentriert, aber ich bin sicher, dass Sie unter PHP / Python vielleicht etwas Ähnliches zum Laufen bringen könnten.
Hoffe das hilft.