• Время чтения ~5 мин
  • 10.09.2022

BDD, или Behavioral Driven Development, является популярным подходом к тестированию во многих организациях и хорошо зарекомендовал себя в объединении усилий по тестированию между командами. Но остается вопрос, как мы можем добиться этого в Laravel, не изучая новый фреймворк для тестирования или новый синтаксис языка, такой как Gherkin.

Для бизнеса возможность определять процессы в удобном для чтения виде и представлять это в наших наборах тестов является огромным преимуществом. Точно так же, как Domain Driven Design позволяет нам создать вездесущий язык для нашего кода, BDD позволит нам иметь вездесущий язык для нашего тестирования.

Давайте рассмотрим несколько примеров. того, как может выглядеть тест BDD, а затем давайте разберем это. Давайте представим, что у нас есть веб-приложение с регистрационной формой. Когда эта форма заполнена, мы ожидаем, что пользователь будет зарегистрирован, и он должен автоматически войти в систему. Давайте посмотрим на это в типичном функциональном тесте:

it('allows a user to register for an account', function (string $email) {
	expect(
		User::query()->count(),
	)->toEqual(0);
 
	post(
		route('register'),
		['name' => 'test', 'email' => $email, 'password' => 'password']
	)->assertRedirect(route('dashboard'));
 
	expect(
		User::query()->count(),
	)->toEqual(1);
})->with('emails');

Это простой пример того, что вы можете сделать с помощью pestPHP, чтобы протестировать эту конечную точку, которая воспроизводит отправку формы. Как видите, как разработчик, это относительно легко понять, если вы привыкли тестировать с помощью вредителей. Тем не менее, ваш QA Engineer будет бороться с этим, так как они не привыкли вредить PHP, и у него нет понятного им синтаксиса.

Как мы могли бы реорганизовать это, чтобы использовать BDD и синтаксис, который может понять наш инженер по контролю качества и более широкая команда? К счастью, плагин pestPHP позволит нам использовать подход «данные, когда и тогда», типичный для мира BDD. Это подключаемый модуль Give when then, с которым легко начать работу. Запустите следующую команду композитора, чтобы установить этот плагин:

composer require milroyfraser/pest-plugin-gwt --dev

С этого момента мы можем начать писать специальные тесты для BDD. На данный момент мы хотим иметь в виду одну вещь: хотим ли мы заменить наши тесты или мы хотим, чтобы BDD улучшил наш текущий набор тестов? Я хотел бы улучшить свой существующий набор тестов, чтобы не потерять ценные тесты.

Давайте возьмем пример, с которым я недавно столкнулся. Я не использовал какой-либо конкретный пакет аутентификации для своего приложения Laravel. Вместо этого мне нужно было создать собственный поток аутентификации с использованием одноразового пароля. Моя регистрационная форма — это компонент Livewire, который обрабатывает логику за меня. Итак, давайте сначала напишем тест функции, чтобы убедиться, что наш компонент работает.

it('will submit the form and create a new user', function (string $email) {
	Livewire::test(
		RegisterForm::class,
	)->set(
		'name', 'test',
	)->set(
		'email', $email,
	)->set(
		'password', 'password',
	)->call(
		'submit'
	)->assertHasNoErrors(
		['name', 'email', 'password']
	);
})->with('emails');

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

В нашем случае, как и в большей части моего кода, я выполняю логику в классах действий, поэтому перенос этого имеет большой смысл. Обычно у меня есть отдельные классы действий для всех операций чтения и записи, которые мне нужно выполнить, чтобы CLI, Web и API могли использовать всю схожую логику — единственная разница заключается в том, как она вызывается. В приведенном выше примере наш компонент Livewire будет вызывать действие для создания пользователя.

Итак, теперь давайте посмотрим, как будет выглядеть бизнес-процесс в Gherkin синтаксис:

Scenario: The Register Action is handled
	Given the RegisterAction is created
	When the handle method is called
	Then a new user will be created

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

For our BDD tests, I will create an Integration directory under test, so that I have:
Unit: Test-Driven Development
Feature: Test-Driven Development
Integration: Behavioral Driven Development

В нашем каталоге Integrations мы будем хранить все наши сценарии, созданные как тесты pestPHP. с помощью установленного нами подключаемого модуля.

scenario('The RegisterAction is handled')
	->given(fn () => new RegisterAction())
	->when(fn (RegisterAction $action) => $action->handle(
		name: 'test',
		email: '[email protected]',
		password: 'password',
	))->then(fn () => assertDatabaseHas('users', [
		'name' => 'test',
		'email' => '[email protected]',
	]));

Как видно из приведенного выше кода, понять его несложно. Он имеет большое сходство с тем, что мы могли бы ожидать в большинстве наборов тестов BDD, но в среде, к которой мы привыкли. Обычно во многих случаях мы можем напрямую перевести это в пользовательскую историю.

Давайте возьмем еще один пример, но на этот раз мы начнем с пользовательской истории:

Как пользователь, когда я активирую свою учетную запись, я должен получить электронное письмо.

Теперь давайте перенесем это в синтаксис Gherkin:

Scenario: A user can activate their account
	Given a new user
	When they activate their account
	Then an email is sent to confirm the activation.

Наконец, давайте перейдем к pestPHP с плагином, который мы тестируем:

scenario('A user can activate their account')
	->given(fn (): User => User::factory()->inactive()->create())
	->when(fn () => Bus::fake())
	->when(fn (User $user): User => $user->activate())
	->then(function (User $user) {
		Bus::assertDispatched(ActivateUser::class);
	});

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

У вас есть нашли какие-нибудь другие интересные способы улучшить стратегию тестирования ваших приложений? Расскажите нам о своих мыслях в Твиттере!

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

Про мене

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

Об авторе CrazyBoy49z
WORK EXPERIENCE
Контакты
Ukraine, Lutsk
+380979856297