我想在测试中循环执行一种行为,该行为将响应通过“消息模板(文件)”生成的消息对某些请求的响应,在该消息中,我用柑橘类测试变量的值和索引的索引替换了一些字符串环。我想我几乎可以使它正常工作,但是不幸的是,当我尝试在行为中使用ReplaceAll String函数时,测试崩溃。请参阅下面的代码片段,其中删除了所有不必要的部分,以期使我的问题更容易理解
public class myBehavior extends AbstractTestBehavior {
private String payloadData;
myBehavior withPayloadData(String payload) {
this.payloadData = payload;
return this;
}
@Override
public void apply() {
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)); // if you uncomment this line the test will crash at starting time when invoking replace_all
}
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");
//s=s.replaceAll("!!Name!!",myvar); // This will crash when starting the test (not actually when running it) !!!
return s;
}
}
@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),
applyBehavior(new myBehavior().withPayloadData("${vm}${i}"))
);
}
09:21:22,102 DEBUG port.LoggingReporter| BEFORE TEST SUITE
09:21:22,102 INFO port.LoggingReporter|
09:21:22,103 INFO port.LoggingReporter|
09:21:22,103 INFO port.LoggingReporter| BEFORE TEST SUITE: SUCCESS
09:21:22,103 INFO port.LoggingReporter| ------------------------------------------------------------------------
09:21:22,103 INFO port.LoggingReporter|
09:21:22,119 DEBUG t.TestContextFactory| Created new test context - using global variables: '{}'
09:21:22,128 INFO port.LoggingReporter|
09:21:22,128 INFO port.LoggingReporter| ------------------------------------------------------------------------
09:21:22,128 DEBUG port.LoggingReporter| STARTING TEST CitrusLearning.mySimpleTest <com.grge.citrus.cmptest.stratus>
09:21:22,128 INFO port.LoggingReporter|
09:21:22,129 DEBUG citrus.TestCase| Initializing test case
09:21:22,130 DEBUG context.TestContext| Setting variable: citrus.test.name with value: 'CitrusLearning.mySimpleTest'
09:21:22,130 DEBUG context.TestContext| Setting variable: citrus.test.package with value: 'com.grge.citrus.cmptest.stratus'
09:21:22,130 DEBUG context.TestContext| Setting variable: vm with value: '/dc/vm/folder/vm_basename'
09:21:22,130 DEBUG citrus.TestCase| Test variables:
09:21:22,131 DEBUG citrus.TestCase| citrus.test.name = CitrusLearning.mySimpleTest
09:21:22,131 DEBUG citrus.TestCase| citrus.test.package = com.grge.citrus.cmptest.stratus
09:21:22,131 DEBUG citrus.TestCase| vm = /dc/vm/folder/vm_basename
09:21:22,131 INFO port.LoggingReporter|
09:21:22,131 DEBUG port.LoggingReporter| TEST STEP 1/1: repeat
09:21:22,131 DEBUG port.LoggingReporter| TEST ACTION CONTAINER with 9 embedded actions
09:21:22,131 DEBUG context.TestContext| Setting variable: i with value: '1'
09:21:22,134 INFO actions.SleepAction| Sleeping 1000 ms
09:21:23,139 INFO actions.SleepAction| Returning after 1000 ms
09:21:23,139 INFO actions.EchoAction| [behavior] - OK ->behavior is invoked
09:21:23,139 INFO actions.EchoAction| [behavior]/dc/vm/folder/vm_basename1 - OK ->variable from Test is correctly transmitted to behavior
09:21:23,140 INFO actions.EchoAction| [func_asis] OK ->in func_asis now
09:21:23,140 INFO actions.EchoAction| [func_asis] myvar=/dc/vm/folder/vm_basename1 - OK ->variable from Test is correctly transmitted to func_asis
09:21:23,140 INFO actions.EchoAction| This is a string in which nothing is replaced, OK fine !
09:21:23,140 INFO actions.EchoAction| [func_replace] OK ->in func_replace
09:21:23,141 INFO actions.EchoAction| [func_replace] myvar=/dc/vm/folder/vm_basename1 - OK ->variable from Test is correctly transmitted to func_asis
09:21:23,141 INFO actions.EchoAction| This is a string in which to replace !!Name!! by the value of my citrus variable but it crashes
09:21:23,143 DEBUG leanExpressionParser| Boolean expression 2 = 3 evaluates to false
09:21:23,143 DEBUG context.TestContext| Setting variable: i with value: '2'
09:21:23,143 INFO actions.SleepAction| Sleeping 1000 ms
09:21:24,145 INFO actions.SleepAction| Returning after 1000 ms
09:21:24,145 INFO actions.EchoAction| [behavior] - OK ->behavior is invoked
09:21:24,145 INFO actions.EchoAction| [behavior]/dc/vm/folder/vm_basename2 - OK ->variable from Test is correctly transmitted to behavior
09:21:24,145 INFO actions.EchoAction| [func_asis] OK ->in func_asis now
09:21:24,145 INFO actions.EchoAction| [func_asis] myvar=/dc/vm/folder/vm_basename2 - OK ->variable from Test is correctly transmitted to func_asis
09:21:24,145 INFO actions.EchoAction| This is a string in which nothing is replaced, OK fine !
09:21:24,146 INFO actions.EchoAction| [func_replace] OK ->in func_replace
09:21:24,146 INFO actions.EchoAction| [func_replace] myvar=/dc/vm/folder/vm_basename2 - OK ->variable from Test is correctly transmitted to func_asis
09:21:24,146 INFO actions.EchoAction| This is a string in which to replace !!Name!! by the value of my citrus variable but it crashes
09:21:24,146 DEBUG leanExpressionParser| Boolean expression 3 = 3 evaluates to true
09:21:24,146 INFO port.LoggingReporter|
09:21:24,147 DEBUG port.LoggingReporter| TEST STEP 1/1 SUCCESS
09:27:51,525 DEBUG port.LoggingReporter| BEFORE TEST SUITE
09:27:51,525 INFO port.LoggingReporter|
09:27:51,525 INFO port.LoggingReporter|
09:27:51,525 INFO port.LoggingReporter| BEFORE TEST SUITE: SUCCESS
09:27:51,525 INFO port.LoggingReporter| ------------------------------------------------------------------------
09:27:51,525 INFO port.LoggingReporter|
09:27:51,542 DEBUG t.TestContextFactory| Created new test context - using global variables: '{}'
09:27:51,551 INFO port.LoggingReporter|
09:27:51,552 ERROR port.LoggingReporter| TEST FAILED CitrusLearning.mySimpleTest <com.grge.citrus.cmptest.stratus> Nested exception is:
java.lang.IllegalArgumentException: No group with name {vm}
at java.util.regex.Matcher.appendReplacement(Matcher.java:849)
at java.util.regex.Matcher.replaceAll(Matcher.java:955)
at java.lang.String.replaceAll(String.java:2223)
at com.grge.citrus.cmptest.stratus.CitrusLearning$myBehavior.func_replace(CitrusLearning.java:180)
at com.grge.citrus.cmptest.stratus.CitrusLearning$myBehavior.apply(CitrusLearning.java:163)
at com.consol.citrus.dsl.design.AbstractTestBehavior.apply(AbstractTestBehavior.java:53)
at com.consol.citrus.dsl.design.ApplyTestBehaviorAction.doExecute(ApplyTestBehaviorAction.java:38)
at com.consol.citrus.actions.AbstractTestAction.execute(AbstractTestAction.java:42)
at com.consol.citrus.dsl.design.DefaultTestDesigner.applyBehavior(DefaultTestDesigner.java:193)
at com.consol.citrus.dsl.testng.TestNGCitrusTestDesigner.applyBehavior(TestNGCitrusTestDesigner.java:168)
at com.grge.citrus.cmptest.stratus.CitrusLearning.mySimpleTest(CitrusLearning.java:194)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:216)
at com.consol.citrus.testng.AbstractTestNGCitrusTest.invokeTestMethod(AbstractTestNGCitrusTest.java:121)
at com.consol.citrus.dsl.testng.TestNGCitrusTest.invokeTestMethod(TestNGCitrusTest.java:121)
at com.consol.citrus.dsl.testng.TestNGCitrusTestDesigner.invokeTestMethod(TestNGCitrusTestDesigner.java:73)
at com.consol.citrus.dsl.testng.TestNGCitrusTest.run(TestNGCitrusTest.java:110)
at com.consol.citrus.dsl.testng.TestNGCitrusTest.run(TestNGCitrusTest.java:56)
at org.testng.internal.MethodInvocationHelper.invokeHookable(MethodInvocationHelper.java:242)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:579)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:135)
at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeSingleClass(TestNGDirectoryTestSuite.java:112)
at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:99)
at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:146)
at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:373)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:334)
at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:119)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:407)
09:27:51,555 INFO port.LoggingReporter| ------------------------------------------------------------------------
09:27:51,555 INFO port.LoggingReporter|
09:27:51,595 INFO port.LoggingReporter|
09:27:51,595 INFO port.LoggingReporter| ------------------------------------------------------------------------
09:27:51,595 DEBUG port.LoggingReporter| AFTER TEST SUITE
对于解决这个问题有很多想法
答案 0 :(得分:1)
您面临的问题是
s=s.replaceAll("!!Name!!",myvar);
不属于Java DSL测试的一部分。在测试运行之前对其进行评估。行为描述为in the Citrus documentat。但是,对echo(...)
的调用是DSL的一部分,因此在实际运行测试时被执行。
您可以做的是让柑橘为您替补。您要用串联的"!!Name!!"
和vm
的值替换i
。为此,请在模板中将"!!Name!!"
替换为"${vm}${i}"
,然后让柑橘为您完成繁重的工作:
String func_replace(String myvar)
{
String s = "This is a string in which to replace ${vm}${id} 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");
return s;
}
在String
到apply()
类的myBehavior
中使用返回的echo(...)
时,柑橘为您代入。
答案 1 :(得分:1)
花了更多时间,我开始理解Citrus如何处理变量,在上述情况下,'myvar'的值实际上设置为“ $ {vm} $ {i}”,执行时将被替换时间,但是从测试动作中调用时...。因此,我查看了自定义测试动作,发现即使在某个时候,变量实例化也有些棘手...但是,尽管如此,我还是可以实现我想做的第一部分是用变量内容替换字符串中的一些预定义值。请参见下面的代码片段。
...但是现在因为我从一个动作中调用了replace函数,所以我无法将字符串返回给调用者,而这正是我打算在行为中执行的操作...因此,我们将调查这是否可行以及如何实现。看看我的测试的其他设计(例如临时文件,其中存储有替换值的字符串,该替换值在func_replace将更新它们后被行为读取。) 无论如何,这是我上面遇到的问题的解决方案:
@Test
public class CitrusLearningL4 extends TestNGCitrusTestDesigner {
public class myBehavior extends AbstractTestBehavior {
private @CitrusResource TestContext parentContext;
myBehavior withContext(@Optional @CitrusResource TestContext context) {
this.parentContext=context;
return this;
}
@Override
public void apply() {
echo("[behavior] - OK ->behavior is invoked");
func_replace();
echo("[behavior] - OK ->behavior is finished");
}
void func_replace()
{
final String s = "This is a string in which '!!Name!!' is present because it was replaced by the value of my test variable";
echo("[func_replace] OK ->in func_replace");
action(new AbstractTestAction() {
public void doExecute(TestContext context) {
String s1 = s;
System.out.println("[anAction] - OK ->anAction is invoked");
String sVar=String.format("%s", (String) parentContext.getVariable("vm") + (String) parentContext.getVariable("i"));
System.out.println("[anAction] - OK ->" + s1.replaceAll("!!Name!!",sVar));
}
});
}
}
@Test @Parameters("context")
@CitrusTest
public void mySimpleBehaviorTest(@Optional @CitrusResource TestContext context) 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),
applyBehavior(new myBehavior().withContext(context))
);
}
}