2017-06-03 7 views
1

Unten ist ein Skript, das mir hilft, einen extendreport für jmeter zu erstellen. Es ist ein JSR223-Postprozessor-Element. Es funktioniert aber gut, das Problem ist, dass ich es nach jeder HTTP-Anfrage im Skript dupliziert habe. Ich habe mehrere Skripte mit 100 von HTTP-Anfragen, die im Wesentlichen eine Kopie des gleichen PostProcessor-Groovy-Skripts benötigen würden. Das ist schwer zu pflegen!jmeter - wie man ein grooviges Skript einfacher für extendreports macht

Ich habe versucht, gemeinsame Teile in ein externes groovy Skript zu teilen, das ich versuchte, den JSR223 PostProcessor anzurufen. Ich habe auch versucht, die Bits des Skripts zu zerlegen und die Werte in einen csv zu setzen, so dass ich nur die csv-Werte aktualisieren konnte, wenn sich etwas änderte.

Ich bin mir sicher, es gibt eine sauberere/bessere Möglichkeit, dies zu tun, aber ich lerne immer noch, so bin ich mir nicht sicher über die beste Möglichkeit, dies zu erleichtern. Hier ist der JSR223 PostProcessor. Das einzige Bit, die mit jeder HTTP-Anforderung ändert, ist das „// Tester“ Abschnitt

import com.relevantcodes.extentreports.ExtentReports; 
import com.relevantcodes.extentreports.ExtentTest; 
import com.relevantcodes.extentreports.LogStatus; 

import java.io.File; 
import java.io.IOException; 
import java.util.HashMap; 
import java.util.Map; 
import java.util.Properties; 

//configure object for response data 
def response = prev.getResponseDataAsString();  

//configure extentreports objects 
ExtentReports report; 
ExtentTest testLogger; 

//set location for file and report config 
String resultsPath = "C:/portalQA/Automation/Results/"; 
String configPath = "C:/portalQA/Automation/JMeter/TestReportConfig/"; 
String reportPath = 
resultsPath+"Login_Results_${reportDate}_${currentTime}_${testenv}.html"; 

File file = new File(reportPath); 

if (!file.exists()) { 

    //if file does not exist, create it 
    report = new ExtentReports(reportPath, true); 
    report.loadConfig(new File(configPath+"extent-config.xml")); 
} else { 
    //else append to existing report 
    report = new ExtentReports(reportPath, false); 
    report.loadConfig(new File(configPath+"extent-config.xml")); 
} 

//test result 

testLogger = report.startTest("Authenticate"); 
testLogger.assignCategory("Initialize Session"); 
if (response.contains("com.blah.portal.model.User")) { 
    testLogger.log(LogStatus.PASS, "Logged in with: ${username}"); 
    testLogger.log(LogStatus.INFO, response); 
} else { 
    testLogger.log(LogStatus.FAIL, "Could not authenticate session"); 
    testLogger.log(LogStatus.INFO, response); 
} 

log.info("Authenticate"); 
print("Authenticate print");    

report.endTest(testLogger); 
report.flush(); 

Antwort

0

Ich sehe zwei Möglichkeiten:

  • ich JSR223 Listener stattdessen schlage vor, mit. Erstens haben Sie nur einen Listener in Ihrem Skript, der Ihr ursprüngliches Problem löst, aber es ist eine bessere Option für das Schreiben in eine Datei im Allgemeinen, da der Listener nur eine Instanz für alle laufenden Threads hat. t erstellen Sie eine Race-Bedingung beim Schreiben in die Datei.

  • Wenn Sie lieber einen Post-Prozessor haben, können Sie ihn auf eine höhere Ebene (nicht unter einen bestimmten Sampler) setzen, was dazu führt, dass er nach jeder Anfrage innerhalb des gleichen Umfangs oder darunter ausgeführt wird.

    Zum Beispiel Konfiguration wie

    Thread Group 
        Post-processor 
        Sampler 1 
        ... 
        Sampler N 
    

    Wird Post-processor führen nach jedem Sampler 1 zu laufen ... Sampler N

In beiden Fällen müssen Sie möglicherweise überprüfen, die Sampler Sie Verarbeitung sind, und Überspringe diejenigen, die du deinem Bericht nicht hinzufügen möchtest (einfachste Möglichkeit ist es, eine Namenskonvention für ausgeschlossene Sampler zu erstellen)

0

Ich hatte auch die gleiche Herausforderung. In meinem Fall muss ich überprüfen, ob die JSON-Antwort vom REST-Service korrekt war. Ich habe es auf folgende Weise gelöst.

enter image description here

Ich habe ein JSR223 PreProcessor unter dem Skript root erstellt. Es enthält meine benutzerdefinierte Klasse für JSON-Parsing und -Austests.

import groovy.json.JsonSlurper 
import org.apache.jmeter.assertions.AssertionResult 

class CustomAssert { 

    def parseResponse(json) { 
     def jsonSlurper = new JsonSlurper() 
     return jsonSlurper.parseText(json) 
    } 

    def assertResult(assertionResult, expectedResult, actualResult) { 
     if (!expectedResult.equals(actualResult)) { 
      assertionResult.setFailure(true); 
      assertionResult.setFailureMessage("Expected ${expectedResult} but was ${actualResult}"); 
     } 
    } 
} 

vars.putObject('customAssert', new CustomAssert()) 

Beachten Sie die letzte Zeile:

vars.putObject('customAssert', new CustomAssert()) 

habe ich eine Instanz meiner CustomAssert-vars.

Dann unter meinen HTTP-Requests habe ich JSR233 Assertion

def a = vars.getObject('customAssert') 
def response = a.parseResponse(prev.getResponseDataAsString()) 

