Невозможно использовать переменную Citrus в функции Java, вызванной поведением Test
Я хочу выполнить цикл внутри теста, чтобы реализовать поведение, которое будет отвечать на некоторые запросы сообщениями, построенными из "шаблонов сообщений (файлов)", в которых я заменяю некоторые строки значением тестовой переменной citrus и индексом цикла. Я думаю, что мне удалось почти заставить его работать, но, к сожалению, мой тестовый сбой, когда я пытаюсь использовать функции 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}"))
);
}
- Вот выходные данные теста с вызовом replaceAll, прокомментированным в func_replace.
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
Большое спасибо за любую идею, чтобы исправить это
2 ответа
Проблема, с которой вы сталкиваетесь, заключается в том, что
s=s.replaceAll("!!Name!!",myvar);
не является частью теста Java DSL. Он оценивается до запуска теста. Поведение описано в документе Citrus. Призывы к 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(...)
Цитрусовые делают замену для вас.
Потратив немного больше времени на это, я начинаю понимать, как Citrus обрабатывает переменные, в случае, указанном выше, значение 'myvar' фактически установлено в "${vm}${i}" и будет заменено во время выполнения, но когда быть вызванным из тестового действия.... Итак, я посмотрел на пользовательское тестовое действие, чтобы найти, что даже когда-нибудь создание экземпляра переменной немного сложно... но, тем не менее, я смог достичь первой части того, что я хотел сделать, а именно заменить некоторые предопределенные значения в строке по содержимому переменных. Смотрите ниже фрагмент, который делает это.
... Но теперь, поскольку я вызываю функцию замены из действия, я не могу вернуть строку вызывающей стороне, что я и планировал сделать в своем поведении... поэтому я выясню, возможно ли это и как, или рассмотрим некоторые из них. другой дизайн для моего теста (например, временный файл для хранения строки с замененными значениями, читаемой поведением после того, как 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))
);
}
}