29. JMeter のプラグインの書き方

ピーター・リンからの紹介

ユーザーは、JMeter の開発者向けドキュメントが古く、あまり役に立たないと不満を漏らしたことが 1 回ならずあります。開発者が簡単に作業できるように、簡単なステップバイステップのチュートリアルを作成することにしました。このことをマイクに話したとき、彼はチュートリアルで何をカバーすべきかについていくつかのアイデアを持っていました。

チュートリアルに入る前に、Java の経験が数年ある人であっても、プラグインを作成することは必ずしも簡単ではないことをお伝えしておきます。私が最初に作成した JMeter 用の拡張機能は、HTTP アクセス ログを解析し、XML 形式で要求を生成する単純なユーティリティでした。これはスタンドアロンのコマンド ライン ユーティリティであったため、実際にはプラグインではありませんでした。JMeter の最初の本格的なプラグインは、Web サービス サンプラーでした。私は .NET プロジェクトに取り組んでおり、Web サービスのストレス テストを行う必要がありました。.NET Web サービスをテストするための商用ツールのほとんどは、コストがかかりすぎます。不十分なテスト ツールに数百ドル以上、または優れたツールに数千ドル以上を支払うよりも、JMeter 用のプラグインを作成する方が簡単で安価であると判断しました。

自由時間に 2 週間のコーディングを行った後、Apache Soap ドライバーを使用した実用的なプロトタイプを作成しました。私はそれを JMeter に提出し、mike はコミッターになりたいかどうか尋ねてきました。過去に Jakarta JSTL と tomcat にパッチを提供したことがあったので、光栄に思いました。それ以来、アクセスログサンプラー、Tomcat 5 モニター、分布グラフを書いてきました。それ以来、Mike はアクセス ログ サンプラーを大幅に改善し、より便利なものにしました。

マイク・ストーバーからの紹介

JMeter の設計における私の主な目標の 1 つは、JMeter の機能をできるだけ多く拡張するためのプラグインを簡単に作成できるようにすることでした。オープンソースであることの利点の 1 つは、多くの人々がアプリケーションを改善するために彼らの努力を貸してくれる可能性があることです。私は、JMeter 開発者がプラグインを書くことを生きがいにするために、コードの単純さをいくらか犠牲にするという意識的な決定を下しました。

一部の人々は、コードを直接掘り下げて JMeter を改善することに成功しましたが、これを行う方法に関する実際のチュートリアルは不足していました。私はずっと前にそれについてのドキュメントを書こうとしましたが、ほとんどの人はそれが役に立たなかった. うまくいけば、Peter の助けがあれば、この試みはより成功するでしょう。

29.1 JMeterの基本構造

JMeter は、プロトコルと機能別に編成されています。これは、開発者がアプリケーション全体を構築することなく、単一のプロトコル用の新しい jar を構築できるようにするためです。JMeter のビルドの詳細については、チュートリアルの後半で説明します。ほとんどの JMeter 開発者は eclipse を使用しているため、この記事では参照ポイントとして eclipse ディレクトリを使用します。

ルート ディレクトリ - /eclipse/workspace/apache-jmeter/

apache-jmeter 内のフォルダー

