PHP PHP  ·  30 вопросов  ·  ~85 мин  ·  ⏱ Таймер 25:00  ·  Сложный  · 

Тестирование с PHPUnit

Тест проверяет способность написать проверку, которая ловит изменение поведения, а не повторяет внутреннее устройство метода. Вопросы охватывают data providers, исключения, doubles, интеграционные границы и устойчивость набора тестов.

Отвечено: 0 из 30
⏱ --:--
0%
💡 Инструкция: Выберите один ответ из пяти. Смотрите, какое наблюдаемое поведение защищает тест и почему он упадёт при настоящем дефекте. Таймер — 85 минут.
Вопрос 1 из 30
Что делает хороший unit-тест?
PHP
final class AccountTest extends TestCase
{
    public function testRejectsWithdrawalAboveBalance(): void
    {
        $account = Account::withBalance(100);
        $this->expectException(InsufficientFunds::class);
        $account->withdraw(101);
    }
}
Вопрос 2 из 30
Почему имя testItWorks слабое?
PHP
final class ServiceTest extends TestCase
{
    public function testItWorks(): void
    {
        self::assertFalse($this->service->run($this->input));
    }
}
Вопрос 3 из 30
Как проверить исключение?
PHP
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Количество должно быть положительным');
$order->addItem($product, 0);
Вопрос 4 из 30
Что не так с тестом, который читает DateTimeImmutable("now")?
Вопрос 5 из 30
Почему тест private-метода через Reflection хрупок?
Вопрос 6 из 30
Когда provider полезен?
PHP
final class QuantityTest extends TestCase
{
    /** @dataProvider invalidQuantities */
    public function testRejectsInvalidQuantity(int $quantity): void
    {
        $this->expectException(InvalidArgumentException::class);
        new Quantity($quantity);
    }
}
Вопрос 7 из 30
Зачем именовать datasets?
PHP
final class QuantityTest extends TestCase
{
    public static function invalidQuantities(): iterable
    {
        yield 'zero' => [0];
        yield 'negative' => [-1];
        yield 'too large' => [10_001];
    }
}
Вопрос 8 из 30
Что должен выдавать provider?
PHP
final class TotalTest extends TestCase
{
    public static function totals(): iterable
    {
        yield [100, 0, 100];
        yield [100, 10, 90];
    }
}
Вопрос 9 из 30
Почему network-call внутри provider плох?
Вопрос 10 из 30
Какие случаи нужны для диапазона 1..10?
Вопрос 11 из 30
Чем stub отличается от mock в практическом смысле?
PHP
$clock = $this->createStub(Clock::class);
$clock->method('now')->willReturn(new DateTimeImmutable('2026-07-14'));

$mailer = $this->createMock(Mailer::class);
$mailer->expects(self::once())->method('send');
Вопрос 12 из 30
Когда fake удобнее сложного mock?
PHP
$repository = new InMemoryUserRepository();
$repository->save($user);
self::assertSame($user, $repository->get($user->id()));
Вопрос 13 из 30
Почему не стоит мокировать value object Money?
PHP
$price = new Money(1000, 'RUB');
$discount = new Money(100, 'RUB');
self::assertEquals(new Money(900, 'RUB'), $price->minus($discount));
Вопрос 14 из 30
Что проверить у Mailer mock?
Вопрос 15 из 30
Почему mock, возвращающий невозможные данные, вреден?
Вопрос 16 из 30
Что проверяет интеграционный тест репозитория?
PHP
$repository = new PdoUserRepository($this->database);
$repository->save(new User(1, 'a@example.test'));
self::assertSame('a@example.test', $repository->get(1)->email);
Вопрос 17 из 30
Как изолировать тесты базы?
PHP
final class RepositoryTest extends TestCase
{
    protected function setUp(): void
    {
        $this->pdo->beginTransaction();
    }

    protected function tearDown(): void
    {
        if ($this->pdo->inTransaction()) {
            $this->pdo->rollBack();
        }
    }
}
Вопрос 18 из 30
Почему SQLite может быть недостаточна?
PHP
$pdo = new PDO('sqlite::memory:');
$pdo->exec('CREATE TABLE events (payload TEXT NOT NULL)');

$repository = new EventRepository($pdo);
Вопрос 19 из 30
Что проверять у миграции?
Вопрос 20 из 30
Когда HTTP-тест полезен?
Вопрос 21 из 30
Что такое flaky-тест?
PHP
final class OfferTest extends TestCase
{
    public function testExpiresAtNoon(): void
    {
        $offer = new Offer(expiresAt: new DateTimeImmutable('today 12:00'));
        self::assertTrue($offer->isActive(new DateTimeImmutable('now')));
    }
}
Вопрос 22 из 30
Как локализовать зависимость от порядка?
PHP
$tests = ['creates user', 'updates user', 'deletes user'];
shuffle($tests);
foreach ($tests as $test) {
    runTestInIsolatedState($test);
}
Вопрос 23 из 30
Что показывает coverage?
PHP
$result = $coverage->summary();
printf('Lines: %.1f%%, branches: %.1f%%', $result->lines, $result->branches);
Вопрос 24 из 30
Зачем фиксировать seed случайного теста?
Вопрос 25 из 30
Как улучшить сообщение assert?
Вопрос 26 из 30
Какой тест обязателен для защищённого ресурса?
PHP
$response = $client->as($alice)->get('/orders/' . $bobOrder->id);
self::assertSame(404, $response->status());
Вопрос 27 из 30
Что делать с секретами в fixtures?
PHP
$fixture = [
    'api_key' => 'test_key_not_valid_anywhere',
    'password' => 'example-only',
];
$scanner->assertNoRealSecrets($repositoryPath);
Вопрос 28 из 30
Как тестировать внешний платёжный сервис?
PHP
$gateway = new FakePaymentGateway();
$service = new Checkout($gateway);
$service->pay($order);
self::assertSame($order->total(), $gateway->lastAmount());
Вопрос 29 из 30
Какой quality gate разумен?
Вопрос 30 из 30
Почему тесты должны запускаться из чистой установки lock-файла?

Ответьте на все 30 вопросов, чтобы получить результат

🔗 Встроить тест на свой сайт (iframe) ▼

Скопируйте код и вставьте в любое место на вашем сайте:

Также доступна прямая ссылка на embed-страницу