Je souhaite utiliser l'API fournie par Apache JMeter pour créer et exécuter des scripts de test à partir d'un programme Java. J'ai compris les bases de ThreadGroup et Samplers. Je peux les créer dans mon Java en utilisant l'API JMeter.
ThreadGroup threadGroup = new ThreadGroup();
LoopController lc = new LoopController();
lc.setLoops(5);
lc.setContinueForever(true);
threadGroup.setSamplerController(lc);
threadGroup.setNumThreads(5);
threadGroup.setRampUp(1);
HTTPSampler sampler = new HTTPSampler();
sampler.setDomain("localhost");
sampler.setPort(8080);
sampler.setPath("/jpetstore/shop/viewCategory.shtml");
sampler.setMethod("GET");
Arguments arg = new Arguments();
arg.addArgument("categoryId", "FISH");
sampler.setArguments(arg);
Cependant, je ne sais pas comment créer un script de test combinant le groupe de threads et l'échantillonneur, puis l'exécuter à partir du même programme. Des idées?
Si je comprends bien, vous souhaitez exécuter un plan de test complet par programme à partir d'un programme Java. Personnellement, je trouve plus facile de créer un fichier .JMX de plan de test et de l'exécuter dans JMeter non Mode GUI :)
Voici un exemple simple Java basé sur le contrôleur et l'échantillonneur utilisé dans la question d'origine.
import org.Apache.jmeter.control.LoopController;
import org.Apache.jmeter.engine.StandardJMeterEngine;
import org.Apache.jmeter.protocol.http.sampler.HTTPSampler;
import org.Apache.jmeter.testelement.TestElement;
import org.Apache.jmeter.testelement.TestPlan;
import org.Apache.jmeter.threads.SetupThreadGroup;
import org.Apache.jmeter.util.JMeterUtils;
import org.Apache.jorphan.collections.HashTree;
public class JMeterTestFromCode {
public static void main(String[] args){
// Engine
StandardJMeterEngine jm = new StandardJMeterEngine();
// jmeter.properties
JMeterUtils.loadJMeterProperties("c:/tmp/jmeter.properties");
HashTree hashTree = new HashTree();
// HTTP Sampler
HTTPSampler httpSampler = new HTTPSampler();
httpSampler.setDomain("www.google.com");
httpSampler.setPort(80);
httpSampler.setPath("/");
httpSampler.setMethod("GET");
// Loop Controller
TestElement loopCtrl = new LoopController();
((LoopController)loopCtrl).setLoops(1);
((LoopController)loopCtrl).addTestElement(httpSampler);
((LoopController)loopCtrl).setFirst(true);
// Thread Group
SetupThreadGroup threadGroup = new SetupThreadGroup();
threadGroup.setNumThreads(1);
threadGroup.setRampUp(1);
threadGroup.setSamplerController((LoopController)loopCtrl);
// Test plan
TestPlan testPlan = new TestPlan("MY TEST PLAN");
hashTree.add("testPlan", testPlan);
hashTree.add("loopCtrl", loopCtrl);
hashTree.add("threadGroup", threadGroup);
hashTree.add("httpSampler", httpSampler);
jm.configure(hashTree);
jm.run();
}
}
Dépendances
Ce sont les JAR mininum nus requis basés sur JMeter 2.9 et le HTTPSampler utilisé. D'autres échantillonneurs auront très probablement des dépendances JAR de bibliothèque différentes.
Remarque
package jMeter;
import Java.io.File;
import Java.io.FileOutputStream;
import org.Apache.jmeter.config.Arguments;
import org.Apache.jmeter.config.gui.ArgumentsPanel;
import org.Apache.jmeter.control.LoopController;
import org.Apache.jmeter.control.gui.LoopControlPanel;
import org.Apache.jmeter.control.gui.TestPlanGui;
import org.Apache.jmeter.engine.StandardJMeterEngine;
import org.Apache.jmeter.protocol.http.control.gui.HttpTestSampleGui;
import org.Apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
import org.Apache.jmeter.reporters.ResultCollector;
import org.Apache.jmeter.reporters.Summariser;
import org.Apache.jmeter.save.SaveService;
import org.Apache.jmeter.testelement.TestElement;
import org.Apache.jmeter.testelement.TestPlan;
import org.Apache.jmeter.threads.ThreadGroup;
import org.Apache.jmeter.threads.gui.ThreadGroupGui;
import org.Apache.jmeter.util.JMeterUtils;
import org.Apache.jorphan.collections.HashTree;
public class JMeterFromScratch {
public static void main(String[] argv) throws Exception {
String jmeterHome1 = "/home/ksahu/Apache-jmeter-2.13";
File jmeterHome=new File(jmeterHome1);
// JMeterUtils.setJMeterHome(jmeterHome);
String slash = System.getProperty("file.separator");
if (jmeterHome.exists()) {
File jmeterProperties = new File(jmeterHome.getPath() + slash + "bin" + slash + "jmeter.properties");
if (jmeterProperties.exists()) {
//JMeter Engine
StandardJMeterEngine jmeter = new StandardJMeterEngine();
//JMeter initialization (properties, log levels, locale, etc)
JMeterUtils.setJMeterHome(jmeterHome.getPath());
JMeterUtils.loadJMeterProperties(jmeterProperties.getPath());
JMeterUtils.initLogging();// you can comment this line out to see extra log messages of i.e. DEBUG level
JMeterUtils.initLocale();
// JMeter Test Plan, basically JOrphan HashTree
HashTree testPlanTree = new HashTree();
// First HTTP Sampler - open example.com
HTTPSamplerProxy examplecomSampler = new HTTPSamplerProxy();
examplecomSampler.setDomain("www.google.com");
examplecomSampler.setPort(80);
examplecomSampler.setPath("/");
examplecomSampler.setMethod("GET");
examplecomSampler.setName("Open example.com");
examplecomSampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
examplecomSampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());
// Second HTTP Sampler - open blazemeter.com
HTTPSamplerProxy blazemetercomSampler = new HTTPSamplerProxy();
blazemetercomSampler.setDomain("www.tripodtech.net");
blazemetercomSampler.setPort(80);
blazemetercomSampler.setPath("/");
blazemetercomSampler.setMethod("GET");
blazemetercomSampler.setName("Open blazemeter.com");
blazemetercomSampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
blazemetercomSampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());
// Loop Controller
LoopController loopController = new LoopController();
loopController.setLoops(1);
loopController.setFirst(true);
loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
loopController.setProperty(TestElement.GUI_CLASS, LoopControlPanel.class.getName());
loopController.initialize();
// Thread Group
ThreadGroup threadGroup = new ThreadGroup();
threadGroup.setName("Example Thread Group");
threadGroup.setNumThreads(1);
threadGroup.setRampUp(1);
threadGroup.setSamplerController(loopController);
threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
threadGroup.setProperty(TestElement.GUI_CLASS, ThreadGroupGui.class.getName());
// Test Plan
TestPlan testPlan = new TestPlan("Create JMeter Script From Java Code");
testPlan.setProperty(TestElement.TEST_CLASS, TestPlan.class.getName());
testPlan.setProperty(TestElement.GUI_CLASS, TestPlanGui.class.getName());
testPlan.setUserDefinedVariables((Arguments) new ArgumentsPanel().createTestElement());
// Construct Test Plan from previously initialized elements
testPlanTree.add(testPlan);
HashTree threadGroupHashTree = testPlanTree.add(testPlan, threadGroup);
threadGroupHashTree.add(blazemetercomSampler);
threadGroupHashTree.add(examplecomSampler);
// save generated test plan to JMeter's .jmx file format
SaveService.saveTree(testPlanTree, new FileOutputStream(jmeterHome + slash + "example.jmx"));
//add Summarizer output to get test progress in stdout like:
// summary = 2 in 1.3s = 1.5/s Avg: 631 Min: 290 Max: 973 Err: 0 (0.00%)
Summariser summer = null;
String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary");
if (summariserName.length() > 0) {
summer = new Summariser(summariserName);
}
// Store execution results into a .jtl file
String logFile = jmeterHome + slash + "example.jtl";
ResultCollector logger = new ResultCollector(summer);
logger.setFilename(logFile);
testPlanTree.add(testPlanTree.getArray()[0], logger);
// Run Test Plan
jmeter.configure(testPlanTree);
jmeter.run();
System.out.println("Test completed. See " + jmeterHome + slash + "example.jtl file for results");
System.out.println("JMeter .jmx script is available at " + jmeterHome + slash + "example.jmx");
System.exit(0);
}
}
System.err.println("jmeter.home property is not set or pointing to incorrect location");
System.exit(1);
}
}
J'ai créé un projet de démonstration de principe simple en utilisant JMeter Java Api avec les dépendances Maven: https://github.com/piotrbo/jmeterpoc
Vous pouvez soit générer le fichier jmx du projet JMeter et l'exécuter à partir de la ligne de commande, soit l'exécuter directement à partir de Java.
C'était un peu délicat car le fichier jmx nécessite l'existence de l'attribut 'guiclass' pour chaque TestElement. Pour exécuter jmx, il suffit d'ajouter guiclass
(même avec une valeur incorrecte). Pour ouvrir dans l'interface graphique JMeter, il faut mettre la valeur correcte pour chaque guiclass
.
Les contrôleurs de flux basés sur des conditions sont un problème beaucoup plus ennuyeux. L'API JMeter ne vous offre pas beaucoup plus que l'interface graphique. Vous devez toujours passer un condition
par exemple dans IfController
comme normal String
. Une chaîne doit contenir du javascript. Vous avez donc Java avec javascript avec par exemple une erreur de syntaxe et vous ne le saurez pas jusqu'à ce que vous exécutiez votre test de performance :
Probablement une meilleure alternative pour rester avec le code et le support de IDE au lieu de l'interface graphique JMeter est d'apprendre un peu Scala un peu et d'utiliser --- (http: // gatling .io /
L'exécution en mode non GUI est beaucoup plus rapide. Avoir fait un projet qui utilise Jmeter en mode backend puis analyse le fichier XML pour afficher les résultats des tests. Jetez un oeil à ce repo- https://github.com/rohitjaryal/RESTApiAutomation.git