置き場
JMeter を起動するための.batおよび.shファイルが含まれています。また、 ApacheJMeter.jarとプロパティ ファイルも含まれています。
ビルド/ドキュメント
ディレクトリには、JMeter ドキュメント ファイルが含まれています
エクストラ
ant 関連の追加ファイル
ライブラリ
JMeter に必要な jar ファイルが含まれています
ライブラリ/拡張
JMeter とプロトコルのコア jar ファイルが含まれています
ソース
各プロトコルとコンポーネントのサブディレクトリが含まれています
src/*/テスト
単体テスト関連ディレクトリ
xdocs
ドキュメント用の XML ファイル。JMeter は XML からドキュメントを生成します。

チュートリアルが進むにつれて、サブディレクトリの説明が提供されます。とりあえず、 srcディレクトリ に注目しましょう。

src 内のフォルダー

bshclient
BeanShell ベースのクライアントのコード
ボルト
Bolt プロトコルのコード
コンポーネント
ビジュアライザー、アサーションなどの非プロトコル固有のコンポーネントが含まれています。
すべてのコア インターフェイスと抽象クラスを含む JMeter のコア コード。
距離
ディストリビューションを作成するスクリプトをビルドします
距離チェック
ディストリビューションのテストに関連するコード。結果のソース/バイナリ アーカイブの内容を更新する場合に探す場所です。
新しい Bean フレームワークの使用方法を示すサンプラーの例
機能
すべてのコンポーネントで使用される標準関数
発生器
すべての要素を含むテスト計画を生成するコード。ディストリビューションのテストに使用
ヨルファン
一般的なユーティリティ関数を提供するユーティリティ クラス
ランチャー
API を介して JMeter を開始および停止するためのコード
ライセンス
JMeters の依存関係で使用されるライセンスに関する情報が含まれています
プロトコル
JMeterがサポートするさまざまなプロトコルが含まれています
リリース
JMeter ディストリビューションのリリースに関連するコード
テストキット
テスト用のユーティリティ コード
テストキット-ワイヤーモック
WireMock でテストするためのユーティリティ コード

プロトコルディレクトリ 内には、プロトコル固有のコンポーネントがあります。

プロトコル 内のフォルダー

ftp
ftp サーバーの負荷テスト用コンポーネント
http
Web サーバーの負荷テスト用のコンポーネント
ジャワ
負荷テスト用のコンポーネント Java コンポーネント
jdbc
JDBC を使用したデータベース サーバーの負荷テスト用コンポーネント
ジャムス
JMS サーバーの負荷テスト用のコンポーネント
ジュニット
JUnit テストを使用した負荷テスト用のコンポーネント
junit-サンプル
JUnit ベースのテスト実装の例
LDAP
LDAP サーバーの負荷テスト用のコンポーネント
郵便物
メールサーバーの負荷テスト用コンポーネント
ネイティブ
負荷テスト OS ネイティブ コマンドのコンポーネント
TCP
TCP サービスの負荷テスト用コンポーネント

原則として、HTTP に関連するすべてのサンプラーはhttpディレクトリに配置されます。このルールの例外は、Tomcat5 モニターです。モニターの機能はストレスまたは機能テストとはわずかに異なるため、別のものです。最終的には再編成される可能性がありますが、現時点では独自のディレクトリにあります。難しさという点では、ビジュアライザーの作成はおそらく作成が難しいプラグインの 1 つです。

29.2 JMeter GUI – TestElement コントラクト

JMeter コンポーネントを作成するときは、注意しなければならない特定の規約があります。JMeter コンポーネントが JMeter 環境で適切に動作する場合の動作方法です。このセクションでは、コンポーネントの GUI 部分が満たさなければならない契約について説明します。

JMeter の GUI コードは、テスト要素コードから厳密に分離されています。したがって、コンポーネントを作成すると、テスト要素用のクラスと、GUI プレゼンテーション用の別のクラスが存在します。GUI プレゼンテーション クラスは、テスト要素への参照に固執してはならないという意味でステートレスです (ただし、これには例外があります)。

GUI 要素は、提供された適切な抽象クラスを拡張する必要があります。

  • AbstractSamplerGui
  • AbstractAssertionGui
  • AbstractConfigGui
  • AbstractControllerGui
  • AbstractPostProcessorGui
  • AbstractPreProcessorGui
  • AbstractVisualizer
  • AbstractTimerGui

これらの抽象クラスは非常に多くの配管作業を提供するため、それらを拡張する必要はなく、代わりにインターフェースを直接実装することはほとんど選択肢になりません。これらのクラスを拡張しないという切実な必要性がある場合は、IRC に参加してください。別の方法であなたを納得させることができます :-)。

適切な GUI クラスを拡張したので、あとは何をすればよいのでしょうか? 次の手順を実行します:

  1. getLabelResource() を実装する
    1. このメソッドは、コンポーネントのタイトル/名前を表すリソースの名前を返す必要があります。リソースは、JMeters のmessages.propertiesファイル (および場合によっては翻訳も) に入力する必要があります。
  2. GUI を作成します。好きなスタイルで、GUI をレイアウトします。クラスは最終的にJPanelを拡張 するため、レイアウトはクラス独自のContentPaneにある必要があります。アクションやイベントを介して GUI 要素をTestElementクラスに接続しないでください。可能な限り、swing の内部モデルがすべてのデータに依存するようにします。
    1. すべての JMeter GUI コンポーネントにいくつかの標準的な GUI を追加する必要があります。
      1. クラスのsetBorder(makeBorder())を呼び出します。これにより、標準の JMeter 境界線が表示されます
      2. makeTitlePanel()でタイトル ペインを追加します。通常、これは GUI に最初に追加されるものであり、Box の垂直レイアウト スキームで、または JMeter のVerticalLayout クラスを使用して実行する必要があります。init()メソッド の例を次に示します。
        プライベートボイドinit() {
            setLayout(新しい BorderLayout());
            setBorder(makeBorder());
            ボックス ボックス = Box.createVerticalBox();
            box.add(makeTitlePanel());
            box.add(makeSourcePanel());
            追加 (ボックス、BorderLayout.NORTH);
            add(makeParameterPanel(),BorderLayout.CENTER);
        }
        
  3. public void configure(TestElement el) を実装する
    1. 必ずsuper.configure(e)を呼び出してください。これにより、要素の名前など、一部のデータが入力されます。
    2. このメソッドを使用して、データを GUI 要素に設定します。例:
      public void configure(TestElement el) {
          super.configure(el);
          useHeaders.setSelected(
                  el.getPropertyAsBoolean(RegexExtractor.USEHEADERS));
          useBody.setSelected(
                  !el.getPropertyAsBoolean(RegexExtractor.USEHEADERS));
          regexField.setText(
                  el.getPropertyAsString(RegexExtractor.REGEX));
          templateField.setText(
                  el.getPropertyAsString(RegexExtractor.TEMPLATE));
          defaultField.setText(
                  el.getPropertyAsString(RegexExtractor.DEFAULT));
          matchNumberField.setText(
                  el.getPropertyAsString(RegexExtractor.MATCH_NUM));
          refNameField.setText(
                  el.getPropertyAsString(RegexExtractor.REFNAME));
      }
      
    3. public void modifyTestElement(TestElement e) を実装します。これは、GUI 要素からTestElementにデータを移動する場所です。これは、前の方法の論理的な逆です。
      1. super.configureTestElement(e)を呼び出します。これにより、いくつかのデフォルト データが処理されます。
      2. 例:
        public void modifyTestElement(TestElement e) {
            super.configureTestElement(e);
            e.setProperty(新しい BooleanProperty(
                    RegexExtractor.USEHEADERS、
                    useHeaders.isSelected()));
            e.setProperty(RegexExtractor.MATCH_NUMBER,
                    matchNumberField.getText());
            if (e instanceof RegexExtractor) {
                RegexExtractor 正規表現 = (RegexExtractor)e;
                regex.setRefName(refNameField.getText());
                regex.setRegex(regexField.getText());
                regex.setTemplate(templateField.getText());
                regex.setDefaultValue(defaultField.getText());
            }
        }
        
    4. public TestElement createTestElement()を実装します。このメソッドは、TestElementクラスの新しいインスタンスを作成し、上で作成したmodifyTestElement(TestElement) メソッドに渡します。
      public TestElement createTestElement() {
          RegexExtractor エクストラクタ = new RegexExtractor();
          modifyTestElement(エクストラクタ);
          抽出器を返します。
      }
      

テスト要素の参照を保持できない理由は、JMeter が複数のテスト要素に対して GUI クラス オブジェクトのインスタンスを再利用するためです。これにより、多くのメモリが節約されます。また、新しいコンポーネントの GUI 部分を非常に簡単に作成できます。Swing のレイアウトにはまだ苦労する必要がありますが、GUI 要素からTestElementにデータを取得するための適切なイベントとアクションを作成することについて心配する必要はありません。JMeter は、configure およびmodifyTestElementメソッドを呼び出すタイミングを認識しており、非常に簡単な方法で実行できます。

ただし、ビジュアライザーの作成はやや特殊なケースです。

29.3 ビジュアライザーの作成

GUI モードでの負荷テストは悪い習慣です。そのようなプラグインを開発するべきではありません。次のような最新のコンポーネントをご覧ください。

コンポーネントの種類のうち、ビジュアライザーは、コントローラー、関数、サンプラーなどよりも Swing でより深くする必要があります。分布グラフの完全なソースは components/org/apache/jmeter/visualizers/にあります。分布グラフ ビジュアライザーは 2 つのクラスに分けられます。

DistributionGraphVisualizer
JMeter がインスタンス化するビジュアライザ
分布グラフ
実際のグラフを描画する JComponent

ビジュアライザーを作成する最も簡単な方法は、次のようにすることです。

  1. org.apache.jmeter.visualizers.gui.AbstractVisualizerを拡張する
  2. コールバックとイベント通知に必要な追加のインターフェイスを実装します。たとえば、DistributionGraphVisualizerは次のインターフェイスを実装します。
    • イメージビジュアライザー
    • ItemListener – クラスのコメントによると、 ItemListenerは古く、使用されていません。
    • グラフリスナー
    • クリア可能

AbstractVisualizerは、 Graph Resultsなどのほとんどのビジュアライザーが 使用するいくつかの一般的な機能を提供します。抽象クラスによって提供される一般的な機能には、次のものがあります。

  • テスト要素を構成する – これは、新しいResultCollectorを作成し、ファイルを設定し、エラー ログを設定することを意味します
  • ストックメニューを作る
  • 変更が行われたときにテスト要素を更新する
  • ログ ファイルのファイル パネルを作成する
  • タイトル パネルを作成する

場合によっては、ファイル テキスト ボックスのメニューを表示したくない場合があります。その場合、init()メソッドをオーバーライドできます。これがDistributionGraphVisualizerの実装です。

/**
 * GUI を初期化します。
 */
