Save 37% off PRO during our Black Friday Sale! »

[ru] Backend Testing Intro

8718586ba62e3ca28bac772a75a427f5?s=47 alexvox
April 21, 2016

[ru] Backend Testing Intro

8718586ba62e3ca28bac772a75a427f5?s=128

alexvox

April 21, 2016
Tweet

Transcript

  1. None
  2. Тестирование бэкенда и что такое API Алексей Вовк, руководитель группы

    тестирования Школа автоматизации тестирования 2016
  3. Содержание • Зачем нужен бэкенд? • Что такое API? •

    Спецификации API • Форматы данных • Тестирование бэкенда через его API 4
  4. • Зачем нужен бэкенд? • Что такое API? 5

  5. • Внутренняя логика • Сложные вычисления • Запросы в базу

    данных, другие сервисы • … Бэкенд 6 Backend Frontend • Взаимодействие с пользователем
  6. • Зачем нужен бэкенд? • Что такое API? • Спецификации

    API 7
  7. API (Application Programming Interface) Набор HTTP-запросов для общения программ между

    собой 8
  8. API 9 API Service

  9. API 10 Client API Backend

  10. API 11 Frontend … API Backend

  11. API 12 A API API B C Backend API API

    Client
  12. API 13 API Backend Client ИНКАПСУЛЯЦИЯ

  13. • Что такое API? • Спецификации API • Форматы данных

    14
  14. API. Спецификации Набор правил, которых придерживается API • SOAP •

    REST • RPC • others… 15
  15. API. Спецификации 16 Wie geht es lhnen? But I speak

    English… О чем эти двое?
  16. API. Спецификации 17 Wie geht es lhnen? Sehr gut Как

    ваше ничего? Норм How are you today? Great! Английский Русский Немецкий
  17. API. Спецификации 18 SOAP REST RPC

  18. REST (Representation State Transfer) • Объекты • HTTP-метод – что

    делаем с объектом 19
  19. REST 20 REST

  20. REST 21 REST POST /robot part=knees action=bend

  21. REST 22 REST done POST /robot part=knees action=bend

  22. REST 23 REST GET /robot part=knees condition=true angle=false

  23. REST 24 REST true GET /robot part=knees condition=true angle=false

  24. REST 25 REST

  25. Robot knees angle:90 REST 26 REST POST /robot/knees …

  26. REST 27 REST 200 OK Robot knees angle:90 POST /robot/knees

  27. REST 28 REST GET /robot/knees

  28. REST 29 REST GET /robot/knees Robot knees angle:90

  29. REST 30 Объект GET PUT POST DELETE /database /table Получаем

    записи таблицы Создаем таблицу Изменяем таблицу Удаляем таблицу REST API table database
  30. • Спецификации API • Форматы данных • Тестирование бэкенда через

    его API 31
  31. Форматы данных 32 Э т о т т е к

    с т д о л ж н о б ы т ь н е у д о б н о ч и т а т ь
  32. XML (eXtensible Markup Language) <cat>white</cat> 33

  33. XML <cat> <type>persian</type> <measures> <length>45</length> <height>22</height> <weight>8</weight> </measures> <color> <main>white</main>

    <spots>brown</spots> </color> </cat> 34
  34. JSON (JavaScript Object Notation) { “cat”: “white” } { “age”:

    5 } { “weight”: 8.2 } { “names”: [“kitty”, “missis”, “bad”] } 35
  35. JSON { “type”: “persian”, “measures”: { “length”: 45 “height”: 22

    “weight”: 8 }, “color”: { “main”: “white” “spots”: “brown” } } 36
  36. API • API – для общения программ между собой •

    Спецификация API – набор правил, «язык» на котором общаются программы • Формат данных – в каком виде передаются данные 37
  37. • Форматы данных • Тестирование бэкенда через его API •

    конец близок 38
  38. Тестирование бэкенда 39 Описание API -------------------- -------------------- --------------------

  39. 40

  40. 41 ~$ curl

  41. curl curl <URI> 42

  42. ~$ curl https://cloud-api.yandex.ru/v1/disk

  43. ~$ curl https://cloud-api.yandex.ru/v1/disk {"message":"Не авторизован.","description": "Unauthorized", "error":"UnauthorizedError"}

  44. curl. Опции curl [-<опции>] <URI> -v (--verbose) --help 45

  45. ~$ curl -v https://cloud-api.yandex.ru/v1/disk

  46. > < HTTP/1.1 401 UNAUTHORIZED < Server: nginx < Date:

    Wed, 16 Mar 2016 16:25:47 GMT < Content-Type: application/json < Content-Length: 99 < Connection: keep-alive < Access-Control-Allow-Origin: * < Access-Control-Allow-Headers: Accept-Language, Accept, X-HTTP-Method, X-Requested-With, Content-Type, Authorization < Access-Control-Allow-Credentials: true < {"message":"Не авторизован.","description":"Unauthorized", "error":"UnauthorizedError"}
  47. curl. Заголовки curl … <URI> -H '<Имя>: <Значение>' -H '<Имя_2>:

    <Значение_2>' ... 48
  48. Авторизация -H 'Authorization: Basic <логин:пароль>' -H 'Cookie: <имя куки=значение>' -H

    'Authorization: OAuth <токен>' 49
  49. OAuth авторизация 50 App Login/password Token Authorization Service Service Token

  50. OAuth авторизация 51 App A • Только чтение • Выдан

    до 01.01.2018 App B • Только запись • Выдан до 15.04.2017 App C • Полный доступ • Выдан бессрочно
  51. ~$ curl -v -H 'Authorization: OAuth fe2cb3fc66e34eb4910137cae4ca9bc8' https://cloud- api.yandex.ru/v1/disk

  52. > < HTTP/1.1 200 OK < Server: nginx < Date:

    Wed, 16 Mar 2016 16:30:59 GMT < Content-Type: application/json; charset=utf-8 < Content-Length: 165 < Connection: keep-alive < Vary: Accept-Encoding < Access-Control-Allow-Origin: * < Access-Control-Allow-Headers: Accept-Language, Accept, X-HTTP- Method, X-Requested-With, Content-Type, Authorization < Access-Control-Allow-Methods: GET, OPTIONS < Access-Control-Allow-Credentials: true < {"trash_size":0,"total_space":10737418240,"used_space":83291316,"s ystem_folders":{"applications":"disk:/Приложения","downloads":"dis k:/Загрузки/"}}
  53. 54 http://pro.jsonlint.com/

  54. 55

  55. 56

  56. 57

  57. 58

  58. 59

  59. 60

  60. ~$ curl -v -H 'Authorization: OAuth fe2cb3fc66e34eb4910137cae4ca9bc8' https://cloud- api.yandex.ru/v1/disk |

    python -m json.tool
  61. > < HTTP/1.1 200 OK …………………………………………………………………………………………………………………………………………………………………………… < Access-Control-Allow-Origin: * <

    Access-Control-Allow-Headers: Accept-Language, Accept, X-HTTP- Method, X-Requested-With, Content-Type, Authorization < Access-Control-Allow-Methods: GET, OPTIONS < Access-Control-Allow-Credentials: true < { "system_folders": { "applications": "disk:/Приложения", "downloads": "disk:/Загрузки/" }, "total_space": 10737418240, "trash_size": 0, "used_space": 83291316 }
  62. curl. Параметры запроса curl … <URI>?<Параметр>=<Значение> &<Параметр_2>=<Значение> &<Параметр_3>=<Значение> … 63

  63. ~$ curl -v -H 'Authorization: OAuth fe2cb3fc66e34eb4910137cae4ca9bc8' https://cloud-api.yandex.ru /v1/disk/resources?path=/folder1/myfile.txt |

    python -m json.tool <URI> ? path=<path>
  64. > < HTTP/1.1 200 OK …………………………………………………………………………………………………………………………………………………………………………………………… < Access-Control-Allow-Origin: * <

    Access-Control-Allow-Headers: Accept-Language, Accept, X-HTTP-Method, X-Requested-With, Content-Type, Authorization < Access-Control-Allow-Methods: PUT, PATCH, DELETE, GET, OPTIONS < Access-Control-Allow-Credentials: true < { "created": "2016-03-15T17:43:48+00:00", "md5": "0c2fdbeced2f07c68e8ddc85698ea643", "media_type": "document", "mime_type": "text/plain", "modified": "2016-03-15T17:43:48+00:00", "name": "myfile.txt", "path": "disk:/folder1/myfile.txt", "size": 126976, "type": "file" }
  65. ~$ curl -v -H 'Authorization: OAuth fe2cb3fc66e34eb4910137cae4ca9bc8' 'https://cloud-api.yandex.ru /v1/disk/resources?path=/folder1/myfile.txt&fields= name'

    | python -m json.tool <URI> ? path=<path> & fields=<fields>
  66. > < HTTP/1.1 200 OK ……………………………………………………………………………………………………………………………………………………… < Access-Control-Allow-Origin: * <

    Access-Control-Allow-Headers: Accept-Language, Accept, X-HTTP-Method, X-Requested-With, Content-Type, Authorization < Access-Control-Allow-Methods: PUT, PATCH, DELETE, GET, OPTIONS < Access-Control-Allow-Credentials: true < { "name": "myfile.txt" }
  67. curl. Кавычки curl … '<URI>?param1=value 1' 68

  68. URLEncode • В url’е передаем только латинские символы • Остальные

    символы заменяем на соответствующий им код 69 @ %40
  69. ~$ curl -v -H 'Authorization: OAuth fe2cb3fc66e34eb4910137cae4ca9bc8' 'https://cloud- api.yandex.ru/v1/disk/resources/?path=/folder1/ myfile&1.txt'

    | python -m json.tool ~$ curl -v -H 'Authorization: OAuth fe2cb3fc66e34eb4910137cae4ca9bc8' 'https://cloud- api.yandex.ru/v1/disk/resources/?path=/folder1/ myfile%261.txt' | python -m json.tool myfile&1 myfile%261
  70. ~$ curl -v -H 'Authorization: OAuth fe2cb3fc66e34eb4910137cae4ca9bc8' 'https://cloud- api.yandex.ru/v1/disk/resources/?path=/folder1/ myfile

    1.txt' | python -m json.tool ~$ curl -v -H 'Authorization: OAuth fe2cb3fc66e34eb4910137cae4ca9bc8' https://cloud- api.yandex.ru/v1/disk/resources/?path=/folder1/ myfile%201.txt | python -m json.tool myfile 1 myfile%201
  71. ~$ curl -v -H 'Authorization: OAuth fe2cb3fc66e34eb4910137cae4ca9bc8' 'https://cloud- api.yandex.ru/v1/disk/resources/?path=/folder1/ мой

    файл.txt' ~$ curl -v -H 'Authorization: OAuth fe2cb3fc66e34eb4910137cae4ca9bc8' 'https://cloud- api.yandex.ru/v1/disk/resources/?path=/folder1/ %D0%BC%D0%BE%D0%B9%20%D1%84%D0%B0%D0%B9%D0%BB.txt' мой файл %D0%BC%D0%BE%D0%B9%20%D1%84%D0%B0%D0%B9%D0%BB
  72. Куда смотреть? 73

  73. ~$ curl –v -H 'Authorization: OAuth fe2cb3fc66e34eb4910137cae4ca9bc8‘ 'https://cloud-api.yandex.ru /v1/disk/resources ?path=/folder1/myfile.txt

    &fields=name' Заголовки URI Параметры
  74. ~$ curl –v -H 'Authorization: OAuth fe2cb3fc66e34eb4910137cae4ca9bc8‘ 'https://cloud-api.yandex.ru /v1/disk/resources ?path=/folder1/myfile.txt

    &fields=name' Заголовки Параметры URI
  75. ~$ curl –v -H 'Authorization: OAuth fe2cb3fc66e34eb4910137cae4ca9bc8‘ 'https://cloud-api.yandex.ru /v1/disk/resources ?path=/folder1/myfile.txt

    &fields=name' Заголовки Параметры URI
  76. ~$ curl –v -H 'Authorization: OAuth fe2cb3fc66e34eb4910137cae4ca9bc8‘ 'https://cloud-api.yandex.ru /v1/disk/resources ?path=/folder1/myfile.txt

    &fields=name' Заголовки Параметры URI
  77. > < HTTP/1.1 200 OK < Access-Control-Allow-Origin: * < Access-Control-Allow-Headers:

    Accept-Language, Accept, X-HTTP-Method, X-Requested-With, Content-Type, Authorization < Access-Control-Allow-Methods: PUT, PATCH, DELETE, GET, OPTIONS < Access-Control-Allow-Credentials: true < { "created": "2016-03-15T17:43:48+00:00", "md5": "0c2fdbeced2f07c68e8ddc85698ea643", "media_type": "document", "mime_type": "text/plain", "modified": "2016-03-15T17:43:48+00:00", "name": "myfile.txt", "path": "disk:/folder1/myfile.txt", "size": 126976, "type": "file" } Код ответа Заголовки Тело ответа
  78. > < HTTP/1.1 200 OK < Access-Control-Allow-Origin: * < Access-Control-Allow-Headers:

    Accept-Language, Accept, X-HTTP-Method, X-Requested-With, Content-Type, Authorization < Access-Control-Allow-Methods: PUT, PATCH, DELETE, GET, OPTIONS < Access-Control-Allow-Credentials: true < { "created": "2016-03-15T17:43:48+00:00", "md5": "0c2fdbeced2f07c68e8ddc85698ea643", "media_type": "document", "mime_type": "text/plain", "modified": "2016-03-15T17:43:48+00:00", "name": "myfile.txt", "path": "disk:/folder1/myfile.txt", "size": 126976, "type": "file" } Код ответа Заголовки Тело ответа
  79. Коды ответов • 1xx – информационные • 2xx – успех

    • 3xx – перенаправление • 4xx – ошибка клиента • 5xx – ошибка сервера 80
  80. 81

  81. > < HTTP/1.1 200 OK < Access-Control-Allow-Origin: * < Access-Control-Allow-Headers:

    Accept-Language, Accept, X-HTTP-Method, X-Requested-With, Content-Type, Authorization < Access-Control-Allow-Methods: PUT, PATCH, DELETE, GET, OPTIONS < Access-Control-Allow-Credentials: true < { "created": "2016-03-15T17:43:48+00:00", "md5": "0c2fdbeced2f07c68e8ddc85698ea643", "media_type": "document", "mime_type": "text/plain", "modified": "2016-03-15T17:43:48+00:00", "name": "myfile.txt", "path": "disk:/folder1/myfile.txt", "size": 126976, "type": "file" } Код ответа Заголовки Тело ответа
  82. > < HTTP/1.1 200 OK < Access-Control-Allow-Origin: * < Access-Control-Allow-Headers:

    Accept-Language, Accept, X-HTTP-Method, X-Requested-With, Content-Type, Authorization < Access-Control-Allow-Methods: PUT, PATCH, DELETE, GET, OPTIONS < Access-Control-Allow-Credentials: true < { "created": "2016-03-15T17:43:48+00:00", "md5": "0c2fdbeced2f07c68e8ddc85698ea643", "media_type": "document", "mime_type": "text/plain", "modified": "2016-03-15T17:43:48+00:00", "name": "myfile.txt", "path": "disk:/folder1/myfile.txt", "size": 126976, "type": "file" } Код ответа Заголовки Тело ответа
  83. { "created": "2016-03-15T17:43:48+00:00", "md5": "0c2fdbeced2f07c68e8ddc85698ea643", "media_type": "document", "mime_type": "text/plain", "modified":

    "2016-03-15T17:43:48+00:00", "name": "myfile.txt", "path": "disk:/folder1/myfile.txt", "size": 126976, "type": "file" }
  84. 85

  85. { "created": "2016-03-15T17:43:48+00:00", "md5": "0c2fdbeced2f07c68e8ddc85698ea643", "media_type": "document", "mime_type": "text/plain", "modified":

    "2016-03-15T17:43:48+00:00", "name": "myfile.txt", "path": "disk:/folder1/myfile.txt", "size": 126976, "type": "file" }
  86. 87

  87. 88

  88. ~$ curl -v -H 'Authorization: OAuth fe2cb3fc66e34eb4910137cae4ca9bc8' 'https://cloud-api.yandex.ru/v1/disk /resources/move?from=/folder1/letsmoveit.mp3 &path=/folder2/letsmoveit.mp3'

    | python -m json.tool
  89. > < HTTP/1.1 405 METHOD NOT ALLOWED < Server: nginx

    < Date: Wed, 16 Mar 2016 16:55:52 GMT < Content-Type: application/json < Content-Length: 126 < Connection: keep-alive < Access-Control-Allow-Origin: * < Access-Control-Allow-Headers: Accept-Language, Accept, X-HTTP- Method, X-Requested-With, Content-Type, Authorization < Access-Control-Allow-Credentials: true < { "description": "Method Not Allowed", "error": "MethodNotAllowedError", "message": "Метод не поддерживается." }
  90. curl. Метод curl -X <Метод> … 91

  91. ~$ curl -v -X POST -H 'Authorization: OAuth fe2cb3fc66e34eb4910137cae4ca9bc8' 'https://cloud-api.yandex.ru/v1/disk

    /resources/move?from=/folder1/letsmoveit.mp3 &path=/folder2/letsmoveit.mp3' | python -m json.tool
  92. > < HTTP/1.1 201 CREATED < Server: nginx < Date:

    Wed, 16 Mar 2016 17:00:09 GMT < Content-Type: application/json; charset=utf-8 < Content-Length: 135 < Connection: keep-alive < Access-Control-Allow-Origin: * < Access-Control-Allow-Headers: Accept-Language, Accept, X-HTTP-Method, X-Requested-With, Content-Type, Authorization < Access-Control-Allow-Methods: POST, OPTIONS < Access-Control-Allow-Credentials: true < { "href": "https://cloud- api.yandex.ru/v1/disk/resources?path=disk%3A%2Ffolder2%2Fletsmoveit.mp3" , "method": "GET", "templated": false }
  93. ~$ curl -v -X GET -H 'Authorization: OAuth fe2cb3fc66e34eb4910137cae4ca9bc8' 'https://cloud-api.yandex.ru/v1/disk/resources

    ?path=/folder2/letsmoveit.mp3' | python -m json.tool Проверяем, что операции действительно выполняются
  94. > < HTTP/1.1 200 OK ……………………………………………………………………………………………………………………………………………………………………………………………… < Access-Control-Allow-Origin: * <

    Access-Control-Allow-Headers: Accept-Language, Accept, X-HTTP-Method, X-Requested-With, Content-Type, Authorization < Access-Control-Allow-Methods: PUT, PATCH, DELETE, GET, OPTIONS < Access-Control-Allow-Credentials: true < { "created": "2016-03-16T12:42:31+00:00", "md5": "a89533ef839242ded6545c78551b3217", "media_type": "audio", "mime_type": "audio/mpeg", "modified": "2016-03-16T12:42:31+00:00", "name": "letsmoveit.mp3", "path": "disk:/folder2/letsmoveit.mp3", "size": 126976, "type": "file" }
  95. ~$ curl -v -X GET -H 'Authorization: OAuth fe2cb3fc66e34eb4910137cae4ca9bc8' 'https://cloud-api.yandex.ru/v1/disk/resources

    ?path=/folder1/letsmoveit.mp3' | python -m json.tool
  96. > < HTTP/1.1 404 NOT FOUND ……………………………………………………………………………………………………………………………………………………… < Access-Control-Allow-Origin: *

    < Access-Control-Allow-Headers: Accept-Language, Accept, X-HTTP-Method, X-Requested-With, Content-Type, Authorization < Access-Control-Allow-Credentials: true < { "description": "Resource not found.", "error": "DiskNotFoundError", "message": "Не удалось найти запрошенный ресурс." }
  97. curl. Тело запроса curl … '<URI>' -d'<Тело запроса>' 98

  98. ~$ curl -v -X POST -H 'If-Match: 0' -H 'Authorization:

    OAuth 0419096515ab425bb755bc330f343353' 'https://cloud- api.yandex.ru/v1/data/user/databases/mydb/deltas' -d '{"delta_id": "1", "changes": [{"record_id": "1", "collection_id": "123", "change_type": "insert", "changes": [{"change_type": "set", "field_id": "myfield", "value": {"string": "test"}}]}],}'
  99. > < HTTP/1.1 201 CREATED < Server: nginx < Date:

    Thu, 17 Mar 2016 12:52:17 GMT < Content-Type: application/json; charset=utf-8 < Content-Length: 128 < Connection: keep-alive < Access-Control-Allow-Methods: POST, GET, OPTIONS < Access-Control-Expose-Headers: ETag < ETag: 1 < Access-Control-Allow-Credentials: true < Access-Control-Allow-Origin: * < Access-Control-Allow-Headers: Accept-Language, Accept, X-HTTP-Method, X- Requested-With, Content-Type, Authorization < { "href": "https://cloud- api.yandex.ru/v1/data/user/databases/mydb/deltas?base_revision=1", "method":"GET", "templated":false }
  100. ~$ curl -v -X GET -H 'Authorization: OAuth 0419096515ab425bb755bc330f343353' 'https://cloud-api.yandex.ru/v1/data/user

    /databases/mydb/snapshot' | python -m json.tool
  101. { "created": "2016-03-17T12:50:24.820000+00:00", "database_id": "mydb", "modified": "2016-03-17T12:52:17.410000+00:00", "records": { "items":

    [ { "collection_id": "123", "fields": [ { "field_id": "myfield", "value": { "string": "test", "type": "string" } } ], "record_id": "1", "revision": 1 } ] }, "records_count": 1, "revision": 1 }
  102. curl. Структура curl [-Опции] -X Метод -H 'Заголовок: Значение' …

    'URI?Параметр=Значение&Параметр=Значение…' -d 'Тело запроса' 103
  103. Проверяем • Входные и выходные данные • Граничные значения и

    классы эквивалентности • Бэкенд не живет сам по себе • Операция действительно выполнена 104
  104. Полезные ссылки Описание curl: http://bit.ly/yaqa-curl Про Swagger: http://bit.ly/yaqa-swagger Пример Swagger’а

    от разработчиков: http://bit.ly/yaqa-swagger-demo Документирование API с помощью RAML: http://bit.ly/yaqa-raml REST vs. SOAP: http://bit.ly/yaqa-rest-soap Потренироваться делать запросы в API Яндекс.Диска: http://bit.ly/yaqa-poligon Описание работы с базами данных DataSync API: http://bit.ly/yaqa-datasync Видео о REST API Яндекс.Диска и разработке REST вообще: http://bit.ly/yaqa-disk-rest-video 105
  105. Есть вопросы? Самое время задать