Разработка через тестирование - модульное тестирование (в CakePHP) - PullRequest
4 голосов
/ 05 апреля 2011

У меня возникли проблемы с настройкой модульного тестирования в CakePHP, особенно при тестировании вставки / обновления базы данных. Допустим, у меня есть модель, которая примерно такая:

class User {
  var $name = 'User';

  function updatePassword($data) {
    return $this->updateAll($data);
  }
}

class UserTestCase {
  function testUpdatePassword() {
    $tmpData = array(
      'User' => array(
         'password' => sha1(uniqid('', true)) //dummy pass
    );

    $result = $this->User->updatePassword($tmpData);

    $this->assertTrue($result);
  }
}

У меня проблема в том, что в моем тестовом случае:

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

Этот пример может показаться немного надуманным (я мог бы сделать update в контроллере, не создав, например, метод дополнительной модели), но суть в том, что при тестировании обновления / вставки данные являются фиктивными и Данные, извлеченные из форм, могут отличаться, и выгоды, похоже, не перевешивают затраты.

Ваши подходы к TDD и модульному тестированию приветствуются, и было бы неплохо понять, какое покрытие вы обычно пытаетесь предоставить кейсам.

Приветствия

Ответы [ 3 ]

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

Кто-то однажды сказал, что юнит-тесты должны рассказать историю. Этот подход может помочь вам написать тесты, которые имеют смысл с точки зрения приложения, которое вы кодируете. Напишите описательные имена для каждого метода тестирования, например:

function testUpdatingInsecurePasswordShouldFail() {
    $data = array('User' => array(
        'password' => 'password'
    ));
    $result = $this->User->updatePassword($data);
    $this->assertFalse($result);

    $data = array('User' => array(
        'password' => ''
    ));
    $result = $this->User->updatePassword($data);
    $this->assertFalse($result);
}

Рассказав "историю" небезопасных паролей, вы можете написать код модели, чтобы пройти новый тест. Другой пример:

function testUpdatingStrongPasswordShouldSucceed() {
    $data = array('User' => array(
        // forget about hashing for the moment
        'password' => 'battery hoarse collect maple'
    ));
    $this->User->updatePassword($data);
    $result = $this->User->find('count', array(
        'conditions' => array(
            // making some assumptions about the test data here
            'User.username' => 'test_user1',
            'User.password' => 'battery hoarse collect maple',
        ),
    );
    $this->assertEqual($result, 1);
}

Обратите внимание, что мы делаем немного больше, чтобы убедиться, что обновление работает правильно. Когда среда тестирования начнет обнаруживать ошибки и регрессии, вы будете рады, что приложили дополнительные усилия.

Одним из преимуществ хороших описательных имен тестов является то, что теперь мы можем использовать опцию cake test --testdox для вывода результатов на понятном английском языке:

[x] Updating insecure password should fail
[x] Updating strong password should succeed
3 голосов
/ 05 апреля 2011

Преимущества TDD для меня (как только вы полностью обернетесь вокруг него):

  1. Я могу отлаживать свой код без браузера
  2. Если мой код зависит от различных частей моего кода, и я (или кто-то еще) вносит изменения, которые случайно нарушают что-то, что я успешно проверил ранее, мои автоматические модульные тесты немедленно поймают это
  3. (Личное). Это меняет мое представление о вводе - вместо того, чтобы вводить данные вручную в текстовое поле, я начинаю думать о вводе, который может исходить из сценария, а не из браузера, - действительно заставляет меня сосредоточиться на санации ввода более
  4. Автоматическое тестирование - после завершения работы системы я могу выполнить все моих тестов и выполнить их в считанные секунды, чтобы убедиться, что все работает, вместо того, чтобы пытаться выполнить всю систему вручную Это может занять несколько часов, в зависимости от сложности.
2 голосов
/ 05 апреля 2011

ddawber,

Вы упоминаете три пункта:

1

Я должен предоставить фиктивные данные, которые обычно извлекается из формы

Вы должны взглянуть на CakePHP светильники

2

Формат фиктивных данных не учитывает факт что фактические данные формы могут быть неправильно

Данные формы проверяются на соответствие правилам проверки модели, см. Здесь .

3.

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

Это должно быть просто решено путем написания метода тестирования (и вы выбираете только соответствующие случаи), принимая во внимание 1. и 2. Возможно, вас заинтересует тот факт, что разработчики CakePHP переключаются с самого простого на phpunit в версии 2.0, что может помочь вам планировать свои усилия.

В любом случае, удачного путешествия в испытательный центр CakePHP.

Edit0: Четвертый пункт о покрытии кода кажется спорным. Если бы вы выбрали 100% покрытие, вам нужно было бы написать множество фиктивных объектов, просто чтобы убедиться, что действие контроллера действительно вызывается при его вызове. Написание чего-то подобного является задачей для разработчиков среды, и отказ от написания лишнего кода такого рода напрямую затрагивает охват кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...