プライベートボイドinit() {
    this.setLayout(新しい BorderLayout());

    // メインパネル
    ボーダーマージン = new EmptyBorder(10, 10, 5, 10);
    this.setBorder(マージン);

    // ヘッダー、フッター、Y 軸、グラフ表示でグラフを設定します
    JPanel graphPanel = new JPanel(new BorderLayout());
    graphPanel.add(createGraphPanel(), BorderLayout.CENTER);
    graphPanel.add(createGraphInfoPanel(), BorderLayout.SOUTH);

    // メインパネルとグラフを追加
    this.add(makeTitlePanel(), BorderLayout.NORTH);
    this.add(graphPanel, BorderLayout.CENTER);
}

initメソッドが 最初に行うことは、新しいBorderLayoutを作成することです。ウィジェットをどのようにレイアウトするかによって、別のレイアウト マネージャーを使用したい場合があります。さまざまなレイアウト マネージャーを使用するのは専門家向けです。

initメソッドが行う 2 番目のことは、境界線を作成することです。境界線を増減する場合は、4 つの整数値を変更します。各整数値はピクセルを表します。ビジュアライザーに境界線を付けないようにする場合は、8 行目と 9 行目をスキップします。13 行目では、 DistributionGraphの構成とビジュアライザーへの 追加を担当するcreateGraphPanelを呼び出します。

