Как сохранить JSON на сервере
Мы уже научились отправлять на сервер и принимать обратно данные в JSON-формате. Финальный шаг — будем хранить все наши данные на сервере, чтобы получить доступ к ним с любого устройства. Это поможет нам делать проекты независимыми от локального хранилища.
Как это будет работать
Мы возьмём код из прошлого проекта про отправку JSON на сервер и добавим в него новые возможности.
Логика будет такая:
- Мы научим сервер каждый раз запоминать данные, которые отправит ему наша страница. Чтобы убедиться, что данные в порядке, мы сразу же в ответ будем посылать результат — то, как сервер это запомнил.
- После этого мы поработаем с данными от сервера в понятном для JavaScript виде. Для этого мы немного их поменяем и отправим обратно на сохранение. Это поможет нам понять, как работать с данными в других проектах.
Мы специально используем самые простые и не самые лучшие конструкции в PHP и JavaScript. Наша цель — собрать быстрый прототип и показать, как можно обмениваться данными с сервером. Когда разберёмся с этим, можно и код пооптимизировать. А пока так.
Сохраняем JSON в файл на сервере
Сейчас работает так — по нажатию на кнопку «Проверить JSON» наша страница отправляет на сервер JSON-строку с двумя ключами: именем и фамилией. Новая задача сервера — сохранять себе все полученные данные и отправлять их обратно на страницу. Чтобы данные не потерялись после окончания работы программы, будем сохранять их на сервере в файл json.data . Мы выбрали такое название, но вы можете взять любое другое, имя файла ни на что не влияет.
Так как по нажатию этой кнопки страница обращается на сервере к файлу json.php, то и изменять тоже нужно именно его. Сделаем так:
- Получаем данные от страницы (это уже сделано в прошлом проекте).
- Проверяем, есть ли на сервере нужный нам файл с данными — json.data.
- Если есть — запоминаем его содержимое, а если такого файла нет — создаём его отдельной командой.
- Всё, что было в этом файле, переводим в массив, с которым умеет работать PHP. Таким способом у нас каждая JSON-запись будет храниться в отдельной ячейке массива.
- Добавляем новую запись в этот массив — кладём в него то, что пришло со страницы.
- Записываем это всё обратно в файл и тут же читаем обратно из него — так мы убедимся, что запись прошла нормально и мы можем с этим работать.
- Отправляем всё содержимое файла на страницу, чтобы там увидеть, что сервер работает как нужно.
Задача этого алгоритма — сохранять данные на сервере и отдавать их обратно на страницу. На языке PHP то же самое будет выглядеть так:
Обратите внимание на последние строки в коде — мы освобождаем память на сервере, чтобы она не хранила те переменные, которые нам уже не нужны. Зачем это делать и что будет, если этого не делать, — почитайте в статье про сборщики мусора.
Подготавливаем страницу
Теперь научим нашу страницу правильно обрабатывать ответ от сервера и работать с полученными данными. Для этого нам нужно:
- Преобразовать сырые данные, полученные от сервера, в вид, понятный для JavaScript.
- Любым образом поменять их значения.
- Отправить изменённые данные назад на сервер.
- Получить сразу их обратно и вывести на экран, чтобы убедиться, что сервер правильно понял все изменения.
Перед тем как работать с полученными данными в JavaScript, нам нужно их куда-то сохранить. Для этого в самом начале скрипта заведём новую переменную res , и добавим в функцию sendJSON() такую строку:
// запоминаем данные, которые пришли с сервера
Теперь в этой переменной у нас будут лежать сырые данные, которые отправит нам сервер.
Чтобы мы могли отдельно управлять всеми изменениями, добавим в наш HTML-файл с прошлого проекта новую кнопку рядом с первой:
<!— эта кнопка поменяет полученные данные
и отправит их снова на сервер —!>
Сделаем функцию editJSON(), которая сработает по нажатию на эту кнопку. Работать она будет так:
- Возьмёт сырые данные от сервера и преобразует их в формат, понятный для JavaScript.
- Найдёт все имена, посчитает количество символов в них и допишет это число к имени. Так мы поймём, что данные можно менять как нам нужно.
- Преобразует всё это обратно в JSON и отправит на сервер.
- На всякий случай снова выведет результат на странице, чтобы мы убедились, что на сервере лежат уже новые данные.
Чтобы не писать код заново, мы скопируем уже существующую функцию sendJSON(), переименуем её в editJSON() и добавим в неё то, что нам нужно. А перед этим в самом начале скрипта снова добавим две новые переменные:
- newData , где мы будем хранить данные в понятном формате;
- sendData , куда мы поместим новую JSON-строку перед отправкой на сервер.
Что мы делаем с JSON, полученным с сервера
Перед тем как показать финальный код, поясним один момент. Мы переводим данные с сервера в формат для JavaScript командой
В результате мы получаем двумерный массив, с которым можно работать так:
Дело тут вот в чём: первая цифра в квадратных скобках отвечает за порядковый номер JSON-записи, которые мы отправляли на сервер. Нумерация идёт с нуля, как принято у программистов.
Вторая цифра у нас всегда 0, потому что хотя это и двумерный массив, но каждая запись состоит всего из одного элемента. Так как нумерация с нуля, то мы и пишем 0.
После этого через точку идёт имя поля — у нас это name и lastname. Через них мы можем обращаться к конкретным значениям и менять в них что угодно.
Такая громоздкость получилась из-за того, что мы решили проблему в лоб — просто перевели данные с помощью встроенных средств языка. Это можно было сделать гораздо красивее, но так — быстрее.
Сам код новой функции:
Делаем новый PHP-обработчик на сервере
В скрипте мы обращались к файлу edit.php, которого у нас ещё нет. Всё, что нужно от этого файла, — чтобы он сохранил то, что ему пришло, и тут же отправил это обратно, чтобы мы убедились, что всё хорошо. Мы специально выносим такую простую функцию в отдельный файл, чтобы каждый из них отвечал за свою область работы.
Сам файл довольно прост:
Что дальше
Теперь у нас всё готово, чтобы переделать наши старые проекты и научить их хранить свои данные в облаке. Этим и займёмся.
Allure-Framework. Работа с кодом
Продолжая серию публикаций о возможностях Allure-framework, сегодня мы поговорим о работе с кодом. Под катом разбираем, что такое шаг теста, как выводить информацию в отчет при выполнении шагов и какие бывают категории дефектов. Кроме того, расскажем об аннотациях Allure. Дальше еще интереснее!
Шаг теста. Определение и аннотация @Step
Для визуализации процессов, протекающих в ваших тестах, необходимо использовать шаги. Шаг должен представлять какое-то атомарное действие или проверку. Собственно последовательность шагов и представляет ваш тест. Для наглядности в шаге должны быть описаны входные параметры, а также ожидаемый и фактический результат, если шаг представляет собой проверку.
В Allure для обозначения тестового шага над методом необходимо проставить аннотацию @Step. Затем необходимые шаги-методы включаются в тело тестового метода: тесты с аннотацией @Test.
Рассмотрим пример
Создадим метод с аннотацией @Step, который проверяет соответствие суммы двух слагаемых ожидаемому результату:
Теперь создадим тестовый метод, использующий данный шаг:
При прогоне данного автотеста мы получим следующий отчет:

Аннотация @Step умеет принимать параметр «value», который позволяет указывать имя шага на русском языке. Кроме того, имя шага можно параметризировать – передать в него значения аргументов, передающихся в шаг.
Продемонстрируем на примере
При использовании данного шага в тесте получим отчет:
Вывод информации в отчет при выполнении шагов теста. Вложения
Вложения могут иметь 4 характеристики:
• value/name — наименование вложения;
• type — тип информации в соответствии со стандартом MIME;
• content — содержимое вложения;
• fileExtension — опциональное расширение файла вложения, начинающееся с точки.
Вложения к отчету можно прикреплять 2 способами: с помощью аннотации @Attachment и с помощью статического метода addAttachment класса Allure.
Прикрепление вложений с помощью аннотации @Attachment
В данном способе создается метод, возвращающий массив байтов, над ним размещается аннотация @Attachment. При использовании данного метода считанная информация будет добавлена в отчет в виде файла с соответствующим расширением. Наименование вложения будет таким же, как и имя вызываемого метода.
Продемонстрируем на примере
Создадим метод, который будет зачитывать вложение:
Создадим тестовый шаг, который будет использовать данный метод:
Ну и наконец напишем тест, в котором будет использоваться наш шаг:
В результате прогона данного теста получим отчет:

В аннотации @Attachment можно задавать дополнительные уточняющие параметры:
При использовании данного метода в своих шагах attachment получит наименование «Вложение», содержимое вложения подсветится в соответствии с шаблоном «json», а само вложение будет сохранено в формате «.txt»:

Если поменять тип на «plain/text», то никакой характерной для json-style подсветки ключей-значений уже не будет:
Прикрепление вложений с помощью статического метода addAttachment класса Allure
В данном способе можно прикрепить вложение к шагу теста/тесту, используя перегруженный статический метод addAttachment из класса Allure. В этот метод можно передавать до 4 аргументов — 2 из них обязательны (имя вложения и сам прикладываемый контент), 2 опциональны (расширение файла и MIME-тип).
Другие аннотации Allure
Кроме наиболее известных аннотаций @Step и @Attachment, Allure в своем составе имеет целый ряд других аннотаций:
Аннотация @Description
@Description — аннотация, размещаемая над тестом или шагом. Позволяет прикрепить описание к тесту или шагу теста. Данная аннотация может принимать параметры «value» — текст описания и «useJavaDoc». При установке значения «true» последнему параметру, в качестве описания будет браться джавадок, размещенный над методом.
Приведем пример использования данной аннотации

Аннотации функциональности
Приведем пример использования данных аннотаций
При выполнении тестов и последующем формировании отчета, в разделе Behaviors мы увидим, что тесты сгруппированы в многоуровневый список (@Epic → @Feature → @Story):

Аннотация @Flaky
@Flaky — аннотация, размещаемая над тестом. Позволяет пометить автотест как нестабильный. Если автотест падает хотя бы в одном перезапуске (например, папка «target» между прогонами одного и того же теста не очищается) — в отчете на данном тесте вы увидите знак бомбы. Кроме того, данной аннотацией можно помечать классы с нестабильными тестами.
Приведем пример использования данной аннотации
Обратите внимание, что ветвления в тестах делать не стоит: в данном случае блок if — else используется лишь для того, чтобы сделать тест нестабильным!
При нескольких прогонах теста в режиме перезапуска отчет примет следующий вид:

Аннотации ссылок на тест-кейсы и дефекты
@Issue — аннотация, размещаемая над тестом. Позволяет линковать автотесты с заведенными Issue. Данная аннотация принимает параметр «value», в котором указывается ID дефекта в баг-треккинговой системе.
@Issues — тоже самое, что и @Issue, но в качестве параметра «value» принимает массив Issue.
@TmsLink — аннотация, размещаемая над тестом. Позволяет линковать автотесты с тестовыми кейсами, шаги которых описаны в системах управления тестированием. Данная аннотация принимает параметр «value», в котором указывается ID теста в системе управления тестированием.
@TmsLinks — тоже самое, что и @TmsLink, но в качестве параметра «value» принимает массив TmsLink’ов.
Чтобы из ID дефекта/тест-кейса, указанного в параметре «value», получить полноценную ссылку, необходимо в allure.properties (который должен быть размещен в classpath, например, в src/test/resources) описать шаблон ссылки до соответствующего дефекта/тест-кейса.
При генерации отчета Allure подставит вместо символов <> значения, которые были указаны в параметре value Вашей аннотации, и вы получите полноценные ссылки.
Приведем пример использования данных аннотаций

Аннотации прочих ссылок
@Link — аннотация, размещаемая над тестом. Позволяет приложить к автотесту ссылки на какие-то внешние ресурсы. Данная аннотация может принимать параметры «name» — наименование ссылки (по умолчанию, url), «value» — синоним «name», «url» — адрес, по которому нужно выполнить переход и «type» — параметр, применяемый для создания иконки для ссылки.
@Links — тоже самое, что и @Link, но в качестве параметра «value» принимает массив Link’ов.
Приведем пример использования данных аннотаций

Аннотация @Owner
@Owner — аннотация, размещаемая над тестом. Позволяет указать ответственное лицо за тест. Данная аннотация принимает параметр «value», в котором указывается информация об авторе автотеста.
Приведем пример использования данной аннотации

Аннотация @Severity
@Severity — аннотация, размещаемая над тестом. Позволяет указать уровень критичности функционала, проверяемого автотестом. Данная аннотация принимает параметр «value», который может быть одним из элементов enum SeverityLevel: BLOCKER, CRITICAL, NORMAL, MINOR или TRIVIAL.
Приведем пример использования данной аннотации

Параметризованные автотесты в Allure
Allure умеет работать с параметризованными автотестами. Рассмотрим на примере JUnit 4.12.
Для начала создадим тестовый класс с параметризованными тестами следующего вида:
Теперь прогоним наш тест и соберем отчет:

Allure представляет наш параметризованный тест как набор тестов, если провалиться в какой-либо тест, то мы получим детальную информацию о прогоне именно этого кейса.
Категории дефектов. Распределение дефектов по категориям
Приведем пример кастомной классификации дефектов. Создадим файл categories.json:
• name — наименование категории. Оно будет отображаться на вкладке «Categories» на самом верхнем уровне классификации. Обязательный атрибут.
• matchedStatuses — список статусов, с одним из которых должен завершиться тест, чтобы попасть в данную категорию. Из коробки доступны статусы «failed», «broken», «passed», «skipped» и «unknown». Необязательный атрибут.
• messageRegex — регулярное выражение, которому должно соответствовать Exception-сообщение, чтобы попасть в данную категорию. Необязательный атрибут.
• traceRegex — регулярное выражение, которому должно соответствовать Exception-StackTrace, чтобы попасть в данную категорию. Необязательный атрибут.
Теперь прогоним тесты, обнаруживающие такие дефекты, и посмотрим, как будет выглядеть отчет на вкладке «Categories»:

Тестовое окружение. Блок ENVIRONMENT на главной странице отчета
Allure-отчет позволяет выводить на своей главной странице в специальном блоке информацию о тестовом окружении, на котором были прогнаны тесты. Выглядит это так:

Информация, которая отображается в данном блоке, попадает туда из специального файла environment.properties.
Приведем пример данного файла:
Данный файл необходимо подложить в директорию «target/allure-results» до сборки html-отчета. Сделать это можно вручную, а можно использовать maven-resources-plugin.
Приведем пример его использования в данной ситуации, при условии размещения environment.properties в поддиректории resources директории test. Для этого модифицируем pom.xml:
Теперь при сборке проекта environment.properties будет попадать в «target/allure-results» и участвовать в построении html-отчета.
Заключение
Во второй части лонгрида мы постарались подробно рассказать об аннотациях в Allure, привели примеры их использования. Затронули категории дефектов, тестовое окружение и способы вывода информации в отчет. Приглашаем к обсуждению в комментариях.
Подписывайтесь на блог ЕФС, следите за новыми публикациями. Скоро мы снова расскажем что-то новое и полезное про Allure.
Основы работы с JSON
JSON (JavaScript Object Notation) – это формат передачи данных. Из названия видно, что формат основан на языке программирования JavaScript, однако он доступен и в других языках (Python, Ruby, PHP, Java).
JSON использует расширение .json. При использовании его в других файловых форматах (например, .html) строка JSON берётся в кавычки или присваивается переменной. Этот формат легко передаётся между веб-сервером и клиентом или браузером.
Легковесный и простой для восприятия JSON – отличная альтернатива XML.
Данное руководство ознакомит вас с преимуществами, объектами, общей структурой и синтаксисом JSON.
Синтаксис и структура JSON
Объект JSON имеет вид «ключ-значение» и обычно записывается в фигурных скобках. При работе с JSON все объекты хранятся в файле .json, но также они могут существовать как отдельные объекты в контексте программы.
Объект JSON выглядит так:
«first_name» : «John»,
«last_name» : «Smith»,
«location» : «London»,
«online» : true,
«followers» : 987
Это очень простой пример. Объект JSON может содержать множество строк.
Как видите, объект состоит из пар «ключ-значение», которые заключены в фигурные скобки. Большая часть данных в JSON записывается в виде объектов.
Между ключом и значением ставится двоеточие. После каждой пары нужно поставить запятую. В результате получается:
«key» : «value», «key» : «value», «key»: «value»
Ключ в JSON находится слева. Ключ нужно помещать в двойные кавычки. В качестве ключа можно использовать любую валидную строку. В рамках одного объекта все ключи должны быть уникальны. Ключ может содержать пробел (“first name”), но при программировании могут возникнуть проблемы с доступом к такому ключу. Потому вместо пробела лучше использовать подчеркивание (“first_name”).
Значения JSON находятся в правой части столбца. В качестве значения можно использовать любой простой тип данных:
- Строки
- Числа
- Объекты
- Массивы
- Логические данные (true или false)
- Ноль
Значения могут быть представлены и сложными типами данных (например, объектами или массивами JSON).
JSON поддерживает индивидуальный синтаксис каждого из перечисленных выше типов данных: если значение представлено строкой, то оно будет взято в кавычки, а если числом, то нет.
Как правило, данные в файлах .json записываются в столбик, однако JSON можно записать и в строку:
Так обычно записываются данные JSON в файлы другого типа.
Записывая данные JSON в столбец, вы повышаете удобочитаемость файла (особенно если данных в файле много). JSON игнорирует пробелы между столбцами, потому с их помощью вы можете разделить данные на удобное для восприятия количество столбцов.
«first_name» : «John»,
«last_name» : «Smith»,
«online» : true
Обратите внимание: объекты JSON очень похожи на объекты JavaScript, но это не один и тот же формат. К примеру, в JavaScript можно использовать функции, а в JSON нельзя.
Главным преимуществом JSON является то, что данные в этом формате поддерживают многие популярные языки программирования, потому их можно быстро передать.
Теперь вы знакомы с базовым синтаксисом JSON. Но файлы JSON могут иметь сложную, иерархическую структуру, включающую в себя вложенные массивы и объекты.
Сложные типы в JSON
JSON может хранить вложенные объекты и массивы, которые будут передаваться в качестве значения присвоенного им ключа.
Вложенные объекты
Ниже вы найдёте пример – файл users.json, в котором содержатся данные о пользователях. Для каждого пользователя
(“john”, “jesse”, “drew”, “jamie”) в качестве значения передаётся вложенный объект, который, в свою очередь, тоже состоит из ключей и значений.
Примечание: Первый вложенный объект JSON выделен красным.
» john» : <
«username» : » John»,
«location» : «London»,
«online» : true,
«followers» : 987
«jesse» : <
«username» : «Jesse»,
«location» : «Washington»,
«online» : false,
«followers» : 432
«drew» : <
«username» : «Drew»,
«location» : «Paris»,
«online» : false,
«followers» : 321
«jamie» : <
«username» : «Jamie»,
«location» : «Berlin»,
«online» : true,
«followers» : 654
Обратите внимание: фигурные скобки используются и во вложенном, и в основном объекте. Запятые во вложенных объектах используются так же, как и в обычных.
Вложенные массивы
Данные можно вкладывать в JSON с помощью массивов JavaScript, которые будут передаваться как значения. В JavaScript в начале и в конце массива используются квадратные скобки ([ ]). Массив – это упорядоченный набор данных, который может содержать данные различных типов.
Массив используют для передачи большого количества данных, которые можно сгруппировать. Для примера попробуем записать данные о пользователе.
<
«first_name» : «John»,
«last_name» : «Smith»,
«location» : «London»,
«websites» : [
«description» : «work»,
«URL» : «https://www.johnsmithsite.com/»
«desciption» : «tutorials»,
«URL» : «https://www.johnsmithsite.com/tutorials»
«description» : «twitter»,
«link» : «https://twitter.com/johnsmith»
«description» : «facebook»,
«link» : «https://www.facebook.com/johnsmith»
«description» : «github»,
«link» : «https://github.com/johnsmith»
Ключам «websites» и «social_media» в качестве значений присвоены массивы, которые помещаются в квадратные скобки.
При помощи вложенных массивов и объектов можно создать сложную иерархию данных.
JSON или XML?
XML (eXtensible Markup Language) позволяет хранить данные в удобном для восприятия человека и машины виде. Формат XML поддерживается большим количеством языков программирования.
У XML и JSON очень много общего. Однако XML требует гораздо больше текста, следовательно, такие файлы объёмнее и их сложнее читать и писать. Более того, XML обрабатывается только с помощью интерпретатора XML, а JSON можно обработать с помощью простой функции. В отличие от JSON, XML не может хранить массивы.
Давайте сравним два файла: они содержат одинаковые данные, но первый написан в формате XML, а второй в JSON.
users.xml
<username> John</username> <location>London</location>
JSON – очень компактный формат, и он не требует такого количества тегов, как XML. Кроме того, XML, в отличие от JSON, не поддерживает массивы.
Если вы знакомы с HTML, вы заметили, что формат XML очень похож на него (в частности тегами). JSON проще, требует меньше текста и его проще использовать, например, в приложениях AJAX.
Конечно, формат нужно выбирать в зависимости от потребностей приложения.
Инструменты для JSON
JSON обычно используется в JavaScript, однако этот формат широко применяется в других языках программирования.
Больше информации о совместимости и обработке JSON можно найти на сайте проекта и в библиотеке jQuery.
Писать JSON с нуля приходится редко. Обычно данные загружаются из исходников или преобразовываются в JSON. Вы можете преобразовать CSV или данные с разделителями табуляцией в JSON с помощью открытого инструмента Mr. Data Converter. Чтобы преобразовать XML в JSON и наоборот, используйте utilities-online.info. При работе с автоматическими инструментами обязательно проверяйте результат.
Файлы JSON (в том числе и преобразованные данные) можно проверить с помощью сервиса JSONLint. Чтобы протестировать JSON в контексте веб-разработки, обратитесь к JSFiddle.
Заключение
JSON – простой и легковесный формат данных. Файлы JSON легко передавать, хранить и использовать.
Сегодня JSON часто используется в API.
Вам нечасто придётся писать файлы JSON самостоятельно: обычно они поставляются из других источников. Потому знать, как использовать JSON в программе важнее, чем уметь писать такие файлы.