Intereting Posts
Использование PHP, MSSQL, JQuery для мгновенного поиска Выбор полей с использованием внешних ключей в реляционной таблице Как сделать новые строки в ячейке, используя phpexcel PHP __destruct вызывает net :: ERR_CONNECTION_RESET register_shutdown_function нет. Какая разница? получить следующий и предыдущий день с PHP Есть ли законное использование для простых строк в PHP? Найти недельные периоды (начиная с понедельника) в течение месяца Лучший способ удалить трейлинг-косые черты в URL-адресах с помощью PHP PHP Markdown XSS Sanitizer php обрезать строку, если дольше, чем предел, и положить некоторое упущение в конце … аналогично рубину отправлять напоминания электронной почты с php и mysql БЕЗ cron-job? В чем разница между {{}} и {!! !!} в файлах laravel blade? Невозможно проверить подпись PyOpenSSL в C # Как получить разрешение экрана посетителя в javascript и / или php? Динамическое пользовательское меню WordPress не показывает правильные результаты

Тестирование узловых модулей Slim Framework

Я пытаюсь написать некоторые тесты PHPUnit для моего небольшого приложения с матовой платформой, но не вижу нигде в документах, которые указывают на способ сделать полный запрос и утверждать ответ (либо содержащий текст, либо статус 200, либо ничего действительно).

Есть ли способ сделать это, чтобы кто-нибудь нашел / использовал?

Вот пример того, как вы можете протестировать свое Slim-приложение:

https://github.com/mac2000/SlimTestable

Предположим, что мы имеем простое применение:

<?php use Slim\Slim; require_once 'vendor/autoload.php'; $app = new Slim(); $app->get('/', function(){ echo 'home'; })->name('home'); $app->get('/hello/:name', function($name){ echo "hello $name"; })->name('hello'); $app->map('/login', function() use($app) { if($app->request()->params('login')) { $app->flash('success', 'Successfully logged in'); $app->redirect($app->urlFor('hello', array('name' => $app->request()->params('login')))); } else { $app->flash('error', 'Wrong login'); $app->redirect($app->urlFor('home')); } })->via('GET', 'POST'); $app->run(); 

Как мы его тестируем?

Создать класс App :

 <?php // src/App.php use Slim\Slim; class App extends Slim { function __construct(array $userSettings = array()) { parent::__construct($userSettings); $this->get('/', function(){ echo 'home'; })->name('home'); $this->get('/hello/:name', function($name){ echo "hello $name"; })->name('hello'); $this->map('/login', function() { if($this->request()->params('login')) { $this->flash('success', 'Successfully logged in'); $this->redirect($this->urlFor('hello', array('name' => $this->request()->params('login')))); } else { $this->flash('error', 'Wrong login'); $this->redirect($this->urlFor('home')); } })->via('GET', 'POST'); } /** * @return \Slim\Http\Response */ public function invoke() { $this->middleware[0]->call(); $this->response()->finalize(); return $this->response(); } } 

Обратите внимание, что мы перемещаем все наши маршруты в новый конструктор классов, а также замечаем новый метод invoke , который делает то же самое, что и метод run за исключением того, что возвращает ответ, а не повторяет его.

Теперь ваш файл index.php может выглядеть следующим образом:

 <?php require_once 'vendor/autoload.php'; $app = new App(); $app->run(); 

И теперь настало время для тестов:

 <?php // tests/ExampleTest.php use Slim\Environment; class ExampleTest extends PHPUnit_Framework_TestCase { private $app; public function setUp() { $_SESSION = array(); $this->app = new App(); } public function testHome() { Environment::mock(array( 'PATH_INFO' => '/' )); $response = $this->app->invoke(); $this->assertContains('home', $response->getBody()); } public function testHello() { Environment::mock(array( 'PATH_INFO' => '/hello/world' )); $response = $this->app->invoke(); $this->assertTrue($response->isOk()); $this->assertContains('hello world', $response->getBody()); } public function testNotFound() { Environment::mock(array( 'PATH_INFO' => '/not-exists' )); $response = $this->app->invoke(); $this->assertTrue($response->isNotFound()); } public function testLogin() { Environment::mock(array( 'PATH_INFO' => '/login' )); $response = $this->app->invoke(); $this->assertTrue($response->isRedirect()); $this->assertEquals('Wrong login', $_SESSION['slim.flash']['error']); $this->assertEquals('/', $response->headers()->get('Location')); } public function testPostLogin() { Environment::mock(array( 'REQUEST_METHOD' => 'POST', 'PATH_INFO' => '/login', 'slim.input' => 'login=world' )); $response = $this->app->invoke(); $this->assertTrue($response->isRedirect()); $this->assertEquals('Successfully logged in', $_SESSION['slim.flash']['success']); $this->assertEquals('/hello/world', $response->headers()->get('Location')); } public function testGetLogin() { Environment::mock(array( 'PATH_INFO' => '/login', 'QUERY_STRING' => 'login=world' )); $response = $this->app->invoke(); $this->assertTrue($response->isRedirect()); $this->assertEquals('Successfully logged in', $_SESSION['slim.flash']['success']); $this->assertEquals('/hello/world', $response->headers()->get('Location')); } } 

Вы должны заметить несколько вещей:

При настройке теста мы создаем массив $_SESSION для целей тестирования и создаем экземпляр нашего объекта класса App .

В тестах, а не в run мы вызываем invoke которые делают то же самое, но возвращают объект ответа.

Environment::mock используется для подделки запросов, обрабатываемых с помощью нашего приложения.

Хорошо, так что я смог его грубо и заставить работать. Ниже приведен пример тестового класса конечной точки.

Предполагая, что вы работаете в среде разработки, вы можете выполнять curl запросы на свой собственный локальный хост, таким образом, проверяя, прежде чем совершать репо.

Сначала создайте свой класс:

 class ApiEndpointsTest extends PHPUnit_Framework_TestCase { protected $api_url = "http://localhost/api/v1"; //create a function that will allow you to call API endpoints at-will. private function loadEndpoint($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); $info = curl_getinfo($ch); curl_close($ch); return array( 'body' => $output, 'info' => $info ); } //this allows you to write messages in the test output private function printToConsole($statement) { fwrite(STDOUT, $statement."\n"); } 

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

 //this will test the actual body of the response against something expected. public function testGetUserResponse() { $this->printToConsole(__METHOD__); $url = $this->api_url."/users/124"; $response = $this->loadEndpoint($url); $expected = '[{"name":"John Smith","email":"john@acme.com"}]'; $this->assertEquals($response['body'], $expected); } 

В отдельном тесте вы можете проверить любое другое свойство ответа API-вызова:

 public function testGetUserMimeType() { $this->printToConsole(__METHOD__); $url = $this->api_url."/users/124"; $response = $this->loadEndpoint($url); $this->assertEquals($response['info']['content_type'], 'application/json'); } 

Параметры вашей информации можно найти здесь: http://php.net/manual/en/function.curl-getinfo.php

Замечание: если кто-то читает это эксперт в PHPUnit и знает лучший способ, мне интересно узнать об этом – я новичок в PHPUnit.