Тестирование Phpunit с базой данных - PullRequest
13 голосов
/ 03 января 2011

Я пытаюсь немного сосредоточиться на модульном тестировании с использованием PHPunit.

Я нашел очень хороший учебник здесь http://blog.nickbelhomme.com/php/phpunit-training-course-for-free_282

Но я кое-что упускаю и пока не понимаю, как это сделать.

У меня есть пользовательМодуль, который поддерживает всю информацию о пользователях.И есть функция save, которая сохраняет пользователя в базе данных.Итак, у меня есть функция testFunction

public function testCanCreateUser()
{
    $userData = array(
        'userName'  =>  'User1',
        'firstName' =>  'Joey',
        'lastName'  =>  'Hendricks',
        'email'     =>  'Joey@hendricks.com',
        'password'  =>  'f$tfe8F'

    ); 
    $user = new Model_User($userData);
    $user->save();

}

Первый раз, когда я буду запускать свой тест, это будет работать.Поскольку база данных пуста.Но когда я запускаю свои тесты во второй раз, это не сработает, так как моя система не позволяет одному и тому же пользователю дважды войти в базу данных.Поэтому, чтобы сделать это, я должен заново создавать свою базу данных тестов каждый раз, прежде чем запускать свои тесты.Каков наилучший способ сделать это?Или эту проблему нужно решать по-другому?

Tnx.

Ответы [ 3 ]

22 голосов
/ 03 января 2011

Если вы хотите проверить свою бизнес-логику: Сделайте макет класса Database и верните поддельные данные

Если вы хотите протестировать класс, который запускает операторы sql (и imho, вы тоже можете это проверить, так как я хочу знать, работает ли мой код с реальным БД в бэкэнде), это немного усложняется, но есть способы сделать это:

  • Использование setUp () и tearDown () для получения согласованного состояния для ваших данных перед запуском тестов (imho) является хорошим способом написания тестов на базе db-управляемых модулей.Впрочем, писать множество пользовательских sql вручную может раздражать.

  • Чтобы облегчить жизнь, вы можете заглянуть в расширение DbUnit и посмотреть,работает для вашего приложения.

  • Если вы действительно хотите погрузиться в взаимодействия с базой данных Unittesting, то лучше всего прочитать тему (imho) в главе о тестировании db-unit в Книга phpqa Себастьяна Бергманна .

  • Может ли ваше приложение разрешить использование настраиваемого имени базы данных и автоматическую настройку всех таблиц, также возможно установить БД один раз смного тестовых данных и использовать эти данные во всех ваших тестах.Вы можете быть осторожны, так как один тест не зависит от данных, записанных другим.

10 голосов
/ 03 января 2011

Запустите тесты с другой копией базы данных, которая пуста и / или очищена в методах setUp() или tearDown(), но будьте осторожны, чтобы не делать то, что github сделал .

Если вы используете хорошую базу данных (т.е. не MySQL с таблицами MyISAM), вы можете заключить тест в транзакцию и откатить его после теста:

 function setUp() { $this->db->exec("BEGIN"); }
 function tearDown() { $this->db->exec("ROLLBACK"); }

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

В идеале вы должны использовать внедрение зависимостей и запускать тесты для поддельного класса базы данных:

$fakedb = new DatabaseThatDoesntReallySaveThings();
$user = new Model_User($fakedb, $userData);
$user->save();
$this->assertTrue($fakedb->wasAskedToSaveUser());
2 голосов
/ 03 января 2011

Я думаю, что вы можете использовать tearDown() метод для очистки ваших сохраненных данных.

protected $_user;

public function testCanCreateUser()
{
    ...

    $this->_user = new Model_User($userData);
    $this->_user->save();
}

public function tearDown()
{
    $this->_user->delete();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...