Шаблоны для тестирования разрешений web API
Я работаю над веб-API для создания файлов cookie в формате JSON. Подумайте о /items/<id> с вашей типичной ГРУБОСТЬЮ delete, patch, get, и post.
Недавно мы начали внедрять новую модель разрешений для API, в которой определенные операции запрещены на основе сочетания свойств пользователя и объекта. Например:
- У нас есть два типа элементов - обычные элементы и
lockedэлементы, и у нас есть два типа пользователей - обычные пользователи и пользователи-администраторы. Пользователи принадлежат кcompany. - Обычные пользователи могут изменять любой обычный элемент, который относится к их
company, но не кlockedэлементам - Пользователи с правами администратора могут изменять любой элемент (обычный или заблокированный) в своем
company.
Итак, матрица для тестирования выглядит примерно так:
- Проверьте, могут ли обычные пользователи выполнять полную проверку обычных элементов в своей компании
- Проверка того, что обычные пользователи могут получать, но не изменять заблокированные элементы в своей компании
- Проверка того, что обычные пользователи не могут изменять элементы, не принадлежащие их компании
- Проверьте, могут ли пользователи-администраторы выполнять полный CRUD для обычных элементов в своей компании
- Проверьте, могут ли пользователи-администраторы выполнять полный CRUD для заблокированных элементов в своей компании
- Проверьте, чтобы пользователи-администраторы не могли выполнять какие-либо действия с товарами, не принадлежащими их компании
Если мы умножим это значение, то получим 32 комбинации:
4 types of operations (delete|patch|post|get)умножается на2 types of users (admin | regular user)...2 types of company ownership (your company | not your company)...2 types of item (locked|unlocked)
В этом есть некоторая избыточность. Нам не нужно тестировать пользователей-администраторов на соответствие обычным элементам или элементам, не входящим в их компанию. Это сокращает количество тестов с 32 до 24. По-прежнему требуется много тестов.
Настройка индивидуальных методов тестирования для этого очень трудоемка. Здравые решения таковы:
- Сделайте этот тест табличным. Он будет многословным и запутанным. Тестовая платформа, которую я использую, не позволяет легко параметризовать тесты. Я использую django test suite - у него есть служебный метод
subTest(), который позволяет запускать тесты в цикле for, но все это происходит в одном и том же контексте настройки / демонтажа (поэтому тесты не изолированы). - Не утруждайте себя тестированием разрешений в рамках интеграционных тестов API. Вместо этого протестируйте базовые функции
has_permissionsв тесте более низкого уровня, не настраивая уровень API. Я сомневаюсь в этом. Я большой поклонник тестирования поведения. CRUD API - это поведение. Если вы удалите все проверки разрешений на уровне API, модульные тесты функции разрешений вам не помогут.
Как вы подходите к этой проблеме таким образом, чтобы создать поддерживаемый тестовый код?