Реализация Jest и RTL для начинающих (3/3)


Оглавление

1. Введение
2. Примеры и методы
3. Заключение

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

Введение
В этом посте мы завершаем серию статей о тестировании на Jest следующим содержанием:

  1. Как тестировать условные условия (например, сценарий победы или ничьей), которые отображают определенное содержимое/элементы.
  2. Как протестировать выигрышную комбинацию в игре.

Примеры и методы
Для тестирования условного рендеринга мы сосредоточимся на рендеринге определенных сообщений в этом фрагменте кода, взятом из кода компонента Board в предыдущем посте (часть 2/3):

      {winner ? (
        <h2 data-testid="winnerMessage">
          {winner === "Draw"
            ? "Round Draw. Restart Round."
            : `Player ${winner} is the Winner!`}
        </h2>
      ) : (
        ""
      )}
Вход в полноэкранный режим Выход из полноэкранного режима

тестирование условных рендеров и атрибутов
Как показано выше, это тернарный оператор, вложенный в другой тернарный оператор. Имеется состояние winner, которое содержит строку, имеющую 4 исхода: X или O или Draw или "". Если он пуст, игра будет продолжена. Если Победитель X или Y, будет выведено сообщение о победе, как показано выше. Если это draw, то будет выведено сообщение о ничьей.

Чтобы проверить, отображаются ли различные сообщения, мы будем использовать симуляцию различных наборов ходов. Логика тестирования приведена ниже:

  test("Winner message for player X should appear when winner is decided and button disabled", () => {
    const { getByTestId } = render(<Board />);
    const moveArr = [0, 5, 1, 6, 2];
    for (let index of moveArr) {
      const button = getByTestId(`squareButton${index}`);
      fireEvent.click(button);
    }
    const playerTurnMsg = getByTestId("winnerMessage");
    expect(playerTurnMsg).toHaveTextContent("Player X is the Winner!");
    expect(getByTestId(`squareButton3`)).toHaveAttribute("disabled");
  });
Войти в полноэкранный режим Выход из полноэкранного режима

Первая строка кода — это описание теста. Мы хотим сгенерировать сообщение о победе для X и когда победитель определен, все кнопки всех квадратов должны быть отключены, пока не будет нажата кнопка сброса. Набор ходов, о котором мы говорили выше, выглядит следующим образом: const moveArr = [0, 5, 1, 6, 2]; Цифры — это индексы массива, и мы используем цикл for и fireEvent.click для имитации тестовых ходов. В бэкенде игровое поле должно выглядеть примерно так:

Этот набор ходов позволит игроку X выиграть, и мы будем использовать getByTestId для получения ID элемента JSX, который отображает сообщение о победе, и использовать toHaveTextContent matcher для подтверждения того, что сообщение о победе сгенерировано.
Сразу после этого теста мы используем toHaveAttribute matcher и получим ID любых не нажатых кнопок, чтобы проверить, действительно ли кнопки отключаются после выбора победителя.

тестирование выигрышных комбинаций
Для тестирования комбинаций выигрыша и розыгрыша был создан новый тестовый файл Winner.test.ts. Комбинации показаны на рисунке:

export const drawCombi = [
  ["X", "O", "X", "X", "O", "O", "O", "X", "X"],
  ["X", "O", "X", "O", "O", "X", "X", "X", "O"],
  ["X", "O", "X", "X", "O", "X", "O", "X", "O"],
  ["O", "X", "O", "X", "O", "X", "X", "O", "X"],
  ["X", "O", "O", "O", "X", "X", "X", "X", "O"],
  ["X", "X", "O", "O", "X", "X", "X", "O", "O"],
  ["X", "X", "O", "O", "O", "X", "X", "O", "X"],
  ["O", "X", "X", "X", "O", "O", "X", "O", "X"],
  ["X", "X", "O", "O", "O", "X", "X", "X", "O"],
  ["O", "X", "X", "X", "O", "O", "O", "X", "X"],
  ["X", "O", "X", "O", "X", "X", "O", "X", "O"],
  ["O", "X", "O", "O", "X", "X", "X", "O", "X"],
];

export const winCombi = [
  ["X", "X", "X", "", "", "", "", "", ""],
  ["", "", "", "X", "X", "X", "", "", ""],
  ["", "", "", "", "", "", "X", "X", "X"],
  ["X", "", "", "X", "", "", "X", "", ""],
  ["", "X", "", "", "X", "", "", "X", ""],
  ["", "", "X", "", "", "X", "", "", "X"],
  ["X", "", "", "", "X", "", "", "", "X"],
  ["", "", "X", "", "X", "", "X", "", ""],
];
Вход в полноэкранный режим Выход из полноэкранного режима

Чтобы решить, есть ли победитель, была создана функция decideIfThereIsWinner:

export const winIndexCombi = [
  [0, 1, 2],
  [3, 4, 5],
  [6, 7, 8],
  [0, 3, 6],
  [1, 4, 7],
  [2, 5, 8],
  [0, 4, 8],
  [2, 4, 6],
];

export function decideIfThereIsWinner(arr: String[], select: String) {
  const playerArr: Number[] = [];
  arr.map((a: String, c: Number) => (a === select ? playerArr.push(c) : ""));
  const filteredCombi = winIndexCombi.filter(
    (comb) => comb.filter((steps) => playerArr.includes(steps)).length >= 3,
  );
  const result = filteredCombi.flat(1).length >= 3;
  return result;
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Функция будет брать все возможные комбинации индексов победителей и отображать массив с помощью вложенного метода фильтрации. Если новый массив фильтра filteredCombi имеет длину 3 или более, то она вернет переменную result с булевым значением true. Установив все элементы для перемещения, мы настроим логику тестирования, как показано ниже:

afterEach(cleanup);

describe(Board, () => {
  for (let combi of winCombi) {
    test("Winning Combination for both X and O", () => {
      const arr = combi;
      const result = decideIfThereIsWinner(arr, "X");
      expect(result).toBeTruthy();
    });
  }
  for (let combi of drawCombi) {
    test("Draw Combination check X", () => {
      const arr = combi;
      const result = decideIfThereIsWinner(arr, "X");
      expect(result).toBeFalsy();
    });
  }
  for (let combi of drawCombi) {
    test("Draw Combination check O", () => {
      const arr = combi;
      const result = decideIfThereIsWinner(arr, "O");
      expect(result).toBeFalsy();
    });
  }
});
Войти в полноэкранный режим Выйти из полноэкранного режима

Для проверки выигрышной комбинации, поскольку существует только 8 комбинаций для победы, мы будем ожидать, что все 8 сценариев будут возвращать true boolean из функции decideIfThereIsWinner независимо от того, является игрок X или O. Мы можем использовать toBeTruthy() для подтверждения того, что она возвращает true булево значение для каждого случая. Однако для комбинации ничьих, поскольку X всегда начинает первым, нам нужно проверить обе комбинации ничьих X и O, и мы можем использовать toBeFalsy() matcher для всех случаев, чтобы подтвердить, что случай возвращает false булеву.

Вот и все! Это все тесты, которые я смог придумать. Я надеюсь, что эта серия дала небольшое представление о том, как начать тестировать ваше приложение. Это только вершина айсберга. Если вы хотите узнать больше, официальные документы можно найти на сайте https://jestjs.io/. Спасибо и до следующего раза!

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