Как провести unit-тестирование setcookie() в php?

Какие сложности ждут вас при попытке провести юнит-тестирование методов, вызывающих setcookie().

Однажды, я писал код для класса, который определял, какой рекламный попап показывать пользователю. Алгоритм следующий — проверяем, есть ли в браузере куки А, если такой куки нет — показываем попап, А и сохраняем куки А. Если куки, А уже установлена, проверяем сохранена ли кука Б, и либо показываем попап Б и сохраняем куку Б, либо идём проверять существование куки С и так далее. Не самое изящное, но простое решение.

Строчка за строчкой, я дошёл до места в тестах, где предстояло проверить тот факт, что куки с правильными параметрами устанавливаются у пользователя. Тогда я не смог быстро найти решение, и положился на то, что функция setcookie () сработает как надо, если предоставить ей покрытые тестами параметры.

Сегодня мне показалось, что это любопытный вопрос. Как лучше протестировать setcookie ()? Как определить юнит-тестом, что произошла установка куки? Это возможно?

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

Очевидная проблема — в режиме командной строки, который обычно используют для запуска тестов функции, связанные с заголовками ничего не делают, провести такую проверку невозможно. Но если у вас применяется веб-интерфейс, который запускает юнит-тесты через браузер, то это становится реальным. В этом случае, проверка тривиальна — создаем новый метод assertCookieSet ($params, $headers) внутри которого проверяем наличие в заголовках строчки, сформированный по спецификации, которая должна появиться после вызова setcookie ().

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

На мой взгляд, юнит тестирование не может ответить нам на этот вопрос. Помимо технических ограничений, мы пытаемся проверить сайд эффект вызова функции, которые затрагивает не столько сам класс, сколько взаимодействие между нашим кодом и браузером пользователя. Гораздо лучше вместо юнит-тестирования в этом случае написать тестирование чёрного ящика. В конечном итоге, мне нужно, чтобы попапы появлялись в нужном порядке, а не в том, ставятся куки или нет. Поэтому в этом случае лучше написать тесты для Селениума или аналогов, где мы проверим нашу функциональность.

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

Стоит отметить ещё одну опасность setcookie (). Функция возвращает true даже если куки не могут быть установлены при вызовы через php-cli. False мы получаем либо в случае провала проверки на валидность некоторых параметров, либо в случае, если сделали вывод перед вызовом setcookie (). Вот определение функции на С:

Это означает, что если использовать возврат setcookie () без учёта контекста, у нас возникнет проблема и так делать нельзя:

Если этот метод коллега использует в скрипте для командной строки, никакого сохранения не произойдёт, что приведёт к ошибке. Это возможно, если код плохо прокомментирован, коллега не просмотрел исходный код или установка куки спрятана за слоями абстракций. В этом случае необходимо проверить серверное api или бросить исключение.

Функция setcookie — http://php.net/manual/ru/function.setcookie.php
Стандарт — https://tools.ietf.org/html/rfc6265

Цитата: Наука и искусство

Дональд Кнут об искусстве и науке.

Science is what we understand well enough to explain to a computer. Art is everything else we do.

Дональд Кнут в предисловии к книге A=B

knuth

Цитата: Три добродетели программиста

Ларри Уолл о добродетелях программиста.

Most of you are familiar with the virtues of a programmer. There are three, of course: laziness, impatience, and hubris

Ларри Уолл

larry_wall

Видео: программирование на арабском языке

Программирование на арабском языке.

Что такое Open Graph и какая от него польза

Что такое Open Graph и почему важно поддерживать его на своём сайте?

В 2010 году Фейсбук запустили протокол Open Graph. До внедрения протокола, Фейсбук знал о связях своих пользователей на своём сайте, но полной информации, что они делают на других сервисах не было. С помощью протокола социальная сеть создаёт и определяет связи между произвольными сущностями, не ограничиваясь лайками и профилями пользователей.

По задумке Фейсбука, это выглядит так — книжный сервис внедряет у себя протокол, даёт определения новой сущности — книги — и новую связь — прочтение. Я захожу на этот сервис и отмечаю, что прочитал «50 оттенков серого». Тут же книжный сервис отправляет информацию об этом в Фейсбук и у меня в ленте появляется обновление с текстом вроде «Дмитрий Ню прочитал 50 оттенков серого»». Если мой друг кликнет на такое сообщение, то он окажется на странице книжки. Причём, если он читает Фейсбук с телефона и у него установлено приложение книжного сервиса, то откроется приложение сервиса, а не браузер. Таким образом, Фейсбук знает, что мне продавать дополняет новой информацией социальные графы, сервисы получают трафик, а я ознакомил своих друзей с моими книжными вкусами.

Реальность оказалась скучнее и проще. Полный комплект взаимодействия с Фейсбуком внедрило не так много сайтов. Но оказалось, что если в минимальной форме реализовать протокол на странице, то у вас появлялся контроль над тем, как выглядит превью страницы, когда ты делишься ею в социальной сети. Вместо случайных картинок и текста, который алгоритм Фейсбука считал главным, стало возможным задать собственные.

opengraph2

Что же придумали инженеры самой большой социальной сети в мире, какие инновации помогают показывать нужную картинку товара вместо случайного баннера со страницы?

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

Опрятный пост в Фейсбуке это хорошо, но приносит ли это денежную пользу, стоит ли ради этого добавлять новые метатеги? Для каждого сайта, продающего товары или услуги существует значение конверсии — процент посетителей сайта, которые у вас совершили покупку. Чем понятней и удобней сайт сделан для потенциального клиента, чем представленные услуги точнее отвечают потребностям пользователя, тем больше этот процент.

Но на доход так же влияет и общее количество посетителей — если у вас 10 посетителей и процент конверсии 50%, вы получаете 5 клиентов. Если посетителей 1000, а конверсия 5%, то у вас 50 клиентов. Понятно, что следует работать и над увеличением конверсии и над привлечением новых посетителей.

Люди охотно кликают на красиво оформленные статьи и делятся ими с друзьями, поэтому внедрение и правильное использование open graph тегов поможет вам заполучить новых посетителей. Сегодня не один Фейсбук поддерживает протокол — поддержку реализовали сети ВК, Twitter, Google+, LinkedIn, Pinterest. При этом затраты на внедрение Open Graph минимальны — найти модули или библиотки для современных языков и фреймворков можно без труда:

Современные CMS либо умеют управлять метатегами, либо для них можно установить плагины, которые добавят такую возможность. В случае же, если вы внедряете Open Graph вручную или столкнулись с проблемой, то надо в первую очередь проверить страницу через специальный отладчик Фейсбука. Он покажет вам, какая информация о вашей странице содержится в кэше, какие проблемы обнаружены на странице.

opengraph3

Что такое Open Graph https://www.youtube.com/watch?v=4Q207Z-HkUo
Сайт протокола http://ogp.me/
Руководство Фейсбука https://developers.facebook.com/docs/sharing/webmasters#markup
Влияние тегов Open Graph на SEO https://www.quora.com/Do-OpenGraph-meta-tags-have-an-impact-on-SEO