За последние 24 часа нас посетили 35263 программиста и 1818 роботов. Сейчас ищут 2037 программистов ...

PHPUnit тестирование. Почему, зачем и как.

Тема в разделе "Прочие вопросы по PHP", создана пользователем Invision, 12 янв 2013.

  1. Invision

    Invision Активный пользователь

    С нами с:
    26 фев 2009
    Сообщения:
    1.437
    Симпатии:
    1
    Адрес:
    Томск
    Подключил PHPUnit в Kohana Framework, возникла необходимость протестировать ряд методов в модели и хелперы в проекте. Сейчас сижу и ломаю голову над PHPUnit, пытаюсь понять, есть ли возможность создать тест, который будет передавать в метод все возможные параметры значений (bool, array, object, int, float, null ..). Возможно я чего-то не понимаю.
    Как я вижу принцип работы тестов:
    Есть метод, в который передается к примеру id пользователя, внутри метода выполняется ряд действий. Метод может вернуть исключение в виде 404 ошибки если пользователь не обнаружен, да и вообще вернуть то, что сам и не ожидал получить:) Суть теста заключается в выявлении некорректного поведения метода. Если не прав поправьте. Да и вообще сейчас мало зная о PHPUnit, слабо себе представляю практическое применение.
    На русском языке не нашел достаточное кол-во примеров, возможно подскажут форумчане)
     
  2. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    в двух словах объяснить сложно. читайте статьи. их в нете куча.
    общая суть такая:
    вы создаете кучу тестов. каждый тест проверяет чтото одно. например в вашем случае нужно написать тесты на метод находящий юзера по ид. вы в самом тесте создаете необходимые объекты подключаете библиотеки. вызываете метод с заведомо правильным ИД юзера - те чтобы точно знать какого именно юзера должен вернуть метод. и проверяете реально ли нашел метод его или нет.
    второй тест на случай если такого юзера нет. все тоже. но прописываете ИД юзера которого точно нет в БД. и сраниваеете результат. если метод вернул исключение 404 как у вас - то все хорошо - иначе ошибка теста.
    третий тест, например, для случая когда передали вообще не ИД а какойто мусор. вы заранее знаете что ДОЛЖЕн вернуть метод в этом случае. и проверяете что он реально возвращает. ну и тд. тест на каждый конкретный случай.
    потом запускаете их все вместе. и сразу видно в каком именно тесте сработал ассерт. получается что нужно добиться от метода поведения такого - чтобы все тесты выполнялись корректно.
    по идее тесты начинают писать еще ДО написания самого класса. тоесть тесты уже есть и они все несрабатывают, везде ошибка. и вы далее начинаете реализовывать всю логику класса. запуская тесты иногда. и до тех пор пока все тесты не начнут выполнятся успешно.

    в будущем. если например будете чтото менять в коде метода, рефакторинг например или новый функционал добавлять. запуск тестов сразу покажет что и где сломалось.
     
  3. iliavlad

    iliavlad Активный пользователь

    С нами с:
    24 янв 2009
    Сообщения:
    1.689
    Симпатии:
    4
    Суть тестов - дать некоторую уверенность, что приложение ведёт себя согласно требований. как-то так.
    И как следствие - если ты чего-то не предусмотрел, то тесты не покажут этого, просто потому что они не написаны.

    Небольшой пример
    Код (Text):
    1.    
    2. <?php
    3.  /**
    4.      * Проверка захода пользователя с некорректным паролем
    5.      */
    6.     public function testIncorrectUserLoginAction()
    7.     {
    8.         $login = 'demo';
    9.         $password = 'demo2';
    10.  
    11.         $this->getRequest()
    12.             ->setMethod('POST')
    13.             ->setPost(array('login' => $login, 'password' => $password, ));
    14.         $this->dispatch('/login');
    15.  
    16.         $this->assertModule('default');
    17.         $this->assertController('login');
    18.         $this->assertAction('index');
    19.         $this->assertResponseCode(200);
    20.  
    21.         $this->assertQuery('#loginerror');
    22.         $this->assertNull(Zend_Auth::getInstance()->getIdentity());
    23.     }
    Зашёл пользователь с некорректным паролем. Проверяем, что вызвались нужный модуль, контроллер, действие, вернулся ответ с нужным кодом и сообщением об ошибке ('#loginerror') и др.

    В итоге, если я где-то что-то поменяю и оно каким-то боком коснётся информации об ошибке входа (пропадёт блок '#loginerror'), то я увижу это при выполнении тестов.

    Но конкретно в этом тесте я не увижу, если на странице появится вдруг какая-нибудь отладочная информация или пропадёт весь остальной шаблон.