プライベート コンポーネント createGraphPanel() {
    graphPanel = new JPanel();
    graphPanel.setBorder(BorderFactory.createBevelBorder(
    BevelBorder.LOWERED,Color.lightGray,Color.darkGray));
    graphPanel.add(グラフ);
    graphPanel.setBackground(Color.white);
    グラフパネルを返します。
}

5 行目で、グラフ コンポーネントがグラフ パネルに追加されます。コンストラクターは、 DistributionGraphの新しいインスタンスが作成される場所です。

public DistributionGraphVisualizer() {
    モデル = 新しい SamplingStatCalculator("分布");
    グラフ = 新しい DistributionGraph(モデル);
    graph.setBackground(Color.white);
    初期化();
}

DistributionGraphVisualizer のコンストラクターは、モデルとグラフの作成を担当します。新しい結果が完成するたびに、エンジンはadd(SampleResult res)を呼び出してすべてのリスナーに結果を渡します。ビジュアライザーは新しいSampleResultをモデルに渡します。

パブリック同期ボイド追加(SampleResult res){
    model.addSample(res);
    updateGui(model.getCurrentSample());
}

DistributionGraphVisualizer の場合、addメソッドは実際にはグラフを更新しません。代わりに、 3 行目でupdateGuiを呼び出します。

