Извлечение нескольких значений из ответа JSON с помощью RegEx Extractor - PullRequest
5 голосов
/ 14 ноября 2011

Я тестирую веб-сервис, который возвращает ответы JSON, и я хотел бы извлечь несколько значений из ответа.Типичный ответ будет содержать несколько значений в списке.Например:

{
"name":"@favorites",
"description":"Collection of my favorite places",
"list_id":4894636,
}

Ответ будет содержать много разделов, как в приведенном выше примере.

Что я хотел бы сделать в Jmeter, - это просмотреть ответ JSON и извлечь каждый раздел, описанный выше.таким образом, чтобы я мог связать возвращаемое имя и описание как одну запись для повторения.

Что я смог сделать до сих пор, так это вернуть значение имени с помощью экстрактора регулярных выражений ("name": "(. +?) ") используя шаблон $ 1 $.Я хотел бы вытащить и имя и описание, но не могу заставить его работать.Я пытался использовать регулярное выражение "name": "(. +?)", "Description": "(. +?)" С шаблоном $ 1 $$ 2 $ безуспешно.

Кто-нибудьзнаете, как я могу получить несколько значений с помощью регулярных выражений в этом примере?

Ответы [ 4 ]

3 голосов
/ 14 декабря 2012

Вы можете просто добавить (?s) к регулярному выражению, чтобы избежать разрывов строк.

Например: (?s)"name":"(.+?)","description":"(.+?)"

Это работает для меня в утверждениях.

2 голосов
/ 15 ноября 2011

Возможно, стоит использовать BeanShell-скриптинг для обработки ответа JSON.

Таким образом, если вам нужно получить ВСЕ пары «имя / описание» из ответа (для каждого раздела), вы можете сделать следующее:
1. извлеките все пары «имя / описание» из ответа в цикле;
2. сохранить извлеченные пары в csv-файл в удобном формате;
3. читать сохраненные пары из csv-файла позже в коде - используя CSV Data Set Config в цикле, например,

Обработка ответов JSON может быть реализована с использованием скриптов BeanShell (~ java) + любая библиотека обработки json (например, json-rpc-1.0 ):
- либо в BeanShell Sampler , либо в BeanShell PostProcessor ;
- все необходимые библиотеки beanshell в настоящее время предоставляются по умолчанию поставка метра;
- чтобы использовать библиотеку json-обработки, поместите jar в папку JMETER_HOME / lib.

Схематически это будет выглядеть так:

  1. в случае BeanShell PostProcessor:

    Thread Group
        . . .
        <b>YOUR HTTP Request</b>
            BeanShell PostProcessor    // added as child
        . . .
    
  2. в случае сэмплера BeanShell:

    Thread Group
        . . .
        <b>YOUR HTTP Request</b>
        BeanShell Sampler          // added separate sampler - after your
        . . .
    

В этом случае нет разницы, какой использовать.

bsh-sampler_extract-json-data

Вы можете либо поместить сам код в тело сэмплера (поле «Скрипт»), либо сохранить во внешнем файле, как показано ниже.

Код пробоотборника:

import java.io.*;
import java.util.*;
import org.json.*;
import org.apache.jmeter.samplers.SampleResult;

ArrayList nodeRefs = new ArrayList();
ArrayList fileNames = new ArrayList();

String extractedList = "extracted.csv";
StringBuilder contents = new StringBuilder();

try
{
    if (ctx.getPreviousResult().getResponseDataAsString().equals("")) {
        Failure = true;
        FailureMessage = "ERROR: Response is EMPTY.";
        throw new Exception("ERROR: Response is EMPTY.");
    } else {
        if ((ResponseCode != null) && (ResponseCode.equals("200") == true)) {
            SampleResult result = ctx.getPreviousResult();    
            JSONObject response = new JSONObject(result.getResponseDataAsString());

            FileOutputStream fos = new FileOutputStream(System.getProperty("user.dir") + File.separator + extractedList);

            if (response.has("items")) {
                JSONArray items = response.getJSONArray("items");

                if (items.length() != 0) {
                    for (int i = 0; i < items.length(); i++) {
                        String name = items.getJSONObject(i).getString("name");
                        String description = items.getJSONObject(i).getString("description");
                        int list_id = items.getJSONObject(i).getInt("list_id");

                        if (i != 0) {
                            contents.append("\n");
                        }

                        contents.append(name).append(",").append(description).append(",").append(list_id);
                        System.out.println("\t " + name + "\t\t" + description + "\t\t" + list_id);
                    }
                }                                       
            }

            byte [] buffer = contents.toString().getBytes();    

            fos.write(buffer);
            fos.close();
        } else {
            Failure = true;
            FailureMessage = "Failed to extract from JSON response.";
        }
    }
}
catch (Exception ex) {
    IsSuccess = false;
    log.error(ex.getMessage());
    System.err.println(ex.getMessage());
}
catch (Throwable thex) {
    System.err.println(thex.getMessage());
}

А также набор ссылок на это:


Upd. 08.2017:

На данный момент JMeter имеет набор встроенных компонентов (объединенных из сторонних проектов) для обработки JSON без сценариев:

1 голос
/ 14 ноября 2011

Я предполагаю, что JMeter использует регулярные выражения на основе Java ... Это может означать отсутствие именованных групп захвата.Очевидно, Java7 теперь поддерживает их , но это не обязательно означает, что JMeter будет.Для JSON, который выглядит следующим образом:

{
"name":"@favorites",
"description":"Collection of my favorite places",
"list_id":4894636,
}

{
"name":"@AnotherThing",
"description":"Something to fill space",
"list_id":0048265,
}

{
"name":"@SomethingElse",
"description":"Something else as an example",
"list_id":9283641,
}

... это выражение:

\{\s*"name":"((?:\\"|[^"])*)",\s*"description":"((?:\\"|[^"])*)",(?:\\}|[^}])*}

... должно совпадать 3 раза, сохраняя значение "name" в первой группе захватаи «описание» во вторую группу захвата, аналогичное следующему:

1                 2
---------------   ---------------------------------------
@favorites        Collection of my favorite places
@AnotherThing     Something to fill space
@SomethingElse    Something else as an example

Важно, что это выражение поддерживает экранирование кавычек в части значения (и даже в части имени идентификатора, поэтомучто строка Javascript I said, "What is your name?"! будет сохранена в JSON как AND и правильно проанализирована как I said, \"What is your name?\"!

0 голосов
/ 22 января 2014

Используя Ubik Load Pack плагин для JMeter, который был передан в ядро ​​JMeter и начиная с версии 3.0 доступен как JSON Extractor , вы можете сделать это следующим образом: 1005 *

enter image description here

namesExtractor_ULP_JSON_PostProcessor config:

enter image description here

descriptionExtractor_ULP_JSON_PostProcessor config:

enter image description here

Loop Controller для зацикливания результатов:

enter image description here

Конфигурация счетчика:

enter image description here

Debug Sampler, показывающий, как использовать имя и описание в одной итерации:

enter image description here

А вот что вы получите для следующего JSON:

 [{ "name":"@favorites", "description":"Collection of my favorite places", "list_id": 4894636 }, { "name":"@AnotherThing", "description":"Something to fill space", "list_id": 48265 }, { "name":"@SomethingElse", "description":"Something else as an example", "list_id":9283641 }]

enter image description here

По сравнению с решением Beanshell:

  • Больше "стандартного подхода"

  • Работает намного лучше, чем код Beanshell

  • Это более читабельно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...