Разработка через тестирование - модульное тестирование (в CakePHP)

У меня возникли проблемы с настройкой модульного тестирования в 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 и модульному тестированию приветствуются, и было бы неплохо понять, какое покрытие вы обычно пытаетесь предоставить случаям.

Приветствия

4 голоса | спросил dianovich 5 AMpTue, 05 Apr 2011 02:07:03 +040007Tuesday 2011, 02:07:03

3 ответа


0

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

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
ответил contrebis 5 AMpTue, 05 Apr 2011 06:19:36 +040019Tuesday 2011, 06:19:36
0

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

  1. Я могу отлаживать свой код без браузера
  2. Если мой код зависит от различных частей моего кода, и я (или кто-то другой) вносит изменения, которые случайно нарушают то, что я успешно проверил ранее, мои автоматические модульные тесты немедленно поймают это
  3. (Личное) Это меняет мое представление о вводе - вместо того, чтобы вводить данные вручную в текстовое поле, я начинаю думать о вводе, который может исходить из сценария, а не из браузера, - действительно заставляет меня сосредоточиться на санации ввода более
  4. Автоматическое тестирование - после завершения работы системы я могу выполнить все своих тестов и выполнить их в считанные секунды, чтобы убедиться, что все работает, вместо того, чтобы пытаться пройти через всю систему вручную, что может занять несколько часов, в зависимости от сложности.
ответил Demian Brecht 5 AMpTue, 05 Apr 2011 02:28:05 +040028Tuesday 2011, 02:28:05
0

ddawber,

вы упомянули три момента:

1.

  

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

Вам следует ознакомиться с приспособлениями CakePHP

2.

  

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

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

3.

  

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

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

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

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

ответил benjamin 5 AMpTue, 05 Apr 2011 09:59:07 +040059Tuesday 2011, 09:59:07

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132