Jest параметризованный тест — если условие внутри

#reactjs #jestjs #react-testing-library

#reactjs #jestjs #реагировать-тестирование-библиотека

Вопрос:

Интересно, какой подход лучше. Могу ли я использовать if условие внутри тестов или при наличии таких случаев лучше разделить их на два .each теста?

 test.each([['Option 1'], ['Option 2']])(
    `WHEN selected %s option THEN parameters section is visible`,
    async (optionName) => {
      const { collectButton } = await initializeTest();
      fireEvent.click(screen.getByText(optionName));

      await expectElementToHaveAttribute(collectButton, 'disabled');
      expect(screen.getByText(parametersSectionHeader)).toBeTruthy();
    },
  );

  test.each([['Option a']])(
    `WHEN selected %s option THEN parameters section is NOT visible`,
    async (optionName) => {
      const { collectButton } = await initializeTest();
      fireEvent.click(screen.getByText(optionName));

      await expectElementNotToHaveAttribute(collectButton, 'disabled');
      expect(screen.queryByText(parametersSectionHeader)).toBeFalsy();
    },
  );
 
   test.each([['Option 1', 'visible'], ['Option 2', 'visible'], ['Option a', 'NOT visible']])(
    `WHEN selected %s option THEN parameters section is %s`,
    async (optionName, visibility) => {
      const { collectButton } = await initializeTest();
      fireEvent.click(screen.getByText(optionName));

      if(visibility === 'visible') {
          await expectElementToHaveAttribute(collectButton, 'disabled');
          expect(screen.getByText(parametersSectionHeader)).toBeTruthy();
      } else {
          await expectElementNotToHaveAttribute(collectButton, 'disabled');
          expect(screen.queryByText(parametersSectionHeader)).toBeFalsy();
      }
    },
  );
 

Ответ №1:

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

В этом случае это можно решить, не используя утверждения, специфичные для теста:

   test.each([['Option 1', true], ['Option 2', false], /*...*/])(
    `WHEN selected %s option THEN parameters section is %s`,
    async (optionName, visibility) => {
      const { collectButton } = await initializeTest();
      fireEvent.click(screen.getByText(optionName));

      await expectElementToHaveAttribute(collectButton, 'disabled');
      expect(Boolean(screen.getByText(parametersSectionHeader))).toBe(visibility);
    },
  );
 

Комментарии:

1. Обратите внимание на две вещи: 1. Я хочу иметь понятное имя теста, например, section не отображается, вместо section значение false 2. внутри if условия я вызываю либо expectElementToHaveAttribute или expectElementNotToHaveAttribute , они не совпадают. Вот почему я не могу использовать ваше решение с visibility флагом.

2. Я вижу. Используйте разные параметры теста для метки и значения. Вы можете использовать use some thing вместо expectElementToHaveAttribute и т. Д., Которые могут принимать аргумент. В противном случае это фактически разные тесты.