パブリック同期ボイド updateGui(サンプル s) {
    // サンプルをもう 1 つ受け取りました
    if (遅延 == カウンター) {
        updateGui();
        カウンター = 0;
    } そうしないと {
        カウンター++;
    }
}

GraphVisualizer とは異なり、分布グラフは結果がどのようにまとまるかを示そうとします。したがって、DistributionGraphVisualizerは更新を遅らせます。デフォルトの遅延は10サンプル結果です。

パブリック同期ボイド updateGui() {
    if (graph.getWidth() < 10) {
        graph.setPreferredSize(
                新しいディメンション (getWidth() - 40,
                getHeight() - 160));
    }
    graphPanel.updateUI();
    グラフ.再描画();
}

2 行目から 3 行目は、ユーザーがウィンドウのサイズを変更するか、仕切りをドラッグした場合に、グラフのサイズを変更することを想定しています。行 7 は、グラフを含むパネルを更新します。8 行目はDistributionGraphの更新をトリガーします。グラフの作成について説明する前に、ビジュアライザーで実装する必要がある重要なメソッドがいくつかあります。

public String getLabelResource() {
    return "distribution_graph_title";
}

ラベル リソースは、ビジュアライザーの名前をプロパティ ファイルから取得します。ファイルはcore/org/apache/jmeter/resourcesにあります。ビジュアライザーの名前をハードコーディングしないことをお勧めします。 Message.propertiesファイルはアルファベット順に編成されているため、新しいエントリを簡単に追加できます。

パブリック同期ボイドクリア(){
    this.graph.clear();
    model.clear();
    再描画();
}

JMeter のすべてのコンポーネントは、clear()メソッドのロジックを実装する必要があります。これを行わないと、ユーザーが最後の結果をクリアして新しいテストを実行しようとしても、コンポーネントは UI またはモデルをクリアしません。clear が実装されていない場合、メモリ リークが発生する可能性があります。

public JComponent getPrintableComponent() {
    this.graphPanel を返します。
}

ビジュアライザーが実装する最後のメソッドはgetPrintableComponent()です。このメソッドは、保存または印刷できる JComponent を返す役割を果たします。この機能は最近追加され、ユーザーが特定のビジュアライザーのスクリーン キャプチャを保存できるようになりました。

29.4 グラフリスナー

GUI モードでの負荷テストは悪い習慣です。そのようなプラグインを開発するべきではありません。次のような最新のコンポーネントをご覧ください。

ビジュアライザーはGraphListenerを実装する必要があります。これは、新しい Sample インスタンスをリスナーに簡単に追加できるようにするために行われます。原則として、カスタム グラフがすべてのサンプルをプロットしない場合、インターフェイスを実装する必要はありません。

パブリック インターフェイス GraphListener {
    public void updateGui(Sample s);
    public void updateGui();
}

インターフェイスで重要なメソッドはupdateGui(Sample s)です。DistributionGraphVisualizerから 、 graph.repaint()を呼び出し てグラフを更新していることがわかります。ほとんどの場合、updateGui(Sample s)の実装はまさにそれを行う必要があります。 通常、 ItemListenerVisualizersはこのインターフェースを実装する必要はありません。インターフェイスは、コンボ ボックス、チェックボックス、およびリストで使用されます。ビジュアライザーがこれらのいずれかを使用していて、いつ更新されたかを知る必要がある場合、ビジュアライザーはインターフェースを実装する必要があります。インターフェイスの実装方法の例については、GraphVisualizerを参照してください。

29.5 カスタムグラフを書く

GUI モードでの負荷テストは悪い習慣です。そのようなプラグインを開発するべきではありません。次のような最新のコンポーネントをご覧ください。

Swing を初めて使用し、カスタム JComponents をまだ作成していない人には、Swing に関する本を入手して、Swing ウィジェットがどのように機能するかを理解することをお勧めします。このチュートリアルでは、基本的な Swing の概念については説明しません。また、読者が Swing API と MVC (モデル ビュー コントローラー) の設計パターンに既に精通していることを前提としています。DistributionGraphVisualizerのコンストラクターから、モデルのインスタンスを使用してDistributionGraphの新しいインスタンスが作成されていることがわかります。