a.assertResult(AssertionResult, 'DRY', response.sensorResultHolderUIs[0].result.toString()) 
a.assertResult(AssertionResult, 'DRY', response.sensorResultHolderUIs[1].result.toString()) 
a.assertResult(AssertionResult, 'DRY', response.sensorResultHolderUIs[2].result.toString()) 

Es im Grunde ruft die Instanz von CustomAssert von vars und ruft seine Methoden hinzugefügt. Ich kann so viele setzen JSR233 Assertion s wie ich will. Der einzige Code, der kopiert wird, ist diese beiden Linien auf:

def a = vars.getObject('customAssert') 
def response = a.parseResponse(prev.getResponseDataAsString()) 

Fazit:

  1. Nehmen Sie den gemeinsamen Teil des Codes (das muss nicht kopiert werden).
  2. Wickeln Sie es in eine Klasse ein.
  3. Legen Sie die Klasse in JSR233 PreProcessor unter der Wurzel und seine Instanz exportieren über vars
  4. den Rest des Codes nehmen und einstellen Klasse in 2.
  5. diesen Code Setzen Sie in so viele JSR233 definiert verwenden Assertion s, wie Sie die Instanz in 3 von vars
0

erstellt abrufen möchten Erinnerung Danke user1053510. Ihr Ratschlag führte mich dazu, meinen eigenen JSR223-Listener zu erstellen, der den Bericht rendert. Unten ist der Code in meinem JSR223 Zuhörer:

import com.aventstack.extentreports.*; 
import com.aventstack.extentreports.reporter.*; 
import com.aventstack.extentreports.markuputils.*; 

ExtentHtmlReporter htmlReporter; 
ExtentReports extent; 
ExtentTest test; 

// create the HtmlReporter 
htmlReporter = new ExtentHtmlReporter("C:/AUTO_Results/Results_${testApp}_${reportDate}_${currentTime}_${testenv}.html"); 

//configure report 
htmlReporter.config().setCreateOfflineReport(true); 
htmlReporter.config().setChartVisibilityOnOpen(true); 
htmlReporter.config().setDocumentTitle("${testApp} Results"); 
htmlReporter.config().setEncoding("utf-8"); 
htmlReporter.config().setReportName("${testApp} Results ${reportDate}_${currentTime}_${testenv}"); 
htmlReporter.setAppendExisting(true); 

// create ExtentReports 
extent = new ExtentReports(); 

// attach reporter to ExtentReports 
extent.attachReporter(htmlReporter); 
extent.setReportUsesManualConfiguration(true); 

// Show Env section and set data on dashboard 
extent.setSystemInfo("Tool","JMeter"); 
extent.setSystemInfo("Test Env","${testenv}"); 
extent.setSystemInfo("Test Date","${reportDate}"); 
extent.setSystemInfo("Test Time","${currentTime}"); 

//stringify test info 
String threadName = sampler.getThreadName(); 
String samplerName = sampler.getName(); 
String requestData = props.get("propRequestData"); 
String respCode = props.get("propRespCode"); 
String respMessage = props.get("propRespMessage"); 
String responseData = props.get("propResponse"); 


// create test 
test = extent.createTest(threadName+" - "+samplerName); 
//test.assignCategory("API Testing"); 

// analyze sampler result 
if (vars.get("JMeterThread.last_sample_ok") == "false") { 
    log.error("FAILED: "+samplerName); 
    print("FAILED: "+samplerName); 
    test.fail(MarkupHelper.createLabel("FAILED: "+sampler.getName(),ExtentColor.RED)); 

} else if (vars.get("JMeterThread.last_sample_ok") == "true") { 
    if(responseData.contains("@error")) { 
     log.info("FAILED: "+sampler.getName()); 
     print("FAILED: "+sampler.getName()); 
     test.fail(MarkupHelper.createLabel("FAILED: "+sampler.getName(),ExtentColor.RED)); 

    } else if (responseData.contains("{")) { 
      log.info("Passed: "+sampler.getName()); 
     print("Passed: "+sampler.getName()); 
      test.pass(MarkupHelper.createLabel("Passed: "+sampler.getName(),ExtentColor.GREEN)); 
    } 

} else { 
    log.error("Something is really wonky"); 
    print("Something is really wonky"); 
    test.fatal("Something is really wonky"); 
} 

//info messages 
    test.info("RequestData: "+requestData); 
    test.info("Response Code and Message: "+respCode+" "+respMessage); 
    test.info("ResponseData: "+responseData); 



//playing around 
//markupify json into code blocks 
//Markup m = MarkupHelper.createCodeBlock(requestData); 
//test.info(MarkupHelper.createModal("Modal text")); 
//Markup mCard = MarkupHelper.createCard(requestData, ExtentColor.CYAN); 
// test.info("Request "+m); 
// test.info(mCard); 
//  test.info("Response Data:  "+MarkupHelper.createCodeBlock(props.get("propResponse"))); 
// test.info("ASSERTION MESSAGE:  "+props.get("propAssertion")); 


// end the reporting and save the file 
extent.flush(); 

Dann in jedem Thread Ich habe eine Assertion mit Beanshell dieser Linien:

//request data 
String requestData = new String(prev.SamplerData); 
//String requestData = new String(requestData); 
props.put("propRequestData", requestData); 
//response data 
String respData = new String(prev.ResponseData); 
//String respData = new String(prev.getResponseDataAsString()); 
props.put("propResponse", respData); 
//response code 
String respCode = new String(prev.ResponseCode); 
props.put("propRespCode",respCode); 
//response message 
String respMessage = new String(prev.ResponseMessage); 
props.put("propRespMessage",respMessage); 
Verwandte Themen