Как можно выполнить модульное тестирование в PHP, если используется слой ORM? - PullRequest
7 голосов
/ 05 апреля 2011

У меня есть класс, скажем, Персона.Слой ORM сгенерировал на основе структуры sql соответствующие объекты.У человека класса есть метод: Get ($ id).В методе Get вызывается объект Person и извлекаются поля из таблицы.

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

Как модульное тестирование должно работать в этом состоянии? Нужно ли создавать отдельную базу данных (только структуру) и делать создание / выбор из этой базы данных? Должен ли файл boostrap загружать ту же конфигурацию, что и используемый мной фреймворк, но изменять файл конфигурации, чтобы он работал с поддельной базой данных? Должен ли я очищать новую базу данных каждый раз после каждого теста?

Я также бродил после просмотра ваших ответов, если имитация ответа ORM без фактического создания новой базы данных не подходит?

Ответы [ 3 ]

8 голосов
/ 05 апреля 2011

Как модульное тестирование должно работать в этом состоянии?

Как правило, вы должны мысленно разделить свои тесты юнитов на две части:

  • одна часть вашего кода может тестироваться безбазы данных, так что вы можете заглушить или смоделировать методы, которые делают доступ к базе данных
  • , другая часть ваших тестов должна работать с базой данных, так как она проверяет, правильно ли используется ORM.

Нужно ли создавать отдельную базу данных

Это зависит от ваших потребностей.В приложениях Rails обычно есть «среды» тестирования / разработки / производства - базы данных, конфигурации, каталоги хранилищ.Тестирование предназначено для запуска модульных тестов, разработки для разработки и производства для запуска живого сервера.При разработке вы работаете с конфигурацией dev и, следовательно, с базой данных разработки.Для модульных тестов используется env-тестирование, которое дает то преимущество, что пользователи в базе данных не удаляются и не разрушаются.

Мне нравится эта концепция;в моих тестах phpunit у меня часто есть переключатель в начальной загрузке, который изменяет, какой файл конфигурации загружен.Просто помните, что ваша база данных разработки часто содержит больше данных, чем нужно для отдельного модульного тестирования, и вы, вероятно, создали эти данные вручную и не хотите их терять.Кроме того, другая база данных не стоит денег.

Должен ли я чистить новую базу данных после каждого теста?

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

4 голосов
/ 22 апреля 2011

Выезд Phactory . Я предпочитаю это расширениям базы данных, включенным в PHPUnit, и это позволяет легко вставлять записи в вашу тестовую базу данных.

require_once 'Phactory/lib/Phactory.php';

Phactory::setConnection(new PDO('sqlite:test.db'));

Phactory::define('user', array('name'  => 'Test User',
                               'email' => 'user@example.com'));

$user = Phactory::create('user'); // creates a row in the 'users' table

print("Hello, {$user->name}!"); // prints "Hello, Test User!"

Ваша тестируемая система (SUT) потребуется подключиться к тестовой базе данных. Идея состоит в том, что вы заполняете только те записи, которые вам нужны для метода, который вы тестируете. Уровень orm не должен иметь значения, если в тестовой базе данных есть все те же таблицы и поля, что и в вашей производственной базе данных.

3 голосов
/ 05 апреля 2011

PHPUnit также предоставляет некоторую помощь в этом, взгляните на Тестирование базы данных .

По сути, вы можете написать свои тестовые классы, чтобы они расширяли PHPUnit_Extensions_Database_TestCase, а затем использовали getConnection() и getDataSet() функции для загрузки данных для теста.

require_once 'PHPUnit/Extensions/Database/TestCase.php';

class PersonTest extends PHPUnit_Extensions_Database_TestCase
{
    protected function getConnection() {
        $pdo = new PDO('mysql:host=localhost;dbname=application_test', 'root', '');
        return $this->createDefaultDBConnection($pdo, 'application_test');
    }

    protected function getDataSet() {
        return $this->createMySQLXMLDataSet('person.xml');
    }

Затем вы можете точно определить, что вы хотите проверить в базе данных в XML.

Вы также можете утверждатьчто результирующий DataSet из ваших тестов равен ожидаемому:

public function testCreate() {
    // Execute some code with your ORM to create a person.

    $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet($this->getConnection());
    $actual->addTable('person');
    $expected = $this->createMySQLXMLDataSet('person_create_expected.xml');
    $this->assertDataSetsEqual($expected, $actual);
}

В этом примере мы сравниваем только результирующую таблицу person ... Таким образом, person_create_expected.xml должен содержать только таблицу person какну.

Для создания XML вы можете использовать mysqldump.

mysqldump --xml -t -u root -p application_test > person.xml
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...