Http test index php
Тест по основам PHP
Не секрет, что работа программиста высоко оплачивается. Но конкуренция за вакантные места высокая. Особенно ценны работники с уже готовым опытом, который они могут подтвердить.
PHP онлайн тесты оценивают знания кандидатов программирования на языке PHP и их возможности использовать широко используемые в этом языке возможности.
Тест по PHP — это идеальная оценка для скрининга до работы. Хороший PHP-разработчик должен иметь возможность не только решать проблемы с использованием PHP в качестве языка программирования, но и точно понимать, когда и в каких случаях использовать его богатый набор встроенных функций и других возможностей языка.
PHP тесты помогают в том, чтобы кандидаты могли решать проблемы с программирование на PHP и находить и исправлять ошибки в веб-приложениях. Также PHP тесты систематизируют знания, позволяют писать осмысленный и правильный код, который затем смогут править другие разработчики.
Если программист хочет устроиться на работу по специальности, прохождение тестирования станет его преимуществом среди других кандидатов на должность.
Хотя язык PHP нельзя назвать сложным, всё-таки он требует понимания многих нюансов работы с ним, освоения функционирования классов, фреймворков.
Также PHP тестирование поможет оценить реальный уровень знаний программиста. Наличие в портфеле соискателя нового места работы успешно пройденных тестов значительно упростит прохождение собеседования, а HR менеджер сможет понять, что перед ним находится специалист, который готов постоянно совершенствовать свои навыки кодинга.
На собеседованиях часто задают вопросы про знания и понимание объектно-ориентированного программирования, наследования интерфейсов, абстрактных классов, что позволят с высокой точностью выявить опыт соискателя.
Поэтому прохождение PHP тестирования поможет в решении многих вопросов и придаст дополнительную уверенность кандидату при прохождении собеседования.
Юнит-тестирование в 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()
Простой инструмент для тестирования PHP приложений
Для кого эта статья
Скорее всего для тех, кто ещё не начал тестировать, но имеет такое желание. Опытных в этом деле разработчиков удивить не получится, но тех кто ещё не перешел на сторону света, попробую подтолкнуть на этот шаг.
Предыстория
Решил разобраться с автоматическим тестированием. Раньше этого делать не приходилось, да и тогда не было особо нужно. Зато было свободное время, которое решил потратить с пользой на будущее.
Почитав теорию, начал искать инструмент для этого. Предсказуемо первым на горизонте показался PhpUnit. Но он показался каким-то громоздким, что ли.
Более удобным показался Codeception — разные виды тестов, выразительный синтаксис. Но, посмотрев зависимости, я понял, что мне столько всего не нужно.
Двигаясь в сторону простоты, я нашел atoum, а потом вообще классную вещь под названием Testify.php. Тут-то я подумал, что наконец нашел то, что мне нужно.
Но я рано радовался. Testify.php не подошел при написании первого же теста. Тестировался класс кэширования, который в зависимости от того, включена отладка или нет, мог обрабатывать или игнорировать вызовы. Так как режим отладки предполагал наличие константы DEBUG со значением true/false — переопределить её в одном процессе не получится.
Требования
Реализация
Был написан небольшой скрипт, который открывал тесты по http, собирал результаты, и выдавал в презентабельном HTML виде. Для того, чтобы сделать аналогичным процесс тестирования и для консольного варианта — было решено использовать встроенный в PHP 5.4+ веб-сервер. Запускается он так:
И оно заработало как положено. Так, как аналогичного инструмента не нашел — решил оформить в виде самостоятельного composer пакета, добавил интерактивности (прогресс выполнения наборов тестов отображается в реальном времени как в HTML, так и в консольном варианте).
Теперь этот файл можно открыть либо в браузере, либо в консоли
Сами тесты не на много сложнее:
То есть, каждый отдельный тест являет собой файл, который возвращает 0 после успешного тестирования или текст ошибки, если она возникла.
Пример результата консольного варианта:
Есть возможность выполнить общие команды как перед всеми наборами тестов, так и перед всеми тестами одного набора.
Как тестировать приложения PHP с помощью PHPUnit
В этом руководстве мы вернемся к PHP и на этот раз рассмотрим, как создавать модульные тесты. Это поможет нам создавать более надежные и менее подверженные ошибкам приложения 💪.
Но прежде всего, и для тех, кто не имеет четкого представления о….
Что такое модульные тесты?
В основном это скрипты, которые мы создаем для тестирования определенных блоков кода. Тест получает данные из него и проверяет их с помощью функций, предоставляемых библиотекой, которую мы будем использовать. Таким образом, мы можем убедиться, что все хорошо, прежде чем отправить его в продакшн.
Создадим проект, чтобы посмотреть на все более наглядно.
Создаем структуру нашего проекта. Сначала мы создадим две папки в корневом каталоге, одну назовем app, а другую – tests. Далее создадим файл composer.json со следующим содержимым:
После этого мы запускаем команду composer dump для создания autoload:
Далее мы установим PHPUnit. Это будет библиотека, которую мы будем использовать для создания наших тестов.
После этого нам нужно создать конфигурационный файл для PHPUnit. Для этого перейдем в корневой каталог нашего проекта и создадим файл phpunit.xml, который будет содержать следующий код:
Фактически, мы передаем в атрибуте bootstrap файл загрузки класса, а в testsuite – каталог, в котором мы будем сохранять тесты, который в нашем случае будет находиться в папке tests.
Для этого примера мы создадим класс, который будем использовать в качестве подопытного кролика для запуска наших тестов. Для этого мы переходим в каталог приложения и внутри него создаем папку Classes. После создания этой папки мы обращаемся к ней и создаем файл Calc.php, который будет содержать следующий код:
Как вы можете видеть, это очень простой код. В нем просто есть функция, которая берет два числа и вычисляет сумму.
После того как это сделано, пришло время создать наш первый тест. Для этого перейдем в папку tests и в ней создадим файл CalcTest.php. Очень важно, чтобы имя файла имело формат CamelCase и заканчивалось Test.php. Это способ, который использует PHPUnit для определения того, когда это тест, а когда нет. Если он не имеет такого формата, тест выполнен не будет, поэтому не забывайте об этой детали.
После создания файла мы открываем его и добавляем следующий код:
После создания файла мы открываем его и добавляем следующий код:
Как вы видите, первое, что мы делаем, это добавляем библиотеку PHPUnit и наш класс Calc.
Следующим шагом будет создание класса, который должен называться так же, как и наш файл, и который будет расширять класс TestCase. Таким образом, мы сможем использовать функциональные возможности PHPUnit для создания наших тестов.
Внутри класса мы создадим наши тесты. В данном случае у нас есть только один под названием test_sum. Все методы, которые мы хотим запустить, должны начинаться с имени test_ и иметь формат названия snake_case, иначе PHPUnit проигнорирует их и они не будут запущены. Также каждый тест должен быть самодостаточным и не зависеть от других тестов, чтобы работать правильно.
Внутри test_sum мы создаем экземпляр класса Calc и выполняем метод sum, который возвращает результат. Для проверки теста мы будем использовать метод assertEquals, который является методом класса TestCase и в переводе означает что-то вроде “определить, равны ли они”. В этом методе в качестве первого параметра мы передаем результат, который ожидаем получить, а во втором – результат, который мы получили, чтобы подтвердить, что все в порядке.
Сейчас, когда мы создали наш тест, пришло время проверить его. Для этого переходим в наш корневой каталог и запускаем следующую команду:
Если все прошло успешно, мы должны получить сообщение о том, что все наши тесты успешно пройдены.
Кроме assertEquals, у нас есть еще много типов подтверждений, как вы можете видеть в этом списке. Например, если мы хотим подтвердить, что возвращаемый результат является целым числом, мы можем использовать AssertIsInt:
setUp() и tearDown()
Иногда бывает так, что в различных тестах мы повторяем код и в начале, и в конце, что означает, что у нас много повторяющегося кода. Для решения этой проблемы у нас есть методы setUp и tearDown. Метод setUp всегда будет запускаться перед выполнением каждого теста, а метод tearDown будет запускаться каждый раз, когда один из наших тестов завершится.
Чтобы увидеть их в действии, вернемся к классу Calc и добавим новый метод так, чтобы теперь он выглядел следующим образом:
Затем мы возвращаемся к нашему тесту и изменяем его, чтобы добавить новый тест, а также посмотреть, как применить метод setUp():
Как вы видите, мы добавили метод setUp, который будет создавать экземпляр класса каждый раз, когда выполняется тест. Таким образом, наши тесты будут выглядеть чище и понятнее.
Заключение
Идея тестов заключается в том, что мы всегда запускаем их перед загрузкой в продакшн. Таким образом нам будет легче защитить наш код от ошибок, поэтому я рекомендую вам использовать их при любой возможности.
Похожие записи
Функция загрузки файлов на сайт является одной из самых используемых в Интернете. Обычно информация о…
В этой статье о Python мы рассмотрим, как получить наименьшее общее кратное (НОК) двух чисел.…
Если вам нужно скопировать файл с помощью Python, но вы не знаете, как это сделать,…
Онлайн-тестеры PHP, JS и CSS кода
Полезные инструменты в складчину программиста, веб-разработчика, тестировщика. Эти онлайн-тестеры помогут протестировать ваш веб-код еще до внедрения на сайте, найти ошибки и «пофиксить» в реальном времени. Есть возможность симулировать любую версию PHP и даже фреймворки, а также протестировать и другой код, например CSS или Java Script.
PHPTester
Позволяет протестировать свой php-код в режиме онлайн прямо в вашем браузере без использования веб-сервера. Поддерживаемые версии PHP: 5.5, 5.6, 7.0
Ссылка: //phptester.net/
PHP Sandbox
Отличается от предыдущего только тем, что дает возможность выбрать любую версию PHP — от 4.4.9 до 7.4.
Ссылка: http://sandbox.onlinephpfunctions.com/
PHP Online Test
Удобный тестер с приятным пользовательским интерфейсом. Содержит в себе много еще других плюшек, например PHP виджеты, API, декодеры/энкодеры. Мне он очень понравился, рекомендую.
Ссылка: //phpfiddle.org/
PHP syntax checker
Осуществляет проверку синтаксиса в PHP-коде. Позволяет загрузить и проверить код из файла. Поддерживает версий PHP: 5.3, 5.4, 5.5, 5.6, 7.1
Ссылка: https://extendsclass.com/php-tester.html
JS.DO — Online JavaScript Editor
Название говорит за себя — этот сервис тестирует ваш JS-код. После регистрации можно указать URL-адрес файла с кодом и проверить в реальном времени, не выходя из браузера. Есть возможность симулировать фреймворки — jQuery, Bootstrap.
Ссылка: https://js.do/
CSSDesk
Замечательный онлайн-сервис. Позволяет поэкспериментировать с CSS-кодом в реальном времени и сразу просматривать результат. Готовый код вы можете скачать. А главное, сервис простой и дружелюбный. Новичку, однозначно понравится!