fillincode / tests
A package for simplified work with tests in Laravel
Requires
- php: ^8.1
- laravel/framework: ^10.0|^11.0
README
Быстрая генерация тестов без необходимости писать всю логику тестирования вручную.
Возможности пакета:
- Пакет выполняет тестирования middleware маршрута,
- Запросы от каждого пользователя, определенного в конфигурации,
- Тестирование запросов с передачей данных,
- Тестирование запросов с передачей параметров адресной строки,
- Проверка кода ответа для каждого теста,
- Заполнение данными БД перед выполнением запроса,
- Создание насмешек
Installation
composer require fillincode/tests
Публикация конфигурации
php artisan vendor:publish --provider="Fillincode\Tests\TestServiceProvider"
Config
Конфигурация находится в файле config/fillincode_tests.php
Необходимо указать дефолтные коды ответа для пользователей, а также для невалидных данных и параметров адресной строки
[ 'user' => 200, 'admin' => 200, 'guest' => 401, 'invalid_data' => 422, 'invalid_parameters' => 404, ];
Необходимо указать, какие пользователи есть в системе и какие guards проверяют их авторизацию. Для guest не нужно указывать guard
'users' => [ 'guest', 'user' => 'Passport', 'admin' => 'web', ],
Commands
Сгенерирует базовый класс для функциональных тестов, который содержит основную логику тестов
php artisan f-tests:init
Генерирует класс теста. С помощью этой же команды можно выбрать интерфейсы, который реализует класс. Методы будет автоматически добавлены в класс
php artisan make:f-test
Пример первоначальной настройки пакета
Необходимо в конфигурации указать, какие есть пользователи в системе, дефолтные коды ответа для этих пользователей.
return [ 'web_user' => 200, 'api_user' => 200, 'admin' => 200, 'guest' => 401, 'invalid_data' => 422, 'invalid_parameters' => 404, 'has_fillincode_swagger_parser' => true, 'users' => [ 'guest', 'web_user' => 'web', 'api_user' => 'Passport' 'admin' => 'Moonshine', ], ];
После чего выполнить команду для генерации класса. В этом классе будут реализованы методы тестирования от каждого пользователя.
php artisan f-tests:init
Затем реализовать методы либо в BaseFeatureTest, либо в TestCase для получения этих пользователей.
use App\Models\User; ```` /** * Получения пользователя web_user * * @return User */ public function getWebUser(): User { return User::whereEmail('web_user@gmail.com')->first(); } /** * Получения пользователя api_user * * @return User */ public function getApiUser(): User { return User::whereEmail('api_user@gmail.com')->first(); } /** * Получения пользователя admin * * @return User */ public function getAdmin(): User { return User::whereEmail('admin@gmail.com')->first(); }
Возможности пакета для тестов
Изменения дефолтных кодов для текущего маршрута
- Необходимо имплементировать интерфейс Fillincode/Tests/Interfaces/CodeInterface
- Реализовать метод getCodes
use Fillincode\Tests\Interfaces\CodeInterface; use Tests\Feature\BaseFeatureTest; class ExampleTest extends BaseFeatureTest implements CodeInterface { /** * {@inheritDoc} */ public function getCodes(): array { return [ 'guest' => 401, 'web_user' => 200, 'api_user' => 401, 'admin' => 401, ]; } }
Изменения дефолтных кодов для передачи невалидных параметров в адресной строке
- Необходимо имплементировать интерфейс Fillincode/Tests/Interfaces/ParametersCodeInterface
- Реализовать метод getCodesForInvalidParameters
use Fillincode\Tests\Interfaces\ParametersCodeInterface; use Tests\Feature\BaseFeatureTest; class ExampleTest extends BaseFeatureTest implements ParametersCodeInterface { /** * {@inheritDoc} */ public function getCodesForInvalidParameters(): array { return [ 'guest' => 404, 'web_user' => 404, 'api_user' => 404, 'admin' => 404, ]; } }
Передача параметров во время тестирования
- Необходимо имплементировать интерфейс Fillincode/Tests/Interfaces/ParametersInterface
- Реализовать методы getParameters и getInvalidParameters
Первый метод должен вернуть корректные параметры адресной строки, второй метод должен вернуть некорректные параметры адресной строки
use Fillincode\Tests\Interfaces\ParametersInterface; use Tests\Feature\BaseFeatureTest; class ExampleTest extends BaseFeatureTest implements ParametersInterface { /** * {@inheritDoc} */ public function getParameters(): array { return [ 'project' => Project::factory()->create(['status' => 'active']) ]; } /** * {@inheritDoc} */ public function getInvalidParameters(): array { return [ 'project' => Project::factory()->create(['status' => 'draft']) ]; } }
Валидация данных
- Необходимо имплементировать интерфейс Fillincode/Tests/Interfaces/ValidateInterface
- Реализовать методы getValidData и getNotValidData.
Первый метод должен вернуть валидные данные, второй метод должен вернуть невалидные данные
use Fillincode\Tests\Interfaces\ValidateInterface; use Tests\Feature\BaseFeatureTest; class ExampleTest extends BaseFeatureTest implements ValidateInterface { /** * {@inheritDoc} */ public function getValidData(): array { return [ 'name' => 'test_name', 'age' => 12, ]; } /** * {@inheritDoc} */ public function getNotValidData(): array { return [ 'name' => 'q', 'age' => null, ]; } }
Заполнение БД данными перед выполнением каждого запроса
- Необходимо имплементировать интерфейс Fillincode/Tests/Interfaces/FakeInterface
- Реализовать метод faker. В этом методе нужно будет выполнить логику заполнения данными БД
use Fillincode\Tests\Interfaces\FakeInterface; use Tests\Feature\BaseFeatureTest; class ExampleTest extends BaseFeatureTest implements FakeInterface { /** * {@inheritDoc} */ public function faker(): void { Project::factory(10)->create(['web_user_id' => $this->getWebUser()->id]); } }
Создание фейкового хранилища данных
- Необходимо имплементировать интерфейс Fillincode/Tests/Interfaces/FakeStorageInterface
Для теста, который реализует этот интерфейс автоматически будет создано фейковое public хранилище
use Fillincode\Tests\Interfaces\FakeStorageInterface; use Tests\Feature\BaseFeatureTest; class ExampleTest extends BaseFeatureTest implements FakeStorageInterface { }
Насмешка в тестах
- Необходимо имплементировать интерфейс Fillincode/Tests/Interfaces/MockInterface
- Реализовать метод getMockAction
use Fillincode\Tests\Interfaces\MockInterface; use Tests\Feature\BaseFeatureTest; class ExampleTest extends BaseFeatureTest implements MockInterface { /** * {@inheritDoc} */ public function getMockAction(): void { Http::fake(); } }
Если пакет работает в связке с пакетом Fillincode/Swagger и есть маршруты, которые не нужно документировать
-
Необходимо имплементировать интерфейс Fillincode/Tests/Interfaces/DocIgnoreInterface
use Fillincode\Tests\Interfaces\DocIgnoreInterface; use Tests\Feature\BaseFeatureTest; class ExampleTest extends BaseFeatureTest implements DocIgnoreInterface { }
-
В классе BaseFeatureTest в метод callRouteAction добавить
if (! $this->checkDocIgnoreInterface()) { (new TestParser())->makeAutoDoc($testResponse); }
Пример использования пакета
Для минимального тестирования достаточно создать класс, который будет наследником класса BaseFeatureTest и реализовать методы getRouteName и getMiddleware
use Tests\Feature\BaseFeatureTest; class ExampleTest extends BaseFeatureTest { /** * {@inheritDoc} */ public function getRouteName(): string { return 'api.user.update'; } /** * {@inheritDoc} */ public function getMiddleware(): array { return ['api', 'auth']; } }
Пример класса, который реализует все возможности пакета.
Возможности класса:
- Выполнит запросы от всех пользователей, которые определенны в конфигурации пакета,
- Выполнит тесты с отправкой параметров адресной строки
- Передаст данные для валидации,
- Создаст фейковое хранилище файлов,
- Подделает фасад Http,
- Проигнорирует документирование результатов тестирования
- Заполнит базу 10 проектами
use Tests\Feature\BaseFeatureTest; use Fillincode\Tests\Interfaces\CodeInterface; use Fillincode\Tests\Interfaces\ParametersCodeInterface; use Fillincode\Tests\Interfaces\ParametersInterface; use Fillincode\Tests\Interfaces\ValidateInterface; use Fillincode\Tests\Interfaces\FakeInterface; use Fillincode\Tests\Interfaces\FakeStorageInterface; use Fillincode\Tests\Interfaces\MockInterface; use Fillincode\Tests\Interfaces\DocIgnoreInterface; class ExampleTest extends BaseFeatureTest implements CodeInterface, ParametersCodeInterface, ParametersInterface, ValidateInterface, FakeInterface, FakeStorageInterface, MockInterface, DocIgnoreInterface { /** * {@inheritDoc} */ public function getRouteName(): string { return 'api.user.update'; } /** * {@inheritDoc} */ public function getMiddleware(): array { return ['api', 'auth']; } /** * {@inheritDoc} */ public function getCodes(): array { return [ 'guest' => 401, 'web_user' => 200, 'api_user' => 401, 'admin' => 401, ]; } /** * {@inheritDoc} */ public function getCodesForInvalidParameters(): array { return [ 'guest' => 404, 'web_user' => 404, 'api_user' => 404, 'admin' => 404, ]; } /** * {@inheritDoc} */ public function getParameters(): array { return [ 'project' => Project::factory()->create(['status' => 'active']) ]; } /** * {@inheritDoc} */ public function getInvalidParameters(): array { return [ 'project' => Project::factory()->create(['status' => 'draft']) ]; } /** * {@inheritDoc} */ public function getValidData(): array { return [ 'name' => 'test_name', 'age' => 12, ]; } /** * {@inheritDoc} */ public function getNotValidData(): array { return [ 'name' => 'q', 'age' => null, ]; } /** * {@inheritDoc} */ public function faker(): void { Project::factory(10)->create(['web_user_id' => $this->getWebUser()->id]); } /** * {@inheritDoc} */ public function getMockAction(): void { Http::fake(); } }