V
V
vetsinen2018-01-06 17:58:17
SQL
vetsinen, 2018-01-06 17:58:17

How to write unit tests for scripts that work with databases?

Good afternoon, please tell me what approaches exist if you need to test parts of a web application that work with the database by changing its contents, but which do not change the table structure

Answer the question

In order to leave comments, you need to log in

1 answer(s)
C
Cat Anton, 2018-01-06
@27cm

A test before running creates a clean database specifically for tests.
If the code is simplified, it looks like this:

protected function setUp() {
    parent::setUp();

    // Файл с дампом базы в tmp-директории
    $dumpFile = tempnam('path/to/project/local/test-tmp', 'autotests_dump_');

    // В начало файла с дампом пишем команды для пересоздания тестовой базы
    $sql = "DROP DATABASE IF EXISTS `autotests_dbname`;\n"
         . "CREATE DATABASE `autotests_dbname` DEFAULT CHARACTER SET = utf8;\n"
         . "USE `autotests_dbname`;\n";
    $this->exec('echo ' . escapeshellarg($sql) . ' > ' . escapeshellarg($dumpFile));

    // Делаем дамп с основной базы только структура таблиц, триггеры и т.п.
    // Это может быть локальная dev база.
    $this->exec('mysqldump --no-create-db --no-data --routines local_dev_dbname >> ' . escapeshellarg($dumpFile));

    // Добавляем в дамп файл bootstrap.sql c командами
    // для наполнения базы минимально необходимыми данными
    $this->exec('cat path/to/project/tests/bootstrap.sql >> ' . escapeshellarg($dumpFile));

    // Создаём тестовую базу
    $this->exec('mysql < ' . escapeshellarg($dumpFile));
}

private function exec($cmd) {
    exec($cmd, $out, $err);
    if ($err) {
        throw new Exception("Command execution failed: {$cmd}");
    }
}

Works pretty fast.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question