Pull to refresh

Comments 12

Спасибо! все время лень было разбираться с этим PHPUnit (в первую очередь из-за того, что не понимал, как тестировать данные из БД), но сейчас вижу, сколько времени он может сэкономить.
У меня вопрос. В конструкторе класса инициализируется сессия и устанавливаются cookies.
if (!session_id()) session_start();
if(empty($_COOKIE['user_unid'])) setcookie(«user_unid», 'asd');

При выполнении теста возникает ошибка (из-за того, то phpunit вывод начинает раньше)
Cannot modify header information — headers already sent

Как в этом случае поступить?
мне кажется, надо старт сессии в тесты вписать, можно в конструктор, или в самый первый тест (ведь сессия тоже может и не стартануть), от которого все остальные зависят…
Я не полностью видимо сформулировал вопрос. Как быть с любыми заголовками (header), если они должны выдаваться в конструкторе класса?
Как варианты мной придуманные:
1) Отлавливать exception (как то не правильно)
2) В параметрах конструктора прописывать переменную $testing (но тогда как быть, если эти заголовки действительно нужны для теста)
3) Может как то отключить вывод сообщений самим phpunit до момента создания объекта тестируемого класса (не знаю как)
4) Как то отделить поток вывода класса от потока вывода теста (тоже не знаю как)
Больше пока ничего в голову не лезет.
Есть несколько способов:

1. Dependency Injection
Самый частый ответ в подобных топиках :)
Инициализируйте сессию в «боевом» коде и передавайте результаты в конструктор. В тесте просто передавайте список в конструктор.
Так даже намного удобней так как можно использовать @dataprovider.

Боевой код:

session_start();
$class = new Class_A($_SESSION);

Тест:
$Session_test = array(smth...);
$class = new Class_A($Session_test);

2. Использовать метод setUpBeforeClass().
Он запускается один раз перед всеми тестами. Но так вы далеко не уедете, ведь надо тестирова с разными данными в сессии :)

Метод 1 универсален и используется на пример при тестировании сингтонов.
Мне кажется что у вас проблемы с тестами. Заголовки мешать не должны. Сделайте метод и пускай он возвращает код в зависимости от инфы.
Если вы хотите протестировать файловую систему то есть отдельные тесты,
глава 11
Mocking the Filesystem
Stubbing and Mocking Web Services (WSDL)
Правильный вариант — не использовать session_start() и _COOKIE. Это только в php работают напрямик с такими функциями, во всех нормальных языках и фреймворах для сессий и куков есть отдельные объекты, которые при тестах подменяются на поддельные.
Используйте ob_start() перед началом тестирования. Весь поток вывода будет накапливаться в буфере и сбросится после завершения работы скрипта.
Жаль что phpunit.ru был у hosting.ua… Теперь и не почитать русской документации =\
Вот вроде бы с одной стороны и нужны тесты, писать проверять краевые условия и механизм работы, но с другой стороны для более менее серьезных дел, тесты писать становиться довольно сложнее, а следовательно человеко-часов тратится больше.
С одной стороны да, так правильнее и лучше, с другой стороны дешевле нанять 1-2 тестеров, которые бы проверяли функционал кодера, а кодер занимался бы уже другими делами.

Все выше сказанное естественно имхо.
Автоматические тесты — это не только разовая проверка, это еще и существенная помощь при рефакторинге.
Тесты должны сохранять деньги и время, но не наоборот.

На примере безопасности:
1. У вас на сайте нашли инъекцию через форму. Вы профиксили и сделали тест.
2. У вас снова нашли инъекцию с китайской точкой. Вы профиксили и тоже сделали тест.
3. Появляется мистическое японское тире.

Вы можете представить человека, который сделает такие тесты? :) Кстати человек сможет проверить далеко не все варианты.

Вспомните графы и способы обхода и поиска в них. Тесты это те же самые графы.

Тут вот много писалось про говнокод. Написать говнотест гораздо проще :)
Собсно пример был к тому, что тесты позволяют исключить вероятность второго появления одной и той же ошибки в релизе. Даже если вы про эту ошибку давно уже забыли :)
Sign up to leave a comment.

Articles