public DistributionGraph(SamplingStatCalculator モデル) {
    これ();
    setModel(モデル);
}

setModelメソッド の実装は簡単です。

private void setModel(オブジェクト モデル) {
    this.model = (SamplingStatCalculator) モデル;
    再描画();
}

モデルを設定した後、メソッドがrepaintを 呼び出すことに注意してください。repaintが呼び出されない場合、GUI がグラフを描画しない可能性があります。テストが開始されると、グラフが再描画されるため、repaintの呼び出しは重要ではありません。

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    最終的な SamplingStatCalculator m = this.model;
    同期 (m) {
        drawSample(メートル、グラム);
    }
}

ウィジェットを更新する際のもう 1 つの重要な側面は、drawSampleへの呼び出しを同期ブロック内に配置することです。drawSampleが同期されていない場合、JMeter は実行時にConcurrentModificationExceptionをスロー します。テスト計画によっては、結果をモデルに追加するスレッドが 10 以上ある場合があります。同期ブロックは、個々のリクエストと時間測定の精度には影響しませんが、大きな負荷を生成する JMeter の機能には影響します。テスト計画のスレッド数が増えると、新しいリクエストを開始する前に、グラフの再描画が完了するまでスレッドが待機する必要がある可能性が高くなります。これがdrawSampleの実装です。

private void drawSample(SamplingStatCalculator モデル、グラフィック g) {
    幅 = getWidth();
    double height = (double)getHeight() - 1.0;

    // 最初にグリッドを描画します
    for (int y=0; y < 4; y++){
        int q1 = (int)(高さ - (高さ * 0.25 * y));
        g.setColor(Color.lightGray);
        g.drawLine(xborder,q1,width,q1);
        g.setColor(Color.black);
        g.drawString(String.valueOf((25 * y) + "%"),0,q1);
    }
    g.setColor(Color.black);
    // X 軸を描く
    g.drawLine(xborder,(int)height,width,(int)height);
    // Y 軸を描く
    g.drawLine(xborder,0,xborder,(int)height);
    // テスト計画には 200 を超えるサンプルが必要です
    // 中途半端な分布を生成するため
    // グラフ。サンプルが大きいほど、
    // 結果。
    if (モデル != null && model.getCount() > 50) {
        // ここで棒グラフを描画します
        90 番 = model.getPercentPoint(0.90);
        50 番 = model.getPercentPoint(0.50);
        合計 = model.getCount();
        コレクションの値 = model.getDistribution().values();
        オブジェクト[] objval = 新しいオブジェクト[値.サイズ()];
        objval = values.toArray(objval);
        // オブジェクトをソートします
        Arrays.sort(objval,new NumberComparator());
        int len = objval.length;
        for (int count=0; count < len; count++) {
            // 高さを計算する
            Number[] num = (Number[])objval[カウント];
            double iper = (double)num[1].intValue() / (double)total;
            double iheight = 高さ * iper;
            // 高さが 1 未満の場合は設定します
            // 1 ピクセルに
            if (高さ < 1) {
                高さ = 1.0;
            }
            int ix = (カウント * 4) + xborder + 5;
            int dheight = (int)(高さ - iheight);
            g.setColor(Color.blue);
            g.drawLine(ix -1,(int)height,ix -1,dheight);
            g.drawLine(ix,(int)height,ix,dheight);
            g.setColor(Color.black);
            // 90% ポイントに赤い線を引く
            if (num[0].longValue() == ninety.longValue()) {
                g.setColor(Color.red);
                g.drawLine(ix,(int)height,ix,55);
                g.drawLine(ix,(int)35,ix,0);
                g.drawString("90%",ix - 30,20);
                g.drawString(
                        String.valueOf(num[0].longValue()),
                        ix + 8, 20);
            }
            // 50% ポイントのオレンジ色の線を引きます
            if (num[0].longValue() == 50.longValue()) {
                g.setColor(Color.orange);
                g.drawLine(ix,(int)height,ix,30);
                g.drawString("50%",ix - 30,50);
                g.drawString(
                        String.valueOf(num[0].longValue()),
                        ix + 8, 50);
            }
        }
    }
}

