Использование битовой маски для генерации параметров

Использование битовой маски для генерации параметровОдна из вещей, которые периодически требуются в тестировании, особенно при тестировании различных API, - это генерация сочетаний различных параметров. Скажем, у нас есть несколько параметров, которые могут быть использованы при вызове RESTful сервиса, при этом любой параметр может присутствовать или отсутствовать. Казалось бы, можно использовать циклы для решения этой задачи, но, возможно, более удобным будет использование битовой маски. Давайте посмотрим, как.

Использование циклов для генерации строки параметров

Давайте сначала посмотрим, как это будет выглядеть с циклами. Пусть у нас есть некоторая система, хранящая данные о клиентах какого-то абстрактного сервиса (интернет-провайдер, домофонный сервис, ЖКХ и т.д.). Каждая запись о клиенте включает номер договора, фамилию, имя, отчество, дату рождения, номер паспорта, адрес и телефон. Возьмем для примера 4 параметра, по которым осуществляется поиск (естественно, при условии, что их можно комбинировать):

  1. номер договора (contract),
  2. фамилия (lastName),
  3. имя (firstName),
  4. номер паспорта (passport).

Наша задача будет очень простая: провести позитивный тест и проверить, что при указании от 1 до 4 поисковых параметров сервис возвращает какой-то ответ, если у нас есть такие данные в базе.

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

  1. contract: 12345678
  2. lastName: Иванов
  3. firstName: Сергей
  4. passport: 5101123456

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

Поскольку мы будем рассматривать Java 8, удобнее всего будет написать какой-то DataProvider, который будет возвращать массив строк параметров (одномерный массив) для использования в запросе, каждая из которых будет включать уникальный набор параметров.

Казалось бы, логично это организовать в виде циклов. В данном случае это может выглядеть так:

Каждый цикл отвечает за включение или не включение соответствующего параметра в итоговую строку. Результат вывода будет, в общем, ожидаем. 2 (состояния) в 4 (количество параметров) степени, итого 16 вариантов сочетаний параметров:

Но в таком случае у нас возникает следующая проблема: а что будет, если мы добавим еще два параметра? А потом удалим три? А потом снова добавим четыре? В любом из этих случаев нам придется редактировать код, добавляя или удаляя вложенные циклы. Что в любом случае плохо. Чем больше меняется код, тем потенциально больше шансы сделать ошибку и т.д. Соответственно, надо сделать так, чтобы не трогать сам код, а менять только данные, которыми мы будем оперировать. И в этом нам поможет...

Использование битовой маски для генерации параметров

Использование битовой маски позволит нам избежать вложенных циклов и изменения кода, потому что количество параметров никак не повлияет на то, как будет сгенерирована строка параметров:

Результат будет следующий:

Теперь давайте просто добавим еще один параметр в массив params не изменяя больше ничего:

Теперь результат будет такой:

Вот, собственно, и всё. Это ровно то, что и нужно было. На объем выходных данных влияет только объем входных данных без необходимости изменения кода.

Теперь давайте подробнее посмотрим вот на эти две строчки:

Здесь мы делаем вот что:

  1. Сдвигаем число 1 побитово влево на bitNumber битов.
  2. Выполняем побитовое AND с числом, содержащимся в переменной mask.
  3. Если результат побитового AND равен 0, то добавляем к строке result пустую строку. Результат будет равен нулю только в том случае, если в маске не установлен соответствующий определенному параметру бит. Поскольку (1 AND 1) даёт 1, а (0 AND 1) даёт 0.
  4. Если результат побитового AND не равен 0, то добавляем к строке result параметр, индекс которого соответствует номеру бита. Если строка result не пустая, вставляем перед параметром амперсанд.

В заключение

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

 

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.