Citrus测试中调用Java函数使用replaceAll崩溃问题求助
你的问题其实涉及两个核心层面,咱们一步步拆解解决:
1. 直接触发崩溃的原因:String.replaceAll()的正则特性冲突
String.replaceAll()的第一个参数是正则表达式,第二个参数的替换字符串里,$符号在正则语法中有特殊含义——它用来引用匹配到的捕获组。
从错误日志来看,你的myvar值在调用replaceAll时还是原始的Citrus占位符${vm}${i},这时候正则引擎会把${vm}里的$当成捕获组引用,尝试寻找名为vm的分组,但你的匹配规则!!Name!!根本没定义这个分组,所以直接抛出No group with name {vm}的异常。
快速修复:用replace()替代replaceAll()
如果只是做简单的字面量替换(不需要正则匹配),直接用String.replace()即可,它不会解析正则语法,只做纯字符串替换:
String func_replace(String myvar) { String s = "This is a string in which to replace !!Name!! by the value of my citrus variable but it crashes"; echo("[func_replace] OK ->in func_replace"); echo("[func_replace] myvar="+ myvar + " - OK ->variable from Test is correctly transmitted to func_asis"); // 用replace代替replaceAll,避免正则解析冲突 s = s.replace("!!Name!!", myvar); return s; }
如果确实需要正则匹配的复杂替换,可以用Matcher.quoteReplacement()转义替换字符串中的特殊字符:
import java.util.regex.Matcher; String func_replace(String myvar) { String s = "This is a string in which to replace !!Name!! by the value of my citrus variable but it crashes"; echo("[func_replace] OK ->in func_replace"); echo("[func_replace] myvar="+ myvar + " - OK ->variable from Test is correctly transmitted to func_asis"); // 转义替换值中的正则特殊字符 s = s.replaceAll("!!Name!!", Matcher.quoteReplacement(myvar)); return s; }
2. 深层问题:Citrus变量解析时机错误
你在创建myBehavior实例时直接传入"${vm}${i}",这个赋值动作发生在测试启动阶段,但Citrus的变量解析是在测试执行阶段才会进行的,导致payloadData存储的是未解析的占位符字符串,而非实际变量值。
要让Behavior获取到解析后的变量值,需要在Behavior的apply()方法中通过Citrus上下文来解析占位符:
修改后的myBehavior代码
public class myBehavior extends AbstractTestBehavior { private String payloadTemplate; // 存储变量占位符模板 myBehavior withPayloadTemplate(String template) { this.payloadTemplate = template; return this; } @Override public void apply() { // 在测试执行阶段,通过Citrus上下文解析变量 String payloadData = getCitrusContext().getVariableResolver().resolveValue(payloadTemplate); echo("[behavior] - OK ->behavior is invoked"); echo("[behavior]" + payloadData + " - OK ->variable from Test is correctly transmitted to behavior"); echo(func_asis(payloadData)); echo(func_replace(payloadData)); } String func_asis(String myvar) { String s = "This is a string in which nothing is replaced, OK fine !"; echo("[func_asis] OK ->in func_asis now "); echo("[func_asis] myvar="+ myvar + " - OK ->variable from Test is correctly transmitted to func_asis"); return s; } String func_replace(String myvar) { String s = "This is a string in which to replace !!Name!! by the value of my citrus variable but it crashes"; echo("[func_replace] OK ->in func_replace"); echo("[func_replace] myvar="+ myvar + " - OK ->variable from Test is correctly transmitted to func_asis"); // 使用replace避免正则冲突 s = s.replace("!!Name!!", myvar); return s; } }
调整测试代码中的Behavior调用
@CitrusTest public void mySimpleTest() throws IOException { description("Simple Test invoking a behavior which it self will invoke a java function"); variable("vm", "/dc/vm/folder/vm_basename"); repeat().until("i = 3") .actions( sleep(1000L), // 传入占位符模板,让Behavior在执行时解析 applyBehavior(new myBehavior().withPayloadTemplate("${vm}${i}")) ); }
这样调整后,payloadData会在测试执行阶段被正确解析为实际的变量值(比如/dc/vm/folder/vm_basename1、/dc/vm/folder/vm_basename2等),同时替换操作也不会触发正则解析冲突。
内容的提问来源于stack exchange,提问作者fckbo

