使用 JMeter,如何从 API 的响应正文中提取字符串并将其保存到 csv 文件?

Posted

技术标签:

【中文标题】使用 JMeter,如何从 API 的响应正文中提取字符串并将其保存到 csv 文件?【英文标题】:Using JMeter, how can I extract a string from the body of a response of an API and save it to a csv file? 【发布时间】:2019-02-01 22:44:21 【问题描述】:

我从一个类似这样的 API 获得了一些不同的正文响应:

“eyJhbRciOiRRRzI1RiIsInR5cCI6IkpXVCJ9.eyJ1c2RybmRtZSI6IlRlcmhhdCIsInR1aWQiOiJRZXJoYXQiLRJyb2xlRjoibW9iaWxlRRRwcCIsImVtYWlsIjoidGVzdEB0ZXN0LmNvbSIsImlkIjoiU2RyaGF0IiwiaWR0IjoxRRR5MDU5OTUxLCJleRRiOjE1NRkwNzQzRRR9.RRzm3VvioZ_iR-v5EGSSfYJLf0d9aZ-9R-RP4UbER04” P>

我正在使用 JMeter 的正则表达式提取器提取它,如下所示:

如何将正则表达式提取器中的值打印到 .csv 文件中以供以后在不同的测试中使用?

我尝试了此处提供的解决方案,但没有帮助。也许该脚本需要更多调整,但我没有常规知识: JMeter extract all values from regular expression and store in a csv

如果您能提供任何帮助,我将不胜感激。

更新问题: 使用前面提到的问题的答案中的确切代码,我会得到以下错误:

代码:

def csv = new File("my.csv")
1.upto(vars.get("foo_matchNr") as int, 
    csv << vars.get("foo_$it") << System.getProperty("line.separator")  
)

错误:

    019-02-02 11:30:26,972 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2019-02-02 11:30:26,974 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2019-02-02 11:30:26,978 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2019-02-02 11:30:27,223 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : Thread Group
2019-02-02 11:30:27,223 INFO o.a.j.e.StandardJMeterEngine: Starting 3 threads for group Thread Group.
2019-02-02 11:30:27,223 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2019-02-02 11:30:27,224 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=3 ramp-up=1 perThread=333.33334 delayedStart=false
2019-02-02 11:30:27,226 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2019-02-02 11:30:27,225 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-1
2019-02-02 11:30:27,226 INFO o.a.j.s.FileServer: Stored: D:/Software/apache-jmeter-5.0/bin/testUser.csv
2019-02-02 11:30:27,226 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2019-02-02 11:30:27,559 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-2
2019-02-02 11:30:27,892 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-3
2019-02-02 11:30:28,428 ERROR o.a.j.e.JSR223PostProcessor: Problem in JSR223 script, JSR223 PostProcessor
javax.script.ScriptException: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'null' with class 'null' to class 'int'. Try 'java.lang.Integer' instead
    at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:324) ~[groovy-all-2.4.15.jar:2.4.15]
    at org.codehaus.groovy.jsr223.GroovyCompiledScript.eval(GroovyCompiledScript.java:72) ~[groovy-all-2.4.15.jar:2.4.15]
    at javax.script.CompiledScript.eval(Unknown Source) ~[?:1.8.0_191]
    at org.apache.jmeter.util.JSR223TestElement.processFileOrScript(JSR223TestElement.java:221) ~[ApacheJMeter_core.jar:5.0 r1840935]
    at org.apache.jmeter.extractor.JSR223PostProcessor.process(JSR223PostProcessor.java:44) [ApacheJMeter_components.jar:5.0 r1840935]
    at org.apache.jmeter.threads.JMeterThread.runPostProcessors(JMeterThread.java:925) [ApacheJMeter_core.jar:5.0 r1840935]
    at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:564) [ApacheJMeter_core.jar:5.0 r1840935]
    at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:486) [ApacheJMeter_core.jar:5.0 r1840935]
    at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:253) [ApacheJMeter_core.jar:5.0 r1840935]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_191]
Caused by: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'null' with class 'null' to class 'int'. Try 'java.lang.Integer' instead
    at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToNumber(DefaultTypeTransformation.java:176) ~[groovy-all-2.4.15.jar:2.4.15]
    at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.intUnbox(DefaultTypeTransformation.java:82) ~[groovy-all-2.4.15.jar:2.4.15]
    at Script5.run(Script5.groovy:2) ~[?:?]
    at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:321) ~[groovy-all-2.4.15.jar:2.4.15]
    ... 9 more
2019-02-02 11:30:28,436 INFO o.a.j.t.JMeterThread: Thread is done: Thread Group 1-1
2019-02-02 11:30:28,439 INFO o.a.j.t.JMeterThread: Thread finished: Thread Group 1-1
2019-02-02 11:30:28,583 ERROR o.a.j.e.JSR223PostProcessor: Problem in JSR223 script, JSR223 PostProcessor
javax.script.ScriptException: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'null' with class 'null' to class 'int'. Try 'java.lang.Integer' instead
    at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:324) ~[groovy-all-2.4.15.jar:2.4.15]