一般に、グラフのレンダリングはかなり高速で、ボトルネックになることはありません。原則として、カスタム プラグインをプロファイリングすることをお勧めします。ビジュアライザーがボトルネックにならないようにする唯一の方法は、Borland OptimizeIt などのツールを使用して実行することです。プラグインをテストする良い方法は、簡単なテスト計画を作成して実行することです。ヒープとガベージ コレクションの動作は、規則的で予測可能でなければなりません。

29.6 JMeter 用の TestBean プラグインの作成

このパートでは、新しいTestBeanフレームワークを使用する JMeter 用の単純なコンポーネントを作成するプロセスについて説明します。

このコンポーネントは、ユーザーが CSV ファイルを使用して入力データを簡単に変更できるようにする CSV ファイル読み取り要素になります。このチュートリアルを最も効果的に使用するには、以下に示す 3 つのファイルを開きます (JMeter のsrc/componentsディレクトリにあります)。

  1. パッケージを選択し、3 つのファイルを作成します。
    • [コンポーネント名].java (org.apache.jmeter.config.CSVDataSet.java)
    • [コンポーネント名]BeanInfo.java (org.apache.jmeter.config.CSVDataSetBeanInfo.java)
    • [ComponentName]Resources.properties (org.apache.jmeter.config.CSVDataSetResources.properties)
  2. CSVDataSet.javaはTestBeanインターフェースを実装する必要があります。さらに、 ConfigTestElement を拡張 し、 LoopIterationListenerを実装します
    • TestBeanはマーカー インターフェースであるため、実装するメソッドはありません。
    • ConfigTestElementを拡張すると、コンポーネントがテスト計画のConfig要素になります。さまざまな抽象クラスを拡張することで、コンポーネントの要素のタイプ (つまり、 AbstractSamplerAbstractVisualizerGenericControllerなど) を制御できますが、適切なインターフェイスをインスタンス化するだけでさまざまなタイプの要素を作成することもできますが、抽象クラスはあなたの人生を変えることができますより簡単に)。
  3. CSVDataSetBeanInfo.javaはorg.apache.jmeter.testbeans.BeanInfoSupportを拡張する必要があります
    • super(CSVDataSet.class)を呼び出すゼロ パラメーター コンストラクターを作成します。
    • これに戻ります。
  4. CSVDataSetResources.properties - 今のところ空白
  5. プラグイン クラスの特別なロジックを実装します。
    1. CSVDataSetは単一の CSV ファイルを読み取り、検出した値を JMeter の実行中のコンテキストに格納します。ユーザーはファイルを定義し、各「」の変数名を定義します。CSVDataSetは、テストの開始時にファイルを開き、テストの終了時にファイルを閉じます (したがって、 TestListener を実装します)。CSVDataSetは、ファイル内の新しい行を読み取ることによって、すべてのテスト スレッドの変数の内容を更新し、親コントローラーを介した反復ごとに変数の内容を更新します。ファイルの最後に到達したら、最初からやり直します。TestBeanを実装する場合、あなたのプロパティに細心の注意を払ってください。これらのプロパティは、ユーザーがCSVDataSet要素を構成するための GUI フォームの基礎になります。
    2. テストが開始されると、要素は JMeter によって複製されます。各スレッドは独自のインスタンスを取得します。ただし、必要に応じて、クローン作成の方法を制御する機会があります。
    3. プロパティ: filenamevariableNames。パブリックのゲッターとセッターを使用。
      • filenameは一目瞭然です。読み取る CSV ファイルの名前が保持されます。
      • variableNamesは、値を割り当てる変数の名前をユーザーが入力できるようにする文字列です。なぜストリング?なぜコレクションではないのですか?確かに、ユーザーは複数の (そして未知の数の) 変数名を入力する必要がありますか? 確かにそうですが、リストまたはコレクションを使用した場合、コレクションを処理するために GUI コンポーネントを作成する必要があります。代わりに、ユーザーが変数名のコンマ区切りリストを入力できるようにします。
    4. 次に、 LoopIterationListenerインターフェイスのIterationStartメソッドを実装しました。この「イベント」のポイントは、テストが親コントローラーに入ったときにコンポーネントに通知されることです。この目的のために、 CSVDataSetの親コントローラーが入力されるたびに、データ ファイルの新しい行を読み取り、変数を設定します。したがって、通常のコントローラーの場合、テストをループするたびに、新しい値のセットが読み取られます。ループ コントローラーの場合、各反復は同様に行われます。すべてのテスト スレッドも異なる値を取得します。
  6. CSVDataSetBeanInfoで GUI 要素を設定します。
    • コンポーネントのプロパティのグループ化を作成できます。作成する各グループには、そのグループに含めるラベルとプロパティ名のリストが必要です。すなわち:
      createPropertyGroup("csv_data",
              new String[] { "ファイル名", "変数名" });
      
    • CSVDataSetのfilenameおよびvariableNamesプロパティのGUI 入力要素を含む csv_dataというグループを作成します。次に、これらをどのようなプロパティにするかを定義する必要があります。
      p = プロパティ ("ファイル名");
      p.setValue(NOT_UNDEFINED, Boolean.TRUE);
      p.setValue(DEFAULT, "");
      p.setValue(NOT_EXPRESSION, Boolean.TRUE);
      
      p = プロパティ ("変数名");
      p.setValue(NOT_UNDEFINED, Boolean.TRUE);
      p.setValue(DEFAULT, "");
      p.setValue(NOT_EXPRESSION, Boolean.TRUE);
      
      これにより、基本的に、値をnullにすることはできず、デフォルト値が"" である 2 つのプロパティが作成されます。各プロパティに設定できる属性がいくつかあります。ここに要約があります:
      NOT_UNDEFINED
      プロパティはnullのままにはなりません。
      デフォルト
      NOT_UNDEFINEDtrue の場合、デフォルト値を指定する必要があります。
      NOT_EXPRESSION
      これがtrue の場合、関数の値は解析されません。
      NOT_OTHER
      これは自由形式の入力フィールドではありません。値のリストを指定する必要があります。
      タグ
      String[]を値として使用すると、許容値の定義済みリストが設定され、JMeter はドロップダウン選択を作成します。
      さらに、プロパティに対してカスタム プロパティ エディタを指定できます。
      p.setPropertyEditorClass(FileEditor.class);
      
      これにより、テキスト入力と、ファイルを検索するためのダイアログを開く参照ボタンが作成されます。通常、現在のように複雑なプロパティ設定は必要ありません。より複雑な例については、org.apache.jmeter.protocol.http.sampler.AccessLogSamplerBeanInfoを参照してください。
  7. リソース文字列を定義します。CSVDataSetResources.properties では、すべての文字列リソースを定義する必要があります。翻訳を提供するには、 CSVDataSetResources_ja.propertiesCSVDataSetResources_de.propertiesなどの追加ファイルを作成します。このコンポーネントでは、次のリソースを定義する必要があります。
    表示名
    これにより、メニューに表示される要素の名前が提供されます。
    csv_data.displayName
    csv_dataと呼ばれるプロパティのグループ化を作成するため、グループ化のラベルを提供する必要があります
    ファイル名.表示名
    ファイル名入力要素のラベル。
    filename.shortDescription
    ツールチップのようなヘルプ テキストの宣伝文。
    variableNames.displayName
    変数名入力要素のラベル。
    variableNames.shortDescription
    variableNames入力要素のツール ヒント。
  8. コンポーネントをデバッグします。

29.6 JMeter の構築

JMeter は Gradle を使用してディストリビューションをコンパイルおよびビルドします。JMeter にはいくつかのタスクが定義されているため、開発者は完全なプロジェクトを簡単に構築できます。Gradle に慣れていない方のために説明すると、これは Unix の make に似たビルド ツールです。簡単な説明を含む Gradle タスクのリストは、ルート ソース ディレクトリにある gradle.mdで提供されます。

コマンドの例をいくつか示します。

./gradlew runGui
JMeter GUI をビルドして起動する
./gradlew createDist
プロジェクトをビルドし、関連する jar ファイルを./libフォルダーにコピーします
./gradlew :src:dist:previewSite
./build/docs/siteにサイトのプレビューを作成します
Go to top