Как сделать тест на php
Как сделать тестирование на сайте
В сегодняшней статье собираюсь поведать, как сделать тестирование на сайте. Данное тестирование будет аналогично тому, которое имеется на данном сайте, правда, в упрощённом виде. Сразу говорю, если Ваши знания по PHP и MySQL стремятся к нулю, то можете не читать, а лучше поищите в Интернете готовые скрипты тестов. Для тех же, кто обладает необходимым минимумом, а также хочет узнать, как реализуется тестирование на сайте, я и написал данную статью.
Привожу алгоритм, который Вам потребуется уже преобразовать в PHP+MySQL:
Давайте разберём 3-й пункт с кодом:
Теперь давайте разберём 5-й пункт, так как он тоже является, возможно, не совсем понятным:
Самую суть я разобрал, а уже дальше постарайтесь этот алгоритм применить на практике самостоятельно. Ведь не секрет, что придумать алгоритм гораздо тяжелее, чем его реализовать, и Вам нужно лишь его реализовать, а это не так сложно. Не спорю, алгоритм весьма сложный, но я предупредил вначале статьи, что она не для новичков. И несмотря на то, что алгоритм сложный, в реальности он ещё сложнее может быть, если начать добавлять различные «навороты«, например, разбор вопросов в конце, а также каждый раз перемешивать варианты ответов при выводе вопроса.
Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!
Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.
Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления
Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.
Порекомендуйте эту статью друзьям:
Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):
Комментарии ( 25 ):
Добавьте результат этого скрипка с рисунком??
Результат здесь: http://myrusakov.ru/tests.html В любой тест заходите вот и будет результат, за вычетом того, что в конце данного скрипта нет разбора вопросов.
Да. Было бы не плохо, если бы появились пункты со скринами, или допустим со ссылками для переходу, где можно было бы просмотреть итог.
Здесь люди учатся, а не занимаются копипастом. Если Вам нужен готовый скрипт, то я, помнится, написал в статье, что нужно делать в этом случае. А если Вы пришли сюда учиться, то, будьте любезны, додумайте задачу сами.
Михаил скажите пожалуйста как мне вытащить все вопросы по определенной теме допустим где test_id=3
Уважаемый Андрей,id каждого вопроса теста не должны повторяться. Можно сделать категорию,занести в неё нужные вам тесты,задать ей id,например,3 и при помощи запроса вытащить все данные из неё.
Уважаемый Александр Альт если Вам не сложно помогите мне пожалуйста я php знаю на среднем уровне до темы регулярные выражения (учусь по курсу Михаила)но мне срочно нужно сделать тестирование поможете сопровождая меня советами?
на данный момент я вывел из базы тему теста вопрос теста и варианты ответа вот файл testing.php а вот файл select_testing.php
Здравствуйте Андрей. Пустое поле в таблице не как не повлияет на работу в целом. Чтобы выводился следующий вопрос из таблицы читайте внимательно пункты 2-7 и делайте по аналогии.
Здравствуйте а можно как то обойтись без сессий? я их еще не изучал а тупо копировать я не хочу так как потом сам же не разберусь в коде в случае чего
Андрей, в сессиях нет ничего страшного, изучайте их так как они очень важные. Сделать это без сессий, Вам будет не возможно.
Скажите как сделать так чтобы при нажатии следующий вопрос выводился следуший вопрос? если можно пример пожалуйста
Лучше реализовать одной кнопкой «Ответ» и после ее нажатия, пользователю автоматически подается следующий вопрос. Реализовать можно множеством способов, зависит от того, как у Вас работает система, можно AJAX’ом допустим.
пример из двух файлов, форма отправки находится в файле form.php, а обработчик в файле add.php. Файлы Вы можете конечно называть как вам угодно, лишь придерживаясь правильности именования файлов и правильно указывайте путь к обработчику. Создайте form.php и добавьте следующий код: Затем, создайте add.php и в него добавьте следующее: Затем, запустите form.php и увидите результат работы передачи данных методом GET.
у меня все получилось но все вопросы выводятся на одной странице как это исправить?
Как я реализовывал А/Б-тестирование на PHP
Возникла задача проведения сплит-тестирования нашего интернет-магазина. Погуглил на эту тему. Нашел пару сервисов, но по тем или иным причинам они нам не подошли.
Например, использование тестирования через google analytics не подошло, т.к. мы для ведения статистики используем яндекс.метрику и встраивать еще одну аналитическую систему в сайт не хочется. И к тому же я так понял, что с гуглом есть проблема при тестировании динамических страниц или каких-то их элементов.
Другие сервисы, типа abtest.ru (который, кстати, почему-то не работает) или подобных ему, тоже не подходят, т.к. там можно изменить лишь внешний вид чего-либо. А нам, например, нужно протестировать сайт на предмет вывода/не вывода той или иной информации из базы (ну как пример, выводить ли краткое описание товара в списке товаров или еще выводить спецификации и т.д.).
Решил попробовать реализовать А/Б-тестирование собственными силами, дописав в сайт немного php-кода (интернет-магазин самописный, на php).
Необходимо проверить как будет действовать на конверсию изменение того или иного элемента сайта. Т.е. всех посетителей сайта условно делим на «посетителей-А» и «посетителей-Б». Делим естественно поровну, т.е. каждый первый – это «А», каждый второй – это «Б». В зависимости от того «А» это или «Б», показываем ему соответствующий вариант элемента сайта. По окончании фиксируем оформил ли посетитель заказ или нет
Код описывать не буду, а лишь кратко поясню что и как делал:
По сути получается довольно простой код. Но это и пугает. Кажется что я не учел какие-то тонкости и нюансы процесса А/Б тестирования и все гораздо сложнее и глубже. Ведь возможны различные спорные ситуации. Например, как учитывать посетителей, которые зашли на сайт, затем сайт покинули и снова вернулись? Показывать ли им при повторном посещении сайта тот вариант тестируемого элемента, который им был показан при первом посещении, или же заново учитывать этого посетителя в очереди чередования. И тут уже встает вопрос использования не механизма сессий, а механизма cookies.
Я написал этот пост чтобы поделиться своей реализацией простейшего А/Б – тестирования и заодно выслушать мнения специалистов по этому поводу. Может будут какие подсказки, замечания и т.д.
Как писать легко тестируемый и поддерживаемый код на PHP
Разнообразные фреймворки предоставляют инструменты для быстрой разработки приложений, но зачастую они способствуют накоплению технического долга также быстро, как позволяют создавать функциональность.
Технический долг появляется, когда сопровождение не является главной целью разработчика. Будущие изменения и отладка кода становятся затруднительными в связи с недостаточным модульным тестированием и непроработанной структурой.
В этой статье вы узнаете, как структурировать ваш код так, чтобы достичь простоты тестируемости и сопровождения – и сэкономить ваше время.
Давайте начнем с несколько выдуманного, но типичного кода. Это может быть класс в любом заданном фреймворке:
Этот код будет работать, но требует некоторых улучшений:
1. Этот код не тестируемый.
2. Данный код не такой поддерживаемый, каким бы мог быть.
Например, если мы изменим источник данных, нам нужно будет изменять код базы данных при каждом использовании App::db в нашем приложении. Кроме того непонятно, как быть в случае, когда мы хотим использовать не просто информацию о текущем пользователе?
Предпринятый модульный тест
Здесь приведена попытка создания модульного теста для функционала, описанного выше:
Для того чтобы этот модульный тест работал, нам нужно сделать следующее:
Что ж, давайте перейдем к тому, как это можно улучшить.
Придерживаемся принципа «Не повторяйся»
Этим методом мы можем пользоваться во всем нашем приложении. Мы можем передать текущего пользователя в вызове функции, вместо того, чтобы внедрять данный функционал в нашу модель. Код становится более модульным и поддерживаемым, когда перестает зависеть от других функциональных единиц (например, глобальной переменной сессии).
Однако он все еще не такой легко тестируемый и поддерживаемый, каким бы мог быть. Мы до сих пор полагаемся на соединение с базой данных.
Внедрение зависимости
Давайте поправим ситуацию путем добавления некоторых зависимостей. Здесь показано, как может выглядеть наша модель, если мы поместим соединение с базой данных в класс:
Теперь зависимости для нашей модели User обеспечены. Наш класс больше не предполагает наличие определенного подключения к базе данных, и не полагается на какие-либо глобальные объекты.
На данный момент наш класс в целом тестируемый. Мы можем передать источник данных согласно нашему выбору (по большей части) и идентификатор пользователя и протестировать результаты вызова. Также мы можем переключать соединение к нашим отдельным базам данных (предполагая, что обе базы реализуют одинаковые методы извлечения данных). Круто!
Давайте посмотрим, как выглядит модульный тест сейчас:
Я добавил кое-что новенькое в этот модульный тест: фиктивную реализацию. Фиктивная реализация позволяет нам имитировать (фальсифицировать) PHP объекты. В данном случае мы осуществляем фиктивную реализацию подключения к базе данных. С нашей « заглушкой » мы можем пропустить тестирование подключения к базе данных и просто проверить нашу модель.
Хотите узнать больше о фиктивной реализации?
Таким образом, решаются несколько проблем:
Но мы все еще можем сделать наш код гораздо лучше. С этого места начинается самое интересное.
Интерфейсы
Для дальнейшего улучшения мы можем определить и реализовать интерфейсы. Рассмотрим следующий код:
Здесь происходит несколько вещей.
Что мы имеем в результате?
А еще мы упростили наш модульный тест!
Но мы все еще можем сделать код лучше!
Контейнеры
Рассмотрим использование нашего текущего кода:
Я переместил создание модели User в одно место в конфигурации приложения. В результате:
Заключительное слово
В нашем уроке мы выполнили следующее:
Я уверен, вы заметили, что мы добавили намного больше кода для достижения простоты обслуживания и тестируемости. Сильный аргумент против такой реализации – увеличение сложности. В самом деле, для этого требуется более глубокое знание кода, как для основного разработчика, так и для остальных участников проекта.
Однако, затраты на объяснение и понимание кода с лихвой окупаются снижением технического долга.
Код стал значительно более легким в обслуживании, представилась возможность производить изменения всего в одном месте, а не в нескольких.
Возможность быстро проводить модульное тестирование снизит количество ошибок в коде со значительным отрывом – особенно в долгосрочных или разрабатываемых в сообществе (с открытым исходным кодом) проектах.
Проделывая дополнительную работу сейчас, мы сэкономим время и освободимся от головной боли в будущем.
Источники
Затем вы можете установить ваши зависимости, основанные на Composer, со следующими требованиями:
При использовании PHP фреймворка Laravel 4 применение контейнеров и других идей, описанных здесь, носит исключительно важный характер.
Как создать онлайн тест на php
Иногда людям не знающим программирования, нужно создать онлайн тест на php для своего сайта, на самом деле все очень просто, постараюсь наглядно объяснить.
Для решения данной задачи мы будем использовать простую HTML форму и POST запросы. И так приступим.
1. Нам потребуется создать файл php, в общем по сути не важно, если вы используете CMS, то пишете там, где можно вставить php код.
2. Создадим простую форму с полями «radio», то есть для выбора вариантов ответа и кнопкой для результатов.
В результате получим:
3. Отлично мы создали форму. Теперь в неё нужно внести изменения, чтобы она работала.
Добавим атрибуты к форме.
5. А теперь пропишем имя ответов к каждому варианту, например ‘value = «a»‘
В результате получим:
6. Создадим файл result.php в том же каталоге, в котором создадим скрипт теста на php для обработки и вывода результата правильных и не правильных ответов.
7. Перед html кодом добавим скрипт php:
8. Теперь выводим на страницу в html коде правильные и неправильные ответы:
Заключение. Теперь у вас есть простой тест на php и html, теперь можно и запустить его для онлайн. Вы можете добавить сколько угодно вариантов ответов по аналогии. Добавить стилей и улучшить код. Можно было все сделать намного грамотней, но проще этого не придумаешь. Работа у теста такая: выбрали варианты, нажали на кнопку «результат», нас перекидывает на вторую страницу, где выводится подсчет правильных и неправильных ответов. Удачи!
Юнит-тестирование в PHP
Язык PHP очень легок для изучения. Это, а так же обилие литературы «Освой _что_угодно_ за 24 часа» породило большое количество, мягко говоря, некачественного кода. Как следствие, рано или поздно любой программист, который выходит за рамки создания гостевой книги или сайта-визитки сталкивается с вопросом: «а если я здесь немножко добавлю, все остальное не ляжет?» Дать ответ на этот вопрос и на многие другие может юнит-тестирование.
В самом начале хочется оговориться — здесь речь не будет идти о TDD и методологиях разработки ПО. В данной статье я попробую показать начинающему PHP-разработчику основы использования модульного тестирования на базе фреймворка PHPUnit
Вместо предисловия
Вначале возникает вполне резонный вопрос: А зачем, если все и так работает?
Здесь все просто. После очередного изменения что-то перестанет работать так как надо — это я вам обещаю. И тогда поиск ошибки может отнять очень много времени. Модульное тестирование может свести этот процесс к считанным минутам. Не будем так же исключать переезд на другую платформу и связанные с ним «подводные камни». Чего только стоит разность в точности вычислений на 64- и 32-разрядных системах. А когда-то вы в первый раз столкнетесь с нюансами вроде
Если вопрос необходимости отпал, то можно приступить к выбору инструмента. Здесь ассортимент в общем-то невелик — PHPUnit (http://www.phpunit.de/) и SimpleTest (http://www.simpletest.org/). Поскольку PHPUnit уже стал стандартом де-факто в тестировании PHP приложений, то на нем и остановимся.
Первое знакомство
Вопросы установки рассматривать не будем: все достаточно внятно изложено на сайте. Попробуем лучше понять, как это все работает.
Допустим, есть у нас некий класс «MyClass», одним из методов реализующий возведение числа в степень. (Здесь вынужден извиниться, но все примеры, в общем-то, высосаны из пальца)
Хочется проверить, правильно ли он работает. О всем классе речь пока не идет — только об одном методе. Напишем для проверки такой тест.
require_once ‘PHPUnit/Framework.php’ ;
require_once ‘MyClass.php’ ;
$ phpunit MyClassTest
.
Time: 0 seconds
OK (1 test, 1 assertion)
Результат выполнения теста «ОК». Казалось бы можно остановиться на этом, но иногда было бы неплохо для проверки скормить методу не один набор данных. PHPUnit предоставляет нам такую возможность — это провайдеры данных. Провайдер данных тоже является паблик-методом (название не существенно), который возвращает массив наборов данных для каждой итеррации. Для использования провайдера необходимо указать его в теге @dataProvider к тесту.
Изменим наш тест следующим образом:
require_once ‘PHPUnit/Framework.php’ ;
require_once ‘MyClass.php’ ;
class MyClassTest extends PHPUnit_Framework_TestCase <
После запуска увидим следующую картину:
Опишу подробнее. Точка, которую в первом выводе теста многие могли принять за опечатку на самом деле таковой не является — это успешно пройденный тест. F(ailure) — соответственно тест не пройденный. Значит в данном случае, было проведено 3 теста, один из который завершился неудачно. В расширенном описании нам было сказано, какой именно, с каким набором исходных данных, с каким реальным и каким ожидаемым результатом. Если бы 2 3 действительно равнялось 9-ти, то мы увидели бы таким образом ошибку в нашем сценарии.
Здесь, как мне кажется, есть смысл отвлечься от несколько абстрактной практики и перейти ко вполне конкретной теории. А именно, описать какими же assert-методами мы располагаем для проверки поведения тестируемых сценариев.
Два самых простых — это assertFalse() и assertTrue(). Проверяют, является ли полученное значение false и true соответственно. Далее идут уже упомянутый assertEquals() и обратный ему assertNotEquals(). В их использовании есть нюансы. Так при сравнении чисел с плавающей точкой есть возможность указать точность сравнения. Так же эти методы используются для сравнения экземпляров класса DOMDocument, массивов и любых объектов (в последнем случае равенство будет установлено, если атрибуты объектов содержат одинаковые значения). Так же следует упомянуть assertNull() и assertNotNull() которые проверяют соответствие параметра типу данных NULL (да-да, не забываем, что в PHP это отдельный тип данных). Этим возможные сравнения не ограничиваются. Нет смысла в рамках этой статьи заниматься перепечаткой документации, потому приведу по возможности структурированный список всех возможных методов. Более детально интересующиеся могут прочитать здесь
Базовые методы сравнения
assertTrue() / assertFalse()
assertEquals() / assertNotEquals()
assertGreaterThan()
assertGreaterThanOrEqual()
assertLessThan()
assertLessThanOrEqual()
assertNull() / assertNotNull()
assertType() / assertNotType()
assertSame() / assertNotSame()
assertRegExp() / assertNotRegExp()
Методы сравнения массивов
assertArrayHasKey() / assertArrayNotHasKey()
assertContains() / assertNotContains()
assertContainsOnly() / assertNotContainsOnly()
ООП специфичные методы
assertClassHasAttribute() / assertClassNotHasAttribute()
assertClassHasStaticAttribute() / assertClassNotHasStaticAttribute()
assertAttributeContains() / assertAttributeNotContains()
assertObjectHasAttribute() / assertObjectNotHasAttribute()
assertAttributeGreaterThan()
assertAttributeGreaterThanOrEqual()
assertAttributeLessThan()
assertAttributeLessThanOrEqual()
Методы сравнения файлов
assertFileEquals() / assertFileNotEquals()
assertFileExists() / assertFileNotExists()
assertStringEqualsFile() / assertStringNotEqualsFile()
Методы сравнения XML
assertEqualXMLStructure()
assertXmlFileEqualsXmlFile() / assertXmlFileNotEqualsXmlFile()
assertXmlStringEqualsXmlFile() / assertXmlStringNotEqualsXmlFile()
assertXmlStringEqualsXmlString() / assertXmlStringNotEqualsXmlString()
Разное
assertTag()
assertThat()
Исключения
Если еще не надоело, то вернемся к практике, а именно к обработке исключений. Для начала модифицируем наш тестируемый класс — введем в него метод, который будет это исключение выбрасывать.
class MathException extends Exception < >;
Теперь надо создать тест, который будет завершаться успешно в том случае, если при определенном наборе данных будет вызвано это исключение. Задать требуемое исключение можно как минимум двумя способами — добавив к тесту @expectedException либо вызвав в тесте метод setExpectedException().
require_once ‘PHPUnit/Framework.php’ ;
require_once ‘MyClass.php’ ;
class MyClassTest extends PHPUnit_Framework_TestCase <
Тесты, в общем-то, абсолютно идентичны. Выбор способа остается на ваше усмотрение. Помимо механизмов предоставляемых непосредственно PHPUnit, для тестирования исключений можно воспользоваться стандартным try <…>catch (), к примеру, так:
require_once ‘PHPUnit/Framework.php’ ;
require_once ‘MyClass.php’ ;
class MyClassTest extends PHPUnit_Framework_TestCase <
В этом примере мы так же видим не рассмотренный ранее способ завершения теста с помощью вызова метода fail(). Вывод теста будет следующим:
F
Time: 0 seconds
There was 1 failure:
1) testDivision3(MyClassTest)
Not raise an exception
/home/user/unit/MyClassTest.php:50
Принадлежности
Базовые методы тестирования мы освоили. Можно ли улучшить наш тест? Да. Написанный c начала этой статьи класс проводит несколько тестов, в каждом из которых создается экземпляр тестируемого класса, что абсолютно излишне, потому как PHPUnit предоставляет в наше пользование механизм принадлежностей теста (fixtures). Установить их можно защищенным методом setUp(), который вызывается один раз перед началом каждого теста. После окончания теста вызывается метод tearDown(), в котором мы можем провести «сборку мусора». Таким образом, исправленный тест может выглядеть так:
require_once ‘PHPUnit/Framework.php’ ;
require_once ‘MyClass.php’ ;
class MyClassTest extends PHPUnit_Framework_TestCase <
Наборы тестов
После того, как код нескольких классов будет покрыт тестами, становится довольно таки неудобно запускать каждый тест по отдельности. Здесь нам на помощь могут прийти наборы тестов — несколько связанных единой задачей тестов можно объединить в набор и запускать соответственно его. Наборы реализованы классом PHPUnit_Framework_TestSuite. Необходимо создать экземпляр этого класса и добавить в него необходимые тесты с помощью метода addTestSuite(). Так же с помощью метода addTest() возможно добавление другого набора.
require_once ‘PHPUnit/Framework.php’ ;
// подключаем файлы с тестами
require_once ‘MyClassTest.php’ ;
require_once ‘PHPUnit/Framework.php’ ;
// подключаем файл с набором тестов
require_once ‘SpecificTests.php’ ;
А теперь представим себе набор тестов для сценария, работающего с БД. Неужели нам в каждом тесте придется подключаться к базе? Нет — не придется. Для этого можно создать свой класс унаследованный от PHPUnit_Framework_TestSuite, определить его методы setUp() и tearDown() для инициализации интерфейса БД и просто передать его в тест атрибутом sharedFixture. Базы данных мы оставим на потом, а пока попробуем создать собственный набор тестов для уже имеющегося класса.
require_once ‘PHPUnit/Framework.php’ ;
require_once ‘MyClass.php’ ;
class MyClassTest extends PHPUnit_Framework_TestCase <
class MySuite extends PHPUnit_Framework_TestSuite <
Здесь мы в sharedFixture положили экземпляр тестируемого класса, а в тесте просто его использовали — решение не слишком красивое (я бы даже сказал, вообще не красивое), но общее представление о наборах тестов и передаче принадлежностей между тестами оно дает. Если наглядно изобразить очередность вызова методов, то получится нечто вроде такого:
MySuite::setUp()
MyClassTest::setUp()
MyClassTest::testPower()
MyClassTest::tearDown()
MyClassTest::setUp()
MyClassTest::testDivision()
MyClassTest::tearDown()
.
MySuite::tearDown()
Дополнительные возможности
Помимо всего вышеизложенного может возникнуть необходимость проверить не только расчеты и поведение сценария, но так же вывод и скорость отработки. Для этого в наше распоряжение предоставлены расширения PHPUnit_Extensions_OutputTestCase и PHPUnit_Extensions_PerformanceTestCase соответственно. Добавим в наш тестируемый класс еще один метод, и проверим правильно ли он работает.
require_once ‘PHPUnit/Framework.php’ ;
require_once ‘PHPUnit/Extensions/OutputTestCase.php’ ;
require_once ‘PHPUnit/Extensions/PerformanceTestCase.php’ ;
require_once ‘MyClass.php’ ;
class MyClassOutputTest extends PHPUnit_Extensions_OutputTestCase <
class MyClassPerformanceTest extends PHPUnit_Extensions_PerformanceTestCase <
class MyClassTest extends PHPUnit_Framework_TestCase <
Задать ожидаемый вывод сценария можно с помощью методов expectOutputString() или expectOutputRegex(). А для метода setMaxRunningTime() планируемое время отработки указывается в секундах. Для того, что бы эти тесты запускались вместе с уже написанными их всего лишь надо добавить к нашему набору:
class MySuite extends PHPUnit_Framework_TestSuite <
Пропускаем тесты
И напоследок рассмотрим ситуацию, в которой некоторые тесты необходимо пропускать по каким либо причинам. К примеру в том случае, когда на тестируемой машине отсутствует какое-либо расширение PHP, можно убедившись в его отсутствии пометить тест, как пропущенный добавив к его коду следующее:
Либо в том случае, когда тест написан для кода, которого еще нет в сценарии (не редкая для TDD ситуация) его можно пометить как не реализованный с помощью метода markTestIncomplete()