Если вы начинающий специалист в автоматизации тестирования, или автотестировщик с опытом, готовый обсуждать и улучшать стратегии тестирования, то с радостью представляю вам первый пост в серии, посвященный разборам подходов к тестированию ПО. Здесь я разбираю свой взгляд на способы решения реальных задач по тестированию, используя Playwright + TypeScript.

?? Как отсортировать данные в Typescript и как это поможет протестировать сортировку в вашем веб приложении

Для того, чтобы отсортировать массив данных, в Typescript есть метод .sort(), а так же .sort().reverse() который сверяет значения массива между собой и выстраивает их по возрастанию или убыванию. В подробности мы не углубляемся, сейчас это не имеет никакого значения.
Соответственно, мы можем сделать следующее:

import test, { expect } from '@playwright/test'

test(`Sorting test`, async ({ page }) => {
  // Open page with table
  await page.goto(`/table`)
  // Find locator of 2nd column header
  const headerLocator = page.locator(`//th[2]`)
  // Find locator of all 2nd table column cells
  const cellsLocator = page.locator(`//tbody//tr/td[2]`)
  // Sort column
  await headerLocator.click()
  // Get text from each cell in 2nd column
  const data = await cellsLocator.allTextContents()
  // Make sure that parsed data and sorted data are equal
  expect(data).toEqual([...data].sort())
})

Готово, дело закрыто?

??❓Но в чем же заключается сложность, при решении реальной задачи?

Дело в том, что в реальном приложении, тип данных может отличаться от стандартных, часто используется нетипичные форматы(например цена, или дата), или в кастомные типы данных. Поэтому, при использовании этого подхода, мы столкнемся с тем, что для каждого столбца с данными, придется писать отдельные тест кейсы, передавая в .sort() функцию для сравнения значений.

Далее предлагаю рассмотреть мою тест спеку sortable-table.spec.ts

import { test } from '../src/fixtures'
import { SORTABLE_TABLE_COLUMNS } from '../src/pages/sorting-demo/sorting-demo.columns'

test.describe('Sortable table', () => {

  for (const column of Object.values(SORTABLE_TABLE_COLUMNS)) {
    
    test(`${column} sort ascending`, async ({ sortableTablePage }) => {
      const table = sortableTablePage.table
      await table.sort.validateNone(column)
      await table.sort.apply(column)
      await table.sort.validateAscending(column)
    })

    test(`${column} sort descending`, async ({ sortableTablePage }) => {
      const table = sortableTablePage.table
      await table.sort.validateNone(column)
      await table.sort.apply(column, { clickCount: 2})
      await table.sort.validateDescending(column)
    })

  }

})

??? Разбор: как это работает?

В данной тест спеке представлены два параметризованных теста ${column} sort ascending и ${column} sort descending . Имея всего два теста, мы проверяем сортировку по возрастанию и убыванию во всей таблице.

sortableTablePage - фикстура, которая открывает веб страницу и ждёт, что страница успешно загружена.

Что мы используем в качестве параметра? SORTABLE_TABLE_COLUMNS - статичный объект содержащий информацию о столбцах нашей таблицы: название столбца, формат данных.

На примере DateFormat - можем увидеть, что в классе формата, представлен метод сравнения данных, а так же метод по парсингу string->target format .

Это позволяет нам иметь единый метод для проверки тестирования:

async validate(
    column: TableColumn,
    direction: SortingDirection
  ): Promise<void> {
    await test.step(
      `Validate table column "${column}" is sorted in "${direction}" direction`, 
      async () => {
        await expect(
          this.locators.headerByColumn(column)
        ).toHaveAttribute('aria-sort', direction)

        if (direction !== 'none') {
          const values = await this.getColumnValues(column)
          expect(
            new Set(values).size,
            `To have at least 2 unique values`
          ).toBeGreaterThanOrEqual(2)
          for (let i = 1; i < values.length; i++) {
            await test.step(`Compare row #${i} and #${i + 1}`, async () => {
              const value = values[i - 1]
              const nextValue = values[i]
              const result = await test.step(`Parse and compare values`, () => {
                return column.format.comparator(value, nextValue)
              })
  
              switch (direction) {
                case 'ascending':
                  expect.soft(
                    result,
                    `#${i} ${value} to be less than or equal #${
                      i + 1
                    } ${nextValue}`
                  ).toBeLessThanOrEqual(0)
                  break
  
                case 'descending':
                  expect.soft(
                    result,
                    `#${i} ${value} to be greater than or equal #${
                      i + 1
                    } ${nextValue}`
                  ).toBeGreaterThanOrEqual(0)
                  break
  
                default:
                  throw new Error(`Unknown sorting direction: ${String(direction)}`)
              }
            })
          }
        }
      })
  }

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

? Что дальше?

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

? Напишите в комментариях что вы думаете, а так же , что хотите увидеть следующим.
? Предлагайте фичи и улучшения на GitHub.

Комментарии (1)


  1. CzarOfScripts
    19.08.2025 16:49

    Причем тут вообще тайпскрипт господи...