Тестирование базы данных на PHP (PHPUnit, DbUnit)
Мне в своё время очень помогла разобраться с тестированием книжка Perl Testing: A Developer's Notebook. В подходе к тестированию особой разницы между Perl и PHP нет, так что Вам она тоже может оказаться полезна. Перевода, к сожалению, я по-быстрому не нашёл, возможно она есть только на английском.

При тестировании один из ключевых моментов — нужно постоянно очень хорошо отдавать себе отчёт в том, что именно мы сейчас тестируем. А тестируем мы обычно наш код, а не окружающую среду (вроде базы данных) — в тестах мы предполагаем, что база данных работает корректно, вопрос в том, корректно ли наш код работает с базой данных. Поэтому, да, можно тестировать работу с базой даже без самой базы — mock-нув функции отправляющие SQL-запросы в базу, и в тесте проверяя, что наш код генерирует именно те SQL-запросы, в том порядке и с теми значениями, которые он должен был сгенерировать (а заодно и подставляя тестируемому коду нужные нам данные под видом «ответа от базы на SQL-запрос»). И да, на реальной базе данных этот код может не работать корректно, не смотря на то, что тесты он проходит — просто потому, что он генерирует не те SQL-запросы, которые нужно генерировать для этого сервера БД. Но это не имеет отношения к тестам — они свою работу выполнили: подтвердили, что код работает именно так, как ожидается. А если задача была поставлена неверно, и код должен делать что-то другое — это проблема постановки задачи, а не тестирования.

Барабашка портящий базу — это не проблема тестирования кода. Хотите написать тест против барабашек — сравнивайте в тесте схему базы с эталонной, и правьте тест после любого изменения схемы базы. Но смысла в этом нет.

Совместимость фикстур из тестов с текущей схемой базы проверить очень просто: при запуске теста создавайте тестовую базу данных используя текущую схему основной базы данных, а в фикстурах храните только данные, без схемы таблиц.

Гемор с необходимостью постоянно поддерживать и корректировать тесты для совместимости с новым кодом — он есть, и его не может не быть. Но усилия, которые на это тратятся, с лихвой окупаются пользой от наличия тестов.
В дополнение к powerman
Я могу выделить такие ситуации:
1) тест функционала или классов, не имеющих сильной зависимости от внешних сервисов
2) тоже самое, но со слишком обширным использованием DAO
3) интеграционные тексты

В первом случае можно спокойно мокировать запросы в БД или иные внешние сервисы.
Во втором случае по возможности использую обертывание в транзакцию и откат в самом конце теста (методы setUp и tearDown). Если нельзя, то тоже самое что в п.3
В третьем случае делается всё «на живую» в девелоперской среде или использовать тестовую базу и естественно иметь скрипт генерирующий окружение.