Статьи

Реализация пользовательской функции JMeter

JMeter предоставляет функции, которые можно использовать в сэмплере. При написании сложного плана тестирования вы чувствуете, что в JMeter отсутствуют некоторые методы. Вы используете скрипт Beanshell, чтобы определить свой собственный метод. JMeter вызывает интерпретатор Beanshell для запуска сценария сценария. Это прекрасно работает, если вы не генерируете высокую нагрузку (большое количество потоков). Но как только JMeter пытается генерировать высокую нагрузку, он исчерпывает ресурсы и резко замедляется. Если вместо этого используются пользовательские функции JMeter, то JMeter может генерировать высокую нагрузку без особых усилий. Единственная проблема — выяснить требования к реализации и как интегрироваться с JMeter. Вряд ли есть документ, предоставленный JMeter о реализации пользовательских функций. Но, просмотрев исходный код JMeter и Googling, я нашел способ реализовать пользовательскую функцию JMeter.

Реализация пользовательского метода

Давайте погрузимся в детали реализации. Есть определенные требования, которые должны быть выполнены. Это следующие.

  • Имя пакета класса функции должно содержать «.functions».
  • Класс функции должен расширять AbstractFunction и реализовывать методы execute (), setParameters (), getReferenceKey () и getArgumentDesc ()
  • Создайте файл jar, поместите его в каталог <JMETER_HOME> / lib / ext и перезапустите JMeter.

Имя пакета

JMeter разработан таким образом, что он может работать без графического интерфейса пользователя (Grapical User Interface). Он загружает основные классы и выполняет план тестирования. Он обеспечивает высокий приоритет основным классам и предпочитает сначала загружать эти классы. Чтобы убедиться, что GUI и ядро ​​/ бэкэнд не смешаны, он разделяет классы на основе имени пакета. Он пытается следовать соглашению о том, что класс implmentation функции должен присутствовать в пакете, который должен содержать слово ‘functions’ в нем, например com.code4reference.jmeter.functions . Под капотом он смотрит в файл jmeter.properties и пытается найти следующие значения свойств.

1
classfinder.functions.contain=.functions.

Как видите, значение по умолчанию — ".functions." , вы можете изменить это на что-то другое, но вы должны убедиться, что то же слово должно существовать в имени пакета пользовательского класса функций. Желательно сохранить значение по умолчанию. Как только вы определили пакет, пришло время написать класс реализации Function.

Класс реализации функции

При написании этого класса вы должны реализовать следующие методы.

  1. String getReferenceKey (): имя функции, которую можно вызвать из сэмплера. Соглашение состоит в том, чтобы поставить два «__» (подчеркивание) перед именем функции, например __TimeInMillis и имя функции должны совпадать с именем класса, который реализовал эту функцию. Это имя функции должно храниться в некоторой статической конечной строковой переменной, чтобы ее нельзя было изменить во время выполнения.
  2. List getArgumentDesc (): этот метод в основном возвращает описание аргумента в списке строк. Это описание появляется в функции помощника (показано на рисунке ниже)
  3. void setParameters (Collection parameters): этот метод вызывается JMeter и передает значения, переданные в вызове функции. Переменные передаются как коллекция CompoundVariable. Этот метод вызывается даже без аргумента. В этом методе глобальная переменная может быть установлена ​​и доступна в методе execute ().
  4. String execute (SampleResult previousResult, Sampler currentSampler): JMeter передает предыдущий SampleResult и текущий SampleResult. Этот метод возвращает строку, которая используется в качестве значения замены для вызова функции. Этот метод вызывается несколькими потоками, поэтому он должен быть потокобезопасным. Странная вещь в этом методе состоит в том, что после обработки аргументов результат должен быть преобразован в строку и возвращен

JMeter функция помощник

Исходный код

В приведенном ниже примере исходного кода я реализовал одну функцию с именем __TimeInMillis . Этот метод возвращает время в миллисекундах после корректировки текущего времени с предоставленным смещением. Например, этот вызов метода $ {__ TimeInMillis (2000)} возвращает 1371413879000, когда текущее время равно 1371413877000.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package com.code4reference.jmeter.functions;
 
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Calendar;
 
import org.apache.jmeter.engine.util.CompoundVariable;
import org.apache.jmeter.functions.AbstractFunction;
import org.apache.jmeter.functions.InvalidVariableException;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.samplers.Sampler;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;
 
public class TimeInMillis extends AbstractFunction {
 
    private static final List<String> desc = new LinkedList<String>();
    private static final String KEY = "__TimeInMillis";
    private static final int MAX_PARAM_COUNT = 1;
    private static final int MIN_PARAM_COUNT = 0;
    private static final Logger log = LoggingManager.getLoggerForClass();
    private Object[] values;
 
    static {
        desc.add("(Optional)Pass the milliseconds that should be added/subtracted from current time.");
    }
 
    /**
     * No-arg constructor.
     */
    public TimeInMillis() {
        super();
    }
 
    /** {@inheritDoc} */
    @Override
    public synchronized String execute(SampleResult previousResult, Sampler currentSampler)
            throws InvalidVariableException {
        //JMeterVariables vars = getVariables();
        Calendar cal = Calendar.getInstance();
 
        if (values.length == 1 ) { //If user has provided offset value then adjust the time.
            log.info("Got one paramenter");
            try {
                Integer offsetTime =  new Integer(((CompoundVariable) values[0]).execute().trim());
                cal.add(Calendar.MILLISECOND, offsetTime);
            } catch (Exception e) { //In case user pass invalid parameter.
                throw new InvalidVariableException(e);
            }          
        }
 
        return String.valueOf(cal.getTimeInMillis());
    }
 
    /** {@inheritDoc} */
    @Override
    public synchronized void setParameters(Collection<CompoundVariable> parameters) throws InvalidVariableException {
        checkParameterCount(parameters, MIN_PARAM_COUNT, MAX_PARAM_COUNT);
        values = parameters.toArray();
    }
 
    /** {@inheritDoc} */
    @Override
    public String getReferenceKey() {
        return KEY;
    }
 
    /** {@inheritDoc} */
    @Override
    public List<String> getArgumentDesc() {
        return desc;
    }
}

Я выделил некоторые важные части кода. В строке 19 задается имя функции, где, как в строке 26, приводится описание функции. В строке 60 проверяется количество аргументов и проверяется правильность количества аргументов. Основная часть кода выделяется между 44 и 51, где текущее время корректируется и возвращается как строковый объект. Если вы заинтересованы в проверке реализации других функций, извлеките весь исходный код, представленный в github / Code4Reference . Как только код написан, скомпилируйте его, создайте файл jar и поместите его в каталог <JMETER_HOME> / lib / ext. Вы можете получить образец скрипта Gradle для создания файла jar в этом посте . Если вы не знаете о Gradle, то вы можете использовать команды для создания файла JAR . Самый простой способ создания файла JAR — экспортировать пакет в Eclipse и выбрать место экспорта в качестве файла JAR.

Справка: реализация пользовательской функции JMeter от нашего партнера по JCG Ракеша Кусата в блоге Code4Reference .