| Тестирование PATCH-запросов | 
| 22.01.2019 00:00 | 
| 
 
 Перевод: Ольга Алифанова. Как и PUT-запросы, PATCH-запросы меняют существующую запись, однако их куда сложнее тестировать! PUT-запрос меняет запись целиком, а PATCH – только одну часть запроса. С PATCH-запросом можно проводить множество различных операций – вы можете добавлять, заменять, удалять, копировать и перемещать значения в вашей записи. Опишу несколько примеров, а потом поговорим о том, как это тестировать. Давайте рассмотрим простой пример записи, которую мы будем менять: JSON-описание первой записи будет выглядеть примерно так: {
    "id": "1",
    "firstName": "John",
    "lastName": "Smith",
    "homePhone": "8005551000",
    "workPhone": null
}Обратите внимание, что в первой записи отсутствует телефон. Проведем операцию добавления через PATCH-запрос, чтобы добавить номер. URL для запроса будет примерно таким: https://app/customer/1, где 1 – это id пользователя, чьи данные мы изменяем, а HTTP-глагол для запроса будет, конечно, PATCH. Тело запроса будет выглядеть как-то так:  [
    {"op":"add","path":"/workPhone","value":"8005551001"}
] "op" в этом случае относится к операции, которую вы выполняете через PATCH. Мы используем операцию "add", добавление. "Path" показывает, к какому полю добавляется значение (в этом случае это поле номера телефона); "value" – это то значение, которое вы передаете в это поле, в этом случае – сам номер. Когда эта операция завершена, JSON-описание будет выглядеть примерно так: {
    "id": 1,
    "firstName": "John",
    "lastName": "Smith",
    "homePhone": "8005551000",
    "workPhone": "8005551001"
}Вот как можно тестировать операцию добавления PATCH: 
 Теперь давайте рассмотрим операцию замены "replace". Обратимся к записи номер 2, и заменим домашний телефон. Запись пока что выглядит вот так: {
    "id": 2,
    "firstName": "Amy",
    "lastName": "Jones",
    "homePhone": "8005551002",
    "workPhone": "8005551003"
}URL для этого запроса - https://app/customer/2, потому что мы меняем вторую запись, а тело запроса будет таким:  [
    {"op":"replace","path":"/homePhone","value":"8005551111"}
] Эта операция заменит исходный номер телефона 8005551002 номером 8005551111, и запись будет выглядеть так: {
    "id": 2,
    "firstName": "Amy",
    "lastName": "Jones",
    "homePhone": "8005551111",
    "workPhone": "8005551003"
}Вот что можно попробовать сделать, тестируя PATCH-операцию "replace": 
 Теперь давайте рассмотрим операцию удаления "remove". Начнем с этой записи: {
    "id": 1,
    "firstName": "John",
    "lastName": "Smith",
    "homePhone": "8005551000",
    "workPhone": "8005551001"
}Для удаления домашнего телефона этого пользователя мы снова воспользуемся URL: app/customer/1 и телом запроса, приведенным ниже:  [
    {"op":"remove", "path":"/homePhone"}
] Вот что мы получим в результате: {
    "id": "1",
    "firstName": "John",
    "lastName": "Smith",
    "homePhone": null,
    "workPhone": "8005551001"
}Операцию "remove" довольно легко тестировать. Нам нужно убедиться, что значение действительно удалено и заменено на null. Также неплохо удостовериться, что никакие иные значения не удалились по ошибке (к примеру, что не удалены оба телефона, а не только домашний). Также можно проверить, что обязательное поле невозможно удалить – мы должны получить соответствующее сообщение об ошибке. Перейдем к операции перемещения "move". Давайте посмотрим на предыдущее состояние записи "Джон" и представим, что она неверна – его рабочий телефон на самом деле его домашний. Чтобы переместить телефон, используем вот такое тело запроса:  [
    {"op":"move","from":"/workPhone","path":"/homePhone"}
] В этом примере "from" обозначает, где сейчас находится значение, а "path" – куда вы его перемещаете. После этой операции запись будет выглядеть так: {
    "id": "1",
    "firstName": "John",
    "lastName": "Smith",
    "homePhone": "8005551001",
    "workPhone": null
}Ниже – идеи для тестирования операции "move": 
 И, наконец, рассмотрим операцию копирования "copy". Она копирует существующее значение в другое место. Возьмем вот этот пример: {
    "id": "1",
    "firstName": "John",
    "lastName": "Smith",
    "homePhone": "8005551001",
    "workPhone": null
}Если мы хотим скопировать домашний телефон в поле рабочего телефона, мы выполним следующий запрос:  [
    {"op":"copy","from":"/homePhone","path":"/workPhone"}
] Поле "from" показывает место, где находится значение, которое мы копируем, а "path" – куда его нужно скопировать. В результате запись будет выглядеть так: {
    "id": "1",
    "firstName": "John",
    "lastName": "Smith",
    "homePhone": "8005551001",
    "workPhone": "8005551001"
}Тестирование операции копирования очень похоже на тестирование операции перемещения: 
 Важно помнить, что PATCH-запросы могут выполняться цепочкой. К примеру, если мы начнем с этого сценария: {
    "id": 2,
    "firstName": "Amy",
    "lastName": "Jones",
    "homePhone": "8005551002",
    "workPhone": "8005551003"
}И отправим PATCH-запрос:  [
    {"op":"remove","path":"/homePhone"},
    {"op":"replace","path":"/workPhone","value":"8005551111"}
] То результат будет таким: {
    "id": 2,
    "firstName": "Amy",
    "lastName": "Jones",
    "homePhone": null,
    "workPhone": "8005551111"
}Когда мы выполняем цепочку запросов PATCH, нужно протестировать, что любая невалидная операция приведет к невалидности запроса целиком. К примеру, если бы мы отправили такой запрос:  [
    {"op":"remove","path":"/homePhone"},
    {"op":"replace","path":"/workPhone","value":"NOTAPHONENUMBER"}
] То мы получили бы сообщение об ошибке, и первая часть PATCH-запроса НЕ должна быть выполнена. Другими словами, домашний телефон все еще будет не пустым. Как можно видеть, PATCH-запросы – это практически набор HTTP-глаголов! Их нужно использовать с особой осторожностью, потому что много чего может пойти не так. Если ваше приложение их использует, убедитесь, что вы протестировали их как по отдельности, так и в комбинации. Не забудьте протестировать и "счастливый путь", и способы, при которых нарушится валидация. Если база данных допускает "плохие" значения, не забудьте проверить патч поверх этих значений. Больше информации по этой теме вы можете получить в курсе Тестирование REST API  |