等等

再加上 2 个类似的错误。

我认为“foo_matchNr”被视为一个变量,而“foo”是我的变量,它每次都会改变它的值,还是它是一个值列表?我不知道这个正则表达式提取器是如何工作的,也不是很时髦。

使用从前面提到的问题的答案改编的代码(使用我对 groovy 代码的 0 级知识),我会得到以下错误:

更改代码:

def csv = new File("my.csv")
1.upto(vars.get("foo") as int, 
    csv << vars.get("foo_$it") << System.getProperty("line.separator")  
)

错误:

2019-02-02 11:08:27,613 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2019-02-02 11:08:27,614 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2019-02-02 11:08:27,635 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2019-02-02 11:08:27,850 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : Thread Group
2019-02-02 11:08:27,850 INFO o.a.j.e.StandardJMeterEngine: Starting 3 threads for group Thread Group.
2019-02-02 11:08:27,850 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2019-02-02 11:08:27,850 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=3 ramp-up=1 perThread=333.33334 delayedStart=false
2019-02-02 11:08:27,851 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-1
2019-02-02 11:08:27,852 INFO o.a.j.s.FileServer: Stored: D:/Software/apache-jmeter-5.0/bin/testUser.csv
2019-02-02 11:08:27,853 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2019-02-02 11:08:27,853 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2019-02-02 11:08:28,187 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-2
2019-02-02 11:08:28,520 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-3
2019-02-02 11:08:28,794 ERROR o.a.j.e.JSR223PostProcessor: Problem in JSR223 script, JSR223 PostProcessor
javax.script.ScriptException: java.lang.NumberFormatException: For input string: "eyJhbRciOiRRRzI1RiIsInR5cCI6IkpXVCJ9.eyJ1c2RybmRtZSI6IlRlcmhhdCIsInR1aWQiOiJRZXJoYXQiLRJyb2xlRjoibW9iaWxlRRRwcCIsImVtYWlsIjoidGVzdEB0ZXN0LmNvbSIsImlkIjoiU2RyaGF0IiwiaWR0IjoxRRR5MDU5OTUxLCJleRRiOjE1NRkwNzQzRRR9.RRzm3VvioZ_iR-v5EGSSfYJLf0d9aZ-9R-RP4UbER04"
    at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:324) ~[groovy-all-2.4.15.jar:2.4.15]
    at org.codehaus.groovy.jsr223.GroovyCompiledScript.eval(GroovyCompiledScript.java:72) ~[groovy-all-2.4.15.jar:2.4.15]
    at javax.script.CompiledScript.eval(Unknown Source) ~[?:1.8.0_191]
    at org.apache.jmeter.util.JSR223TestElement.processFileOrScript(JSR223TestElement.java:221) ~[ApacheJMeter_core.jar:5.0 r1840935]
    at org.apache.jmeter.extractor.JSR223PostProcessor.process(JSR223PostProcessor.java:44) [ApacheJMeter_components.jar:5.0 r1840935]
    at org.apache.jmeter.threads.JMeterThread.runPostProcessors(JMeterThread.java:925) [ApacheJMeter_core.jar:5.0 r1840935]
    at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:564) [ApacheJMeter_core.jar:5.0 r1840935]
    at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:486) [ApacheJMeter_core.jar:5.0 r1840935]
    at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:253) [ApacheJMeter_core.jar:5.0 r1840935]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_191]
Caused by: java.lang.NumberFormatException: For input string: "eyJhbRciOiRRRzI1RiIsInR5cCI6IkpXVCJ9.eyJ1c2RybmRtZSI6IlRlcmhhdCIsInR1aWQiOiJRZXJoYXQiLRJyb2xlRjoibW9iaWxlRRRwcCIsImVtYWlsIjoidGVzdEB0ZXN0LmNvbSIsImlkIjoiU2RyaGF0IiwiaWR0IjoxRRR5MDU5OTUxLCJleRRiOjE1NRkwNzQzRRR9.RRzm3VvioZ_iR-v5EGSSfYJLf0d9aZ-9R-RP4UbER04"
    at java.lang.NumberFormatException.forInputString(Unknown Source) ~[?:1.8.0_191]
    at java.lang.Integer.parseInt(Unknown Source) ~[?:1.8.0_191]
    at java.lang.Integer.valueOf(Unknown Source) ~[?:1.8.0_191]
    at org.codehaus.groovy.runtime.StringGroovyMethods.toInteger(StringGroovyMethods.java:3319) ~[groovy-all-2.4.15.jar:2.4.15]
    at org.codehaus.groovy.runtime.StringGroovyMethods.asType(StringGroovyMethods.java:178) ~[groovy-all-2.4.15.jar:2.4.15]
    at org.codehaus.groovy.runtime.dgm$1048.doMethodInvoke(Unknown Source) ~[groovy-all-2.4.15.jar:2.4.15]
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1225) ~[groovy-all-2.4.15.jar:2.4.15]
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034) ~[groovy-all-2.4.15.jar:2.4.15]
    at org.codehaus.groovy.runtime.InvokerHelper.invokePojoMethod(InvokerHelper.java:935) ~[groovy-all-2.4.15.jar:2.4.15]
    at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:926) ~[groovy-all-2.4.15.jar:2.4.15]
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:181) ~[groovy-all-2.4.15.jar:2.4.15]
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.asType(ScriptBytecodeAdapter.java:604) ~[groovy-all-2.4.15.jar:2.4.15]
    at Script4.run(Script4.groovy:2) ~[?:?]
    at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:321) ~[groovy-all-2.4.15.jar:2.4.15]
    ... 9 more
2019-02-02 11:08:28,797 INFO o.a.j.t.JMeterThread: Thread is done: Thread Group 1-1
2019-02-02 11:08:28,797 INFO o.a.j.t.JMeterThread: Thread finished: Thread Group 1-1
2019-02-02 11:08:29,160 ERROR o.a.j.e.JSR223PostProcessor: Problem in JSR223 script, JSR223 PostProcessor
javax.script.ScriptException: java.lang.NumberFormatException: For input string: "

这次它“看到”了我有兴趣处理的字符串,但似乎在处理它们时遇到了一些问题。 对于我从其他 2 个包含不同字符串的响应(我正在发出 3 个请求并获得 3 个响应,每个响应包含不同的正文字符串)中获得的其他 2 个变量,我又得到了 2 个类似的错误。只是“For input string”后面的值不同。

【问题讨论】:

您在 JMeter 日志中遇到了什么错误? @ Vadim Yangunaev 我用我尝试过的 groovy 代码和我得到的错误 + 我头脑简单的观察更新了这个问题。 【参考方案1】:

如果您的响应中只有一个匹配项,请使用此代码粘贴到 JSR223 PostProcessor:

def csv = new File("my.csv")
csv << vars.get("foo") << System.getProperty("line.separator")

【讨论】:

感谢您对我的问题表现出兴趣!您的解决方案有效,但它不会将不同行上的不同字符串分开。它根本没有将它们分开。任何想法我怎么能做到这一点? 我想出了如何将字符串放在 csv 文件中的新行上,方法是将您的答案与我之前使用的代码相结合:def csv = new File("my.csv") csv @JustNatural 我已根据您的建议更新了答案的代码。【参考方案2】:

    为你的第一段“代码”

    def csv = new File("my.csv")
    1.upto(vars.get("foo_matchNr") as int, 
        csv << vars.get("foo_$it") << System.getProperty("line.separator")  
    )
    

    错误告诉$foo_matchNr 变量不存在,使用Debug Sampler 和View Results Tree 侦听器组合仔细检查它是否存在并且具有数值。

    第二段代码:

    def csv = new File("my.csv")
    1.upto(vars.get("foo") as int, 
        csv << vars.get("foo_$it") << System.getProperty("line.separator")  
    )
    

    错误表明它无法转换此行:

       eyJhbRciOiRRRzI1RiIsInR5cCI6IkpXVCJ9.eyJ1c2RybmRtZSI6IlRlcmhhdCIsInR1aWQiOiJRZXJoYXQiLRJyb2xlRjoibW9iaWxlRRRwcCIsImVtYWlsIjoidGVzdEB0ZXN0LmNvbSIsImlkIjoiU2RyaGF0IiwiaWR0IjoxRRR5MDU5OTUxLCJleRRiOjE1NRkwNzQzRRR9.RRzm3VvioZ_iR-v5EGSSfYJLf0d9aZ-9R-RP4UbER04
    

    到Integer。我的期望是您需要将代码更改为:

    new File("my.csv") << vars.get("foo") << System.getProperty("line.separator") 
    

如果上述代码无法生成您要查找的内容,请使用上述调试采样器的输出更新您的问题,并指明您希望存储哪些变量以及如何存储。

查看The Groovy Templates Cheat Sheet for JMeter 文章以开始使用 Groovy 脚本。


一般来说,我建议使用Sample Variables 属性来将生成的JMeter 变量存储到.jtl 结果文件中。如果您希望输出进入单独的文件 - 考虑使用 Flexible File Writer

【讨论】:

以上是关于使用 JMeter,如何从 API 的响应正文中提取字符串并将其保存到 csv 文件?的主要内容,如果未能解决你的问题,请参考以下文章

Guzzlehttp - 如何从 Guzzle 6 获取响应的正文?

如何在 Asp.Net Web API 2 中使用 Owin OAuth2 修改令牌端点响应正文

JMeter json路径在响应中声明json或数组

LoadRunner HTTP响应正文中乱码

React 无法从 PHP API 获取响应正文

改造 2:从响应正文中获取 JSON