【问题标题】:JMeter Thread Group Not Getting to BeanShell PostProcessorJMeter 线程组未到达 BeanShell 后处理器
【发布时间】:2016-02-21 23:44:22
【问题描述】:

在我的 JMeter 测试计划中,我试图将所有错误都写到日志中。我正在使用配置如下的 BeanShell 后处理器

import org.apache.jmeter.services.FileServer;

if (ResponseCode != null && ResponseCode.equals("200") == false) {
Failure = true;

// displays in Results Tree
FailureMessage ="Creation of a new CAE record failed. Response code " + ResponseCode + "." ; 

// Static elements
part1 = "Creation of a new record failed. Response code: ";
part2 = ". Sorry!";

// Open File(s)
FileOutputStream f = new FileOutputStream("d:\\error.csv", true); 
PrintStream p = new PrintStream(f); 

// Write data to file 
p.println( part1 + ResponseCode + part2 );

// Close File(s)
p.close();
f.close();
}

我正在尝试做一个简单的测试,其中 HTTP 请求正在执行一个 POST,该 POST 从目录不再存在的 c:jmeter/tests/payloads 传入一个 json 文件。 (假设有人不小心删除了它......)

问题是测试正在停止(见下文)从未到达 BeanShell 将错误写入日志文件。我需要捕获所有错误响应,并且只有错误响应。

我不确定如何处理这个问题。我读过Jmeter. BeanShell PostProcessor 和其他人,但他们没有解决当它没有到达 BeanShell 时会发生什么的问题。

感谢任何帮助!

org.apache.jorphan.util.JMeterStopThreadException: End of sequence
  at org.apache.jmeter.functions.FileToString.execute(FileToString.java:105)
  at org.apache.jmeter.engine.util.CompoundVariable.execute(CompoundVariable.java:142)
  at org.apache.jmeter.engine.util.CompoundVariable.execute(CompoundVariable.java:118)
  at org.apache.jmeter.testelement.property.FunctionProperty.getStringValue(FunctionProperty.java:101)
  at org.apache.jmeter.testelement.AbstractTestElement.getPropertyAsString(AbstractTestElement.java:274)
  at org.apache.jmeter.config.Argument.getValue(Argument.java:146)
  at org.apache.jmeter.protocol.http.util.HTTPArgument.getEncodedValue(HTTPArgument.java:236)
  at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.sendPostData(HTTPHC4Impl.java:1111)
  at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.handleMethod(HTTPHC4Impl.java:453)
  at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.sample(HTTPHC4Impl.java:329)
  at org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy.sample(HTTPSamplerProxy.java:74)
  at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1146)
  at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1135)
  at org.apache.jmeter.threads.JMeterThread.process_sampler(JMeterThread.java:434)
  at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:261)
  at java.lang.Thread.run(Unknown Source)
Caused by: java.io.FileNotFoundException: File 'C:\JMeter\test\payloads\Request_1.json' does not exist
  at org.apache.commons.io.FileUtils.openInputStream(FileUtils.java:299)
  at org.apache.commons.io.FileUtils.readFileToString(FileUtils.java:1711)
  at org.apache.commons.io.FileUtils.readFileToString(FileUtils.java:1734)
  at org.apache.jmeter.functions.FileToString.execute(FileToString.java:102)

解决方案

根据 Dmitri 的反馈,我已从 Beanshell PostProcessor 切换到 Beanshell Assertion。经过一些调整,我让它在现在只将错误(响应!= 200)写入errors.csv文件的地方工作。它不会附加上一次运行的文件,而是每次运行都会覆盖,因此只捕获最后一次运行的错误。

如果有人认为我的解决方案可以改进,我很乐意收到反馈。再次感谢 Kiril 和 Dmitri。

import org.apache.jmeter.services.FileServer;

if (ResponseCode != null && ResponseCode.equals("200") == true) {
    SampleResult.setResponseOK();  
}
    else if (!ResponseCode.equals ("200") == true ) { 
    Failure = true;
    FailureMessage ="Creation of a new record failed. Response code " + ResponseCode + "." ; // displays in Results Tree
    print ("Creation of a new record failed: Response code  " + ResponseCode + ".");   // goes to stdout
    log.warn("Creation of a new record failed: Response code " + ResponseCode); // this goes to the JMeter log file

// Static elements or calculations
    part1 = "Unable to generate a new record via POST. The response code is: \"";
    part2 = "\". \n\n For response code = \'Non-HTTP ressponse\', verify the payload file still exists. \n For response code = 409, check the recordTypeId and recordGrpId combination for validity. \n For response code = 500, verify the database and its host server are reachable. ";

// Open File(s)
    FileOutputStream f = new FileOutputStream(FileServer.getFileServer().getBaseDir() + "\\error.csv"); 
    PrintStream p = new PrintStream(f); 

// Write data to file 
    p.println( part1 + ResponseCode + part2 );

// Close File(s)
    p.close();
    f.close();
}

【问题讨论】:

  • 与您的问题无关,但ResponseCode.equals("200") == true:通常状态200表示成功,您不必为布尔值添加==。所以也许你的意思是有一个条件为!ResponseCode.equals("200")(即如果返回码不是200,则输入错误条件)?
  • @KirilS。谢谢。在我最初发布后,我在我的代码中发现并更正了这一点。我的意思是输入'ResponseCode.equals("200") == false'。使用你的 '!ResponseCode.equals("200") == true` 做同样的事情吗?
  • !ResponseCode.equals("200")(不带任何 ==)与ResponseCode.equals("200") == false 相同(equals 返回布尔值,运算符!取反)
  • @KirilS。感谢您的澄清。

标签: jmeter


【解决方案1】:
  1. Beanshell 后处理器中没有ResponseCodeFailureFailureMessage,请改用Beanshell Assertion
  2. 您的ResponseCode.equals("200") 子句假定响应成功,错误响应的响应代码通常> 400

有关 JMeter 中 Beanshell 脚本的全面信息,请参阅 How to Use BeanShell: JMeter's Favorite Built-in Component 指南。

【讨论】:

  • 谢谢!感谢您,我已将我的问题附加到解决方案中。我不知道你在 #1 中所说的内容。这一切都不同了。
【解决方案2】:

Jmeter 覆盖您的 error.csv 文件而不是附加到它,因为您在每次断言调用时都重新打开它。尝试预先打开它,例如在setup thread group 中的单独 Beanshell 采样器中:

file = new FileOutputStream("error.csv", true);
bsh.shared.custom_log = new PrintStream(file)

然后在您的 beanshell 断言中以如下方式使用它:

if (ResponseCode.equals("200")==false) {
    bsh.shared.custom_log.println( part1 + ResponseCode + part2 );
}

顺便说一句,AFAIK,你根本不需要这部分,因为默认情况下带有代码 200 的 http 响应是可以的:

if (ResponseCode != null && ResponseCode.equals("200") == true) {
    SampleResult.setResponseOK();  
}

我没有测试代码,所以可能有错别字,但非常相似的代码对我有用。

Beanshell 共享值是在锁定的情况下访问的,因此如果您对它进行大量写入,请注意可能出现的性能问题。使用这样的脚本和相当短的字符串(50-100 个字符),我每秒写入约 1k 次,而对 jmeter 性能没有显着影响。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多