Структурируйте свои тесты Playwright с помощью шагов

Следуйте за мной в Твиттере @tim_deschryver | Подпишитесь на рассылку | Первоначально опубликовано на timdeschryver.dev.


Читайте TLDR-версию на timdeschryver.dev

Всегда полезно знать, почему тест не удался.
В идеале, мы сразу видим, почему (и какая строка (строки)) приводит к неудаче теста.
Но это не всегда легко понять, когда тест содержит несколько шагов.
Именно здесь хороший инструмент для запуска тестов поможет вам выиграть немного времени.

Разделение сквозного теста на несколько шагов — популярная практика, потому что это ускоряет выполнение тестовых примеров и потому что вы, вероятно, построили тест поверх созданных/измененных данных.

Для меня это важно, потому что я люблю писать целые потоки в сквозном тестировании, так я уверен, что все работает, но это даже полезно для более простых тестовых случаев.
К счастью, Playwright может помочь нам и быстро указать на проблему.

В качестве примера рассмотрим пример Playwright, который генерируется как пример с помощью команды init (npm init playwright).

👎 Комментарии к коду

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

В таких случаях шаг можно сравнить с меньшим тестовым случаем в рамках большого теста.

test('should allow me to mark items as complete', async ({ page }) => {
    // Create two items.
    for (const item of TODO_ITEMS.slice(0, 2)) {
        await page.locator('.new-todo').fill(item);
        await page.locator('.new-todo').press('Enter');
    }

    // Check first item.
    const firstTodo = page.locator('.todo-list li').nth(0);
    await firstTodo.locator('.toggle').check();
    await expect(firstTodo).toHaveClass('completed');

    // Check second item.
    const secondTodo = page.locator('.todo-list li').nth(1);
    await expect(secondTodo).not.toHaveClass('completed');
    await secondTodo.locator('.toggle').check();

    // Assert completed class.
    await expect(firstTodo).toHaveClass('completed');
    await expect(secondTodo).toHaveClass('completed');
});
Вход в полноэкранный режим Выход из полноэкранного режима

Давайте также посмотрим на отчет Playwright для этого тестового случая.

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

Глядя на отчет Playwright, становится ясно, почему тест не работает: «ожидание селектора ‘.new-todo-fail'».
Другими словами, он не может найти селектор .new-todo-fail.

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

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

👎 Выписки из журнала

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

Итак, давайте включим их в тест и посмотрим, что произойдет.
В следующем примере, чтобы узнать, какой todo создан и какой todo проверен, добавлены утверждения журнала.

test('should allow me to mark items as complete', async ({ page }) => {
    // Create two items.
    for (const item of TODO_ITEMS.slice(0, 2)) {
        console.log('create todo', item);
        await page.locator('.new-todo').fill(item);
        await page.locator('.new-todo-fail').press('Enter');
    }

    // Check first item.
    const firstTodo = page.locator('.todo-list li').nth(0);
    await firstTodo.locator('.toggle').check();
    await expect(firstTodo).toHaveClass('completed');
    console.log('checked', TODO_ITEMS[0]);

    // Check second item.
    const secondTodo = page.locator('.todo-list li').nth(1);
    await expect(secondTodo).not.toHaveClass('completed');
    await secondTodo.locator('.toggle').check();
    console.log('checked', TODO_ITEMS[1]);

    // Assert completed class.
    await expect(firstTodo).toHaveClass('completed');
    await expect(secondTodo).toHaveClass('completed');
});
Вход в полноэкранный режим Выход из полноэкранного режима

При повторном выполнении тест по-прежнему не работает, но добавленные журналы теперь включены в отчет Playwright.

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

👍 Шаги

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

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

Рефакторинговый тест с шагами выглядит следующим образом.

test('should allow me to mark items as complete', async ({ page }) => {
    for (const item of TODO_ITEMS.slice(0, 2)) {
        await test.step(`Create todo ${item}`, async () => {
            await page.locator('.new-todo').fill(item);
            await page.locator('.new-todo-fail').press('Enter');
        });
    }

    await test.step(`Check first item`, async () => {
        const firstTodo = page.locator('.todo-list li').nth(0);
        await firstTodo.locator('.toggle').check();
        await expect(firstTodo).toHaveClass('completed');
    });

    await test.step(`Check second item`, async () => {
        const secondTodo = page.locator('.todo-list li').nth(1);
        await expect(secondTodo).not.toHaveClass('completed');
        await secondTodo.locator('.toggle').check();
    });

    await expect(firstTodo).toHaveClass('completed');
    await expect(secondTodo).toHaveClass('completed');
});
Войти в полноэкранный режим Выход из полноэкранного режима

Но у рефакторингового теста есть небольшая проблема, поскольку у нас больше нет доступа к переменным firstTodo и secondTodo.
Чтобы исправить это, верните переменные в функции test.step и присвойте их переменной.

test('should allow me to mark items as complete', async ({ page }) => {
    for (const item of TODO_ITEMS.slice(0, 2)) {
        await test.step(`Create todo ${item}`, async () => {
            await page.locator('.new-todo').fill(item);
            await page.locator('.new-todo-fail').press('Enter');
        });
    }

    const firstTodo = await test.step(`Check first item`, async () => {
        const firstTodo = page.locator('.todo-list li').nth(0);
        await firstTodo.locator('.toggle').check();
        await expect(firstTodo).toHaveClass('completed');
        return firstTodo;
    });

    const secondTodo = await test.step(`Check second item`, async () => {
        const secondTodo = page.locator('.todo-list li').nth(1);
        await expect(secondTodo).not.toHaveClass('completed');
        await secondTodo.locator('.toggle').check();
        return secondTodo;
    });

    await expect(firstTodo).toHaveClass('completed');
    await expect(secondTodo).toHaveClass('completed');
});
Вход в полноэкранный режим Выйдите из полноэкранного режима

Теперь, когда тест выполняется, он приводит к следующему отчету Playwright.

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

Когда мы в конечном итоге исправим тест, отчет Playwright будет содержать подробное описание каждого шага.

Заключение

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

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


Следуйте за мной в Twitter по адресу @tim_deschryver | Подпишитесь на рассылку | Первоначально опубликовано на timdeschryver.dev.

Оцените статью
devanswers.ru
Добавить комментарий