Coder Social home page Coder Social logo

citrusframework / citrus Goto Github PK

View Code? Open in Web Editor NEW
440.0 41.0 136.0 84.75 MB

Framework for automated integration tests with focus on messaging integration

Home Page: https://citrusframework.org

License: Apache License 2.0

Java 98.47% XSLT 0.31% HTML 0.09% Groovy 0.84% Gherkin 0.01% Dockerfile 0.01% Shell 0.27% Makefile 0.01%
integration-testing microservices messaging

citrus's Introduction

Citrus Integration Testing Logo

Maven Central build Javadocs Licensed under Apache License version 2.0 Chat on Zulip

Welcome to Citrus

Citrus is a test framework written in Java that is able to create fully automated end-to-end use case tests for enterprise SOA applications. Citrus simulates surrounding interface partners supporting a huge set of different transports and protocols like Http, JMS, TCP/IP, FTP, SOAP, XML and JSON.

Visit our official website at 'https://citrusframework.org' for more information and a detailed documentation.

Preconditions

You need following software on your machine in order to use the Citrus framework:

  • Java 17+ Installed JDK plus JAVA_HOME environment variable set up and pointing to your Java installation directory. Used to compile and build the Citrus code.

  • Maven 3.9.5+ Citrus projects will fit best with Maven. However, it is not required to use Maven. You can also run tests using Gradle for instance.

  • Java IDE (optional) A Java IDE will help you to manage your Citrus project (e.g. creating and executing test cases). You can use the Java IDE that you like best like Eclipse or IntelliJ IDEA.

Installation

  • Download the latest Citrus release archive

  • Extract the archive into an appropriate location on your local storage

  • Read the Maven tutorial to find out how to integrate the Citrus tests into the Maven build lifecycle

Release Notes

Each release comes with a complete reference documentation. At the beginning of the reference you will find a section about the changes and notes for this release. For detailed description of changed packages and classes do also consult the provided javadoc.

Resources

  • Citrus's source repository is hosted on github.com. You can clone the repository with git://github.com/citrusframework/citrus.git as URL

  • Find our blog and more interesting articles around Citrus on https://citrusframework.org/news and checkout the various post categories for selecting a specific topic.

  • https://citrusframework.org offers tutorials and more information about Citrus framework.

Samples

Our sample section is still growing. You can find several sample projects in the separate repository https://github.com/citrusframework/citrus-samples.

Licensing

Copyright 2006-2024 the original author or authors.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Consulting

Just in case you need professional support for Citrus have a look at https://citrusframework.org/contact.html. Contact [email protected] directly for any request or questions

Bugs

Please report any bugs and/or feature requests directly to https://github.com/citrusframework/citrus/issues

Information

For more information on Citrus see citrusframework.org, including a complete reference manual.

citrus's People

Contributors

akuz0 avatar apupier avatar bbortt avatar ceazy79 avatar christophd avatar cliffle avatar dependabot[bot] avatar dimovelev avatar eddumelendez avatar gucce avatar jeisfeld avatar johnals avatar jza089 avatar karnis avatar kezhuw avatar marcelmay avatar martinmaher avatar mbeil avatar picimako avatar rhuss avatar s1hofmann avatar sdenel avatar sgbeal avatar sparsick avatar svettwer avatar swathisprasad avatar taz77 avatar tschlat avatar tvelkoff avatar vdsrd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

citrus's Issues

Global scoped data dictionaries breaking message receipt

When data dictionaries are global scoped and a totally different message arrives that does not match to the dictionary key definitions the message validation is broken for that message. This is especially a problem when XPath data dictionaries can not find the respective nodes in message content.

Global scoped data dictionaries should not break the message receiving validation for non applicable messages. When not applicable for that particular message content (e.g. totally different message content arrives) the global data dictionary should simply not apply for that message.

allow variable value definition in cdata section

allow a variable to be defined as:

<variable name="foo> <value> <![CDATA[ <nodes><node>data</node></nodes> ]]> </value> </variable>

currently, citrus gives this error message:

Caused by: org.xml.sax.SAXParseException; lineNumber: 38; columnNumber: 13; cvc-complex-type.2.3: Element 'value' cannot have character [children], because the type's content type is element-only.

String[] parameters to Java call inside template are re-used

If there is a action inside a , then any "String[]" parameters passed to the Java method seem to get their values cached. ie if I call the template multiple times, then the parameters from the first call get used in all subsequent instances too.

This only seems to happen for String[] parameters (not String parameters) and only when the java call is inside a tepmlate.

Validating timestamp value in interval

It is hard to validate timestamp value exactly, but in most cases tester can expect timestamp in some interval. Especially in combination with citrus:currentDate().
<Timestamp>@between(2001-12-17T09:30:47.0Z,2001-12-17T09:30:50.0Z)@</Timestamp>

I haven't found anything like this in the documentation so I assume this is not yet possible.

NullPointer when receiving messages in a template with global-context="false"

When using a template with global-context="false" Citrus will throw a NullPointerException within any receive action while validating the received message.

The problem was found on 1.2M2.

Suggested solution:
In the template's test context, there's no MessageValidatorRegistry set.

In com.consol.citrus.container.Template add in the doExecute where the new (inner) TestContext is created:

    if (globalContext) {
        innerContext = context;
    } else {
        innerContext = new TestContext();
        ....       
        innerContext.setMessageValidatorRegistry(context.getMessageValidatorRegistry());
    }

Better error reporting

I think better error reporting would be a major enhancement for citrus. Nowadays it is not easy (sometimes even impossible) to conduct from the exceptions occuring (and reported as test failures) where in the XML test plan a test is failing.

My dream would be to have a line number where in the XML description the errors occurs. That this is possible can be seen from Tapestry (http://tapestry.apache.org/tapestry5.1/cookbook/exceptions.html).

I don't say that this is an easy task, but it would make Citrus make even more outstanding because my guess is, that most of the time you are wondering why a test case fails. Let me know, whether I can help you out here.

JUnit4CitrusTestDesigner : validateScript doesn't work properly

Hi,

With JUnit4CitrusTestDesigner, using the following code doesn't not work :

http().client(enterpriseApiHttpClient)
    .response(HttpStatus.OK)
    .contentType(MediaType.APPLICATION_JSON)
    .messageType(MessageType.JSON)
    .validateScriptType("groovy")
    .validateScript(new ClassPathResource("groovy/customer/ValidateGetCustomers.groovy")))
    .timeout(30000L);

It throw a FileNotFoundException for ValidateGetCustomers.groovy even if the file exists. However if I transform this file to a String, it works fine.

Regards

Maven - Plugin

Hi Christoph

is it possible to get the source of your maven plugins so that we can change the target of the generated tests and also for the schema locations.

Best Magnus

Comparing the expected value and returned value

Hi,

Is there any functionality in Citrus which will help me compare the value returned in the response XML to the one I am expecting?

The scenario I want to test is:

The response I get, after sending the HTTP request to my application,contains XML message. This message contains fields like the status string and the code.
What I want to do in my test case is that compare this code and status string to the values I am expecting.

Hence the requirement.

maven cannot find the citrus lib

<dependency>
            <groupId>com.consol.citrus</groupId>
            <artifactId>citrus-core</artifactId>
            <version>1.3.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.consol.citrus</groupId>
            <artifactId>citrus-ws</artifactId>
            <version>1.3.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.consol.citrus</groupId>
            <artifactId>citrus-http</artifactId>
            <version>1.3.1</version>
            <scope>test</scope>
        </dependency>

maven cannot find the libs.

http://maven-repository.com/search?q=citrus-core also no result..

Cant create default archetype

When doing the tutorial for setup with maven, it seems that its using snapshot version that no longer exists under the repo and this causes the step to fail:
http://www.citrusframework.org/reference/html/index.html#setup-using-maven

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1:29.502s
[INFO] Finished at: Tue Feb 16 13:05:01 CET 2016
[INFO] Final Memory: 13M/193M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-archetype-plugin:2.4:generate (default-cli) on project standalone-pom: The desired archetype does not exist (com.consol.citrus.mvn:citrus-quickstart-soap:2.5-SNAPSHOT) -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

SSHClient doesn't work just with username / password

After defining the ssh client in citrus-context.xml with following parameters:

"<citrus-ssh:client id="sshClientSender"
host=""
port="22"
user="
"
password="****"
reply-handler="sshClientHandler"
strict-host-checking="false"
/>"

and using the handler in my testcase with following code:

send("sshClientSender").payload("commandinput")

i always got the message:

com.consol.citrus.exceptions.CitrusRuntimeException: Cannot connect via SSH: com.jcraft.jsch.JSchException: Auth cancel

In /citrus-ssh/src/test/java/com/consol/citrus/ssh/CitrusSshClientTest.java Line 200 i added "session.setPassword(password);"
after that it worked fine.

Kind Regards,
Peter

JSON data dictionary throws NullPointerException

I have a JSON data dictionary like this:

<citrus:json-data-dictionary id="sampleDD">
    <citrus:mappings>
        <citrus:mapping path="id" value="2" />
    </citrus:mappings>
</citrus:json-data-dictionary>

And my <send> action looks like this:

<send endpoint="sampleEndpoint">
    <message data-dictionary="sampleDD" type="json">
        <data>
            {
                "id": 1,
                "name": "abcd",
                "tag": null
            }
        </data>
    </message>
</send>

I presume that this is a valid JSON, even though one of the key has a value null. While running the code, I get an NPE.

Form urlencoded marshaller using wrong xsd location

The x-www-form-urlencoded message marshaller is using the wrong http-message.xsd location. This causes warnings during Citrus start up:

WARN model.FormMarshaller| Failed to setup form message marshaller
java.lang.IllegalArgumentException: Resource class path resource [com/consol/citrus/http/citrus-http-message.xsd] does not exist

Nested iterate conditions not evaluated as expected

If I have nested elements in a Citrus test, then the inner loop only executes during the first iteration of the outer loop. Even if I use to reset the variable associated with the inner loop to 0, the content of the inner loop is not executed.

    <actions>
      <iterate condition="i lt= 5" index="i">
        <create-variables>
          <variable name="j" value="0"/>
        </create-variables>
        <iterate condition="j lt= 3" index="j">
         <echo>
          <message>i=${i} j=${j}</message>
         </echo>
        </iterate>
      </iterate>
    </actions>

This only echoes the following messages:
i=1 j=1
i=1 j=2
i=1 j=3

When i is greater than 1 the condition "j lt= 3" continues to evaluate as false.

Documentation: correct typos and inconsistencies

The (very well structured and presented) documentation contains a few typos and inconsistencies listed below:

  1. Typos found by spell-checker add-on in FireFox

Document URL: http://www.citrusframework.org/reference/html_single/index.html
Citrus Framework - Reference Documentation

Location: 1.2. Usage scenarios
Problem: typo
Text: In a such a test scenario
Suggestion: In such a test scenario

Location: 1.2. Usage scenarios
Problem: appended words
Text: bugfixing
Suggestion: bug fixing

Location: 2.1. Using Maven
Problem: appended words
Text: lifecycles
Suggestion: life cycles

Location: 2.2.1. Preconditions
Problem: typo
Text: precondintions
Suggestion: preconditions

Location: 5.2.4. Explicit message element validation
Problem: typo
Text: appropiate
Suggestion: appropriate

Location: 5.2.4. Explicit message element validation
Problem: typo
Text: choosen
Suggestion: chosen

Location: 5.2.7. Message selectors
Problem: singular form only
Text: informations
Suggestion: information

Location: 6.1. Connecting to the database
Problem: typo
Text: descirbed
Suggestion: described

Location: 6.2. Sleep
Problem: typo
Text: unnessesary
Suggestion: unnecessary

Location: 11.4. JMS synchronous message receiver
Problem: typo
Text: requestor
Suggestion: requester

Location: 11.5. JMS Topics
Problem: typo
Text: destiantion
Suggestion: destination

Location: 12.2.4. JMS connecting message handler
Problem: typo
Text: stategy
Suggestion: strategy

Location: 13.5.1. Send SOAP attachments
Problem: typo
Text: wich
Suggestion: which

Location: 13.5.1. Send SOAP attachments
Problem: typo
Text: fullfill
Suggestion: fulfill

Location: 13.5.2. Receive and validate SOAP attachments
Problem: typo
Text: instanes
Suggestion: instances

Location: 13.5.2. Receive and validate SOAP attachments
Problem: typo
Text: curent
Suggestion: current

Location: 14.4. Synchronous message channel receiver
Problem: typo
Text: Cittrus
Suggestion: Citrus

Location: 15.12. citrus:randomEnumValue()
Problem: typo
Text: funciton
Suggestion: function

Location: 15.21. citrus:mapValue()
Problem: typo
Text: value ist not defined
Suggestion: value is not defined

Location: A.1.1. The use case
Problem: typo
Text: seperate flights
Suggestion: separate flights

Location: A.1.3. Configure the Http adapter
Problem: typo
Text: requsts
Suggestion: requests

Location: A.1.3. Configure the Http adapter
Problem: typo
Text: alredy
Suggestion: already

Location:A.1.3. Configure the Http adapter
Problem: typo
Text: synchrpnous
Suggestion: synchronous

Location: A.1.4. The test case
Problem: typo
Text: test case proceeeds
Suggestion: test case proceeds

  1. Inconsistencies

Document URL: http://www.citrusframework.org/reference/html_single/index.html
Citrus Framework - Reference Documentation

Location: Whole document
Problem: Inconsistent usage of uppercase in acronyms: HTTP (also: URL, URI, XSD)
Text: HTTP | Http | http
Suggestion: HTTP

Location: 1.2. Usage scenarios
Problem: Inconsistent usage of 'capitalization' (first letter capital)
Text: service-oriented Architecture
Suggestion: Service-Oriented Architecture

HTTP Client - Unable to send query param that is enclosed within curly braces

I have a use case where my query param contains text within curly braces. For example:

http://localhost:8080/sample?query={"name":"abcd"}
which, when encoded should look like
http://localhost:8080/sample?query=%7B%22name%22:%22abcd%22%7D

To specify the HTTP client for this particular request,

<citrus-http:client id="sample_client" request-method="GET" request-url="http://localhost:8080/sample?query=&#123;&quot;name&quot;:&quot;abcd&quot;&#125;"/>

I get java.lang.IllegalArgumentException: Not enough variable values available to expand '"name"'

When I give it as

<citrus-http:client id="sample_client" request-method="GET" request-url="http://localhost:8080/sample?query=%7B%22name%22:%22abcd%22%7D"/>

all % characters are escaped to %25 while performing the request. So it'll look like

http://localhost:8080/sample?query=%257B%2522name%2522:%2522abcd%2522%257D

Please suggest a solution for this. Thanks!

minor bug in java action <java...>

Hi Christoph,

tried to set up the java action as described in the documentation (ver. 1.1). Ran into a NullpointerException when
configured as follows:

<method name="invoke">
    <argument type="String[]">1,2</argument>
    <argument type="String">bla</argument>
</method>

After a period of try and error I found out that the following configuration works:

<method name="invoke">
    <argument type="String[]">1,2</argument>
    <argument type="">bla</argument>
</method>

And this one does as well:

<method name="invoke">
    <argument type="String[]">1,2</argument>
    <argument>bla</argument>
</method>

For the reasons of consistency and convenience I think that the upper most configuration should work as well. As a newby like me you would 99 per cent follow this direction at first :-)

Yours
ralf

x-www-form-urlencoded payload lost

When receiving a x-www-form-urlencoded Http POST request the payload is logged to the console by default. This causes the input stream to be consumed before the form payload is handled by the request chain. This results in an empty message body when the message is passed to the test case for validation.

Need to extend request caching filter implementation for x-www-form-urlencoded form data.

Provide protected fields or getters in com.consol.citrus.dsl.junit.JUnit4CitrusTestRunner in order to make it easier extendable

I want to extend the JUnit4CitrusTestRunner to add custom operations. Therefore I need various field to be protected:

For example I need a SendFileBuilder and SendFileAction. Unfortunately, the applicationContext is private rather than protected. Of course, I could just @Autowired it but this is unnecessary IMHO.

I also want to store a variable which is available in the textContext to a local java variable. Currently, I solved this by creating an action

public class RetrieveVariableAction extends AbstractTestAction {
    private TestContext context;
    @Override
    public void doExecute(TestContext context) {
        this.context = context;
    }
    public String getVariableValue(String variableName) {
        if (context == null) {
            throw new IllegalStateException(
                    String.format("%s not available, please run the action before retrieve a variable", TestContext.class.getSimpleName()));
        }
        return context.getVariable(variableName);
    }
}

which is used the following

    protected String retrieveVariable(String variableName) {
        return run(new RetrieveVariableAction()).getVariableValue(variableName);
    }

If you now also make the testRunner protected I could access the testContext via com.consol.citrus.dsl.runner.DefaultTestRunner.createTestContext(). This is just one possible solution, maybe there is a better one. Do you understand my problem, though?
I tried to get the TestContext from the applicationContext but I always got a different one with deeper investigating about the reason.

But, thank you for this framework :-)

Missing 2.5 xsd references in spring.schemas

Spring spring.schemas files missing 2.5 xsd references. This might cause problems when referencing a 2.5 xsd resource in Spring configuration files using the schema location as Spring might not be able to resolve the file resource.

Nullpointer in after suite

Nullpointer exception in after suite when citrus instance has not been initialized. This only happens when error is raised very early in before suite before Citrus instance has been initialized.

ClassPathResource name needs correction in User Guide

Please update the User Guide to display the properly-cased name of the ClassPathResource class. In many instances, it is written as ClasspathResource. This will save many people from headaches on why their class isn't being found.

XMLUtils throws exception if namespace URI contains "xmlns"

After upgrading to the latest snapshot (14) of Citrus I get StringIndexOutOfBoundsExceptions in XMLUtils.lookupNamespaces if a namespace URI contains the string "xmlns":

java.lang.StringIndexOutOfBoundsException: String index out of range: -1
    at java.lang.String.substring(String.java:1937)
    at com.consol.citrus.util.XMLUtils.lookupNamespaces(XMLUtils.java:292)
    at com.consol.citrus.util.XMLUtilsTest.testLookupNamespacesWithNamespaces(XMLUtilsTest.java:23)

The problem can be reproduced by this XML:

<?xml version="1.0" ?>
<ns1:modifyBuildingResult xmlns:ns1="http://www.bfs.admin.ch/xmlns/gwr/building/2" xmlns:ns2="http://www.bfs.admin.ch/xmlns/gwr/plausibilityRuleType/2">
</ns1:modifyBuildingResult>

If you're interested I have a small patch that contains a fix for the problem and some test cases.

DynamicEndpointUriResolver - Suggestion for query param syntax

Hi,

The current syntax for dynamically adding query params for HTTP request is

        <header>
            <element name="citrus_query_params" value="param1=value1,param2=value2" />
        </header>

which will resolve to something like http://localhost:8080/test?param1=value1&param2=value2

I have a use case where the query param value itself contains a comma. With the current setup, that use case is not supported. In line 111 of DynamicEndpointUriResolver.java, if the StringTokenizer delimiter can be changed to '&', I guess it can support all use cases.

Thanks!

AbstractJUnitTest class has TestNG dependency

In the 1.2-SNAPSHOT release there is a testNG dependency in the code of the 'AbstractJUnit4CitrusTest' class.
This is annoying since I choose to use Junit and still have to add the testNG dependency to my pom.
In line '130' of the file there is used an 'org.testng.Assert' which can be replaced quite easily for a Junit assertions or a commons Assert I would think.

Message payload lost for Http PATCH method

When sending a message with httpClient using Http PATCH method the message payload is not added to the request properly. The payload is simply ignored. Also on httpServer component incoming Http PATCH method requests are not handled.

Citrus setup using Ant

I am new to citrus framework and trying to have a basic setup. I followed the steps mentioned in tutorial http://www.citrusframework.org/tutorials-ant.html
I tried running citrus with ant but everytime i am getting below error
c:...\build.xml:47: java.lang.NoSuchMethodException: com.consol.citrus.Citrus.main([Ljava.lang.String;)
at java.lang.Class.getMethod(Class.java:1670)
at org.apache.tools.ant.taskdefs.ExecuteJava.execute(ExecuteJava.java:142)
at org.apache.tools.ant.taskdefs.Java.run(Java.java:771)
at org.apache.tools.ant.taskdefs.Java.executeJava(Java.java:221)
at org.apache.tools.ant.taskdefs.Java.executeJava(Java.java:135)
at org.apache.tools.ant.taskdefs.Java.execute(Java.java:108)
at com.consol.citrus.ant.CitrusAntTask.execute(CitrusAntTask.java:79)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
at org.apache.tools.ant.Task.perform(Task.java:348)
at org.apache.tools.ant.Target.execute(Target.java:435)
at org.apache.tools.ant.Target.performTasks(Target.java:456)
at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393)
at org.apache.tools.ant.Project.executeTarget(Project.java:1364)
at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
at org.apache.tools.ant.Project.executeTargets(Project.java:1248)
at org.apache.tools.ant.Main.runBuild(Main.java:851)
at org.apache.tools.ant.Main.startAnt(Main.java:235)
at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)

List of jars included in my lib folder
activation-1.1.1.jar
antlr-2.7.7.jar
aopalliance-1.0.jar
asm-4.0.jar
asm-analysis-4.0.jar
asm-commons-4.0.jar
asm-tree-4.0.jar
asm-util-4.0.jar
bsh-2.0b4.jar
citrus-ant-tasks-2.1.jar
citrus-core-2.1.jar
citrus-http-2.1.jar
citrus-java-dsl-2.1.jar
citrus-jms-2.1.jar
citrus-model-core-2.1.jar
citrus-model-http-2.1.jar
citrus-model-jms-2.1.jar
citrus-model-ws-2.1.jar
citrus-ws-2.1.jar
com.springsource.javax.jms-1.1.0.jar
commons-cli-1.2.jar
commons-codec-1.9.jar
commons-httpclient-3.0.1.jar
commons-io-2.4.jar
commons-lang-2.6.jar
commons-logging-1.1.3.jar
commons-logging-api-1.1.jar
FastInfoset-1.2.12.jar
groovy-2.1.0.jar
groovy-json-2.1.0.jar
groovy-jsr223-2.1.0.jar
groovy-xml-2.1.0.jar
hamcrest-core-1.3.jar
httpclient-4.3.5.jar
httpcore-4.3.2.jar
istack-commons-runtime-2.16.jar
javax.servlet-3.0.0.v201112011016.jar
javax.xml.soap-api-1.3.5.jar
jaxb-api-2.2.7.jar
jaxb-core-2.2.7.jar
jaxb-impl-2.2.7.jar
jcl-over-slf4j-1.7.7.jar
jcommander-1.27.jar
jdom-1.0.jar
jetty-continuation-8.1.16.v20140903.jar
jetty-http-8.1.16.v20140903.jar
jetty-io-8.1.16.v20140903.jar
jetty-security-8.1.16.v20140903.jar
jetty-server-8.1.16.v20140903.jar
jetty-servlet-8.1.16.v20140903.jar
jetty-util-8.1.16.v20140903.jar
json-simple-1.1.1.jar
jsr173_api-1.0.jar
jtidy-r938.jar
junit-4.11.jar
log4j-1.2.17.jar
mimepull-1.9.jar
rome-1.0.0.jar
rome-fetcher-1.0.0.jar
saaj-impl-1.3.23.jar
serializer-2.7.2.jar
slf4j-api-1.7.7.jar
slf4j-log4j12-1.7.2.jar
snakeyaml-1.6.jar
spring-aop-4.0.7.RELEASE.jar
spring-beans-4.0.7.RELEASE.jar
spring-context-4.0.7.RELEASE.jar
spring-core-4.0.7.RELEASE.jar
spring-expression-4.0.7.RELEASE.jar
spring-integration-core-4.0.4.RELEASE.jar
spring-integration-http-4.0.4.RELEASE.jar
spring-integration-jms-4.0.4.RELEASE.jar
spring-jdbc-4.0.7.RELEASE.jar
spring-jms-4.0.7.RELEASE.jar
spring-messaging-4.0.7.RELEASE.jar
spring-oxm-4.0.7.RELEASE.jar
spring-retry-1.1.1.RELEASE.jar
spring-test-4.0.7.RELEASE.jar
spring-tx-4.0.7.RELEASE.jar
spring-web-4.0.7.RELEASE.jar
spring-webmvc-4.0.7.RELEASE.jar
spring-ws-core-2.2.0.RELEASE.jar
spring-xml-2.2.0.RELEASE.jar
stax-api-1.0-2.jar
stax-ex-1.7.4.jar
testng-6.8.jar
wsdl4j-1.6.3.jar
xalan-2.7.2.jar
xercesImpl-2.11.0.jar
xml-apis-1.4.01.jar

Problem in acknowledgement received after sending the HTTP request

Hi,

I am using Citrus for testing HTTP interface of my application.
I am using "citrus:http-message-sender" along with "send" action in test XML. This send action waits for the HTTP 200 code from the server to verify the success/failure of message send.
What happens is when the response returns from my application, the HTTP header extraction takes place in HttpMessageSender class (code snippet from the class)

 Map<String, ?> httpResponseHeaders = headerMapper.toHeaders(response.getHeaders());     
     Map<String, String> customHeaders = new HashMap<String, String>();
     for (Entry<String, List<String>> header : response.getHeaders().entrySet()) {
        if (!httpResponseHeaders.containsKey(header.getKey())) {
            customHeaders.put(header.getKey(), StringUtils.collectionToCommaDelimitedString(header.getValue()));
        }
     }

Now this, "response.getHeaders()" is giving an exception "Cannot parse date value "0" for expires header " because of the value set by my application in the Expires header.

So can I somehow control this HTTP header extraction to only check certain mandatory HTTP headers and ignore others? As I just want to validate if the HTTP 200 code is returned or not and I don't want the validation of headers like expires.

Mail XML Import name space error

XML payload representation for a mail message does not have any namespace. When using the payload element with test-case XSD a namespace other than Citrus is required. This breaks the combination of mail-message XML representation and nested XML payload feature in a test case.

MailServer stops on emtpy line

Problem

In one of my tests I use the citurs mail server. However, there seems to be problem when the e-mail contains an empty line. The e-mail I get from citrus for verification is cut off at the first empty line.

Example

My e-mail:

Hello,

how are you?

Regards,

Me

The e-mail I get from citrus:

Hello,

DataDictionary not settable via Java DSL

Explicit data dictionary is not settable via Java DSL for send and receive message builder. Should add methods to DSL for setting the data dictionary instance on builder methods.

minor bug in java action <java...>

Hi Christoph,

tried to set up the java action as described in the documentation (ver. 1.1). Ran into a NullpointerException when
configured as follows:

<method name="invoke">
    <argument type="String[]">1,2</argument>

</method>

Cant mvn install citrus with Java 1.7

Hi,

I've configured my env as it says on the readme file, setting up javahome and using java +7:

vagrant@devbox:/opt/poc/citrus$ javac -version
javac 1.7.0_91

JAVA_HOME

vagrant@devbox:/opt/poc/citrus$ echo $JAVA_HOME
/usr/lib/jvm/java-1.7.0-openjdk-amd64

$ sudo update-alternatives --config java

There is only one alternative in link group java (providing /usr/bin/java): /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java
Nothing to configure.

However the clean install still fails with problems with Jetty Java version problems:

[ERROR] ... 23 more
[ERROR] Caused by: java.lang.UnsupportedClassVersionError: org/eclipse/jetty/server/Handler : Unsupported major.minor version 52.0

Its clear for me that mvn is compiling the project with a different java version and this is causing the error scenario, however project readme instructions are clear on the point of using 1.7 and this is the one I'm currently using.

Thanks.

PrettyPrint not working as expected

The method testPrettyPrint in https://github.com/christophd/citrus/blob/master/modules/citrus-core/src/test/java/com/consol/citrus/util/XMLUtilsTest.java is not working as expected.

The output is:

   <?xml version="1.0" encoding="UTF-8"?><testRequest>
      <message>Hello</message>
   </testRequest>

and I would expect to be:

<?xml version="1.0" encoding="UTF-8"?>
<testRequest>
   <message>Hello</message>
</testRequest>

I created this Assertion:

    private static final String LINE_SEPARATOR = System.getProperty("line.separator");
    ....
    @Test
    public void testPrettyPrint() throws IOException {
        String xml = "<testRequest><message>Hello</message></testRequest>";

        StringBuilder builder = new StringBuilder();
        builder.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        builder.append(LINE_SEPARATOR);
        builder.append("<testRequest>");
        builder.append(LINE_SEPARATOR);
        builder.append("   <message>Hello</message>");
        builder.append(LINE_SEPARATOR);
        builder.append("</testRequest>");

        Assert.assertEquals(XMLUtils.prettyPrint(xml), builder.toString());
    }

citrus:randomEnumValue

sorry i write in german:

die Funktion <... value="citrus:randomEnumValue('200', '401', '500')"/> funktioniert nicht, da diese nicht bekannt ist.

Ich denke die Funktion sollte in citrus-function-ctx.xml eingetragen werden, wenn es keine Absicht war die momentan unsichtbar zu machen:

<entry key="randomEnumValue">
    <bean class="com.consol.citrus.functions.core.RandomEnumValueFunction"/>
</entry>

Der Eintrag fehlt in der Version 1.1 und in der neueren Version 1.2-SNAPSHOT.

Danke,
Eugen

Combine two variables into one causes a test failure

If one executes the following test

    @Test
    @CitrusTest
    public void test() throws SQLException {
        variable("ONE", "1");
        variable("TWO", "2");

        variable("TWELFE", "${ONE}${TWO}");
    }

he/she would get

com.consol.citrus.exceptions.CitrusRuntimeException: Unknown variable 'ONE}${TWO'
    at com.consol.citrus.context.TestContext.getVariableObject(TestContext.java:122)
    at com.consol.citrus.context.TestContext.getVariable(TestContext.java:107)
    at com.consol.citrus.context.TestContext.resolveDynamicValue(TestContext.java:261)
    at com.consol.citrus.dsl.runner.DefaultTestRunner.variable(DefaultTestRunner.java:151)
    at com.consol.citrus.dsl.junit.JUnit4CitrusTestRunner.variable(JUnit4CitrusTestRunner.java:120)
    at com.****.test.integration.ws.testcase.***.test(***.java:649)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:203)
    at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:188)
    at com.consol.citrus.dsl.junit.JUnit4CitrusTestRunner.run(JUnit4CitrusTestRunner.java:69)
    at com.consol.citrus.junit.CitrusJUnit4Runner$InvokeRunMethod.evaluate(CitrusJUnit4Runner.java:180)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:73)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:224)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

Docker action sharing docker command instance

Uncovered one minor problem in com.consol.citrus.docker.config.xml.DockerExecuteActionParser -> the same DockerCommand instance is shared across multiple docker actions of the same type. For example if a test contains multiple "build-image" actions, then the same build command instance is used across each build action; As long as the configuration is the same, then everything works ok. But if the configuration differs (different dockerfiles for example) then u got problems ;-)

Empty Http request headers missing on server receive

When receiving a Http message as server that includes an empty Http message header entry the header entry is skipped and not available for message validation in receive action. The header an be seen in Http message request log. Somehow the empty header entry must be lost in Spring message controller

PurgeJmsQueuesAction not purging all the messages on the queue

The PurgeJmsQueuesAction is not purging all the messages on the queue.
In the method purgeDestination a new messageConsumer is created every time in the do-while loop.
This should be only created once, and moved out of the do-while loop. In my implementation this consumes the only 2 - 6 messages unpredictably. When moved out of the do-while loop it consumes all the messages instantly from the queue. My implementation is done with SonicMQ broker.

The method that works well with my implementation is follows:

private void purgeDestination(Destination destination, Session session, String destinationName) throws JMSException {
    if (log.isDebugEnabled()) {
        log.debug("Try to purge queue " + destinationName);
    }
    MessageConsumer messageConsumer = null;
    try {
        javax.jms.Message message;
        messageConsumer = session.createConsumer(destination);
        do {                
            message = (receiveTimeout >= 0) ? messageConsumer
                    .receive(receiveTimeout) : messageConsumer.receive();
            if (message != null && log.isDebugEnabled()) {
                log.debug("Removed message from queue " + destinationName);
            }
        } while (message != null);
        JmsUtils.closeMessageConsumer(messageConsumer);
    } finally {
        JmsUtils.closeMessageConsumer(messageConsumer);
    }
}

Greetings.

Test : SshClientParserTest als TestNG schlägt fehl (Projekt citrus-ssh)

Hallo Christoph

wir erweitern im Moment das Testframework um einige Module und stossen im Moment auf ein Problem, das uns aufhaltet. Siehe Stacktrace unten.

Wir haben das Problem dass wenn wir XML Deklarationen erstellen wollen, dass bereits http://www.citrusframework.org/schema/config Bauchweh tut.
Spring will das citrus-context.xml nicht finden - ich bin mir da nicht so sicher ob einfach ein jar von Spring fehlt oder ob diese Abhängigkeit im Laufe des Builds bereinigt wird.

Install etc. habe ich alles gemacht...

Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.citrusframework.org/schema/config]
Offending resource: class path resource [com/consol/citrus/context/citrus-context.xml]

beste Grüsse - Magnus

Stacktrace vom Test : SshClientParserTest als TestNG direkt aus dem Module angestossen.

0 INFO t.TestContextManager| Could not instantiate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [javax/servlet/ServletContext]
[TestNG] Running:
/private/var/folders/nw/p7kcmqsj2491kpqlt29hyjbr0000gn/T/testng-eclipse-887496121/testng-customsuite.xml

234 INFO icApplicationContext| Refreshing org.springframework.context.support.GenericApplicationContext@2aca64df: startup date [Wed Jun 17 10:18:02 CEST 2015]; root of context hierarchy
331 INFO BeanDefinitionReader| Loading XML bean definitions from class path resource [com/consol/citrus/context/citrus-context.xml]
1696 WARN icApplicationContext| Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.citrusframework.org/schema/config]
Offending resource: class path resource [com/consol/citrus/context/citrus-context.xml]

at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:70)
at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:85)
at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:80)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.error(BeanDefinitionParserDelegate.java:316)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1421)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1414)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:187)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:141)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:110)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:508)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:391)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:335)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:303)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:216)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:187)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsFromImportedResources(ConfigurationClassBeanDefinitionReader.java:313)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:138)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:116)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:330)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:243)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:254)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:94)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:611)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:125)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:102)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:248)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContextInternal(CacheAwareContextLoaderDelegate.java:64)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:91)
at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:101)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:331)
at org.springframework.test.context.testng.AbstractTestNGSpringContextTests.springTestContextPrepareTestInstance(AbstractTestNGSpringContextTests.java:146)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:564)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138)
at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:175)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:107)
at org.testng.TestRunner.privateRun(TestRunner.java:767)
at org.testng.TestRunner.run(TestRunner.java:617)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
at org.testng.SuiteRunner.run(SuiteRunner.java:240)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
at org.testng.TestNG.run(TestNG.java:1057)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)

1699 ERROR t.TestContextManager| Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@20fd55cc] to prepare test instance [com.consol.citrus.ssh.config.SshClientParserTest@422cac21]
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:101)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:331)
at org.springframework.test.context.testng.AbstractTestNGSpringContextTests.springTestContextPrepareTestInstance(AbstractTestNGSpringContextTests.java:146)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:564)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138)
at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:175)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:107)
at org.testng.TestRunner.privateRun(TestRunner.java:767)
at org.testng.TestRunner.run(TestRunner.java:617)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
at org.testng.SuiteRunner.run(SuiteRunner.java:240)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
at org.testng.TestNG.run(TestNG.java:1057)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)

Grant more flexibility for the root of Citrus integration tests

Problem: One CLI accepts testdir as parameter (Citrus.java Line 171), another CLI does not and uses the default value "src/citrus/tests/" (TestCaseCreator.java Line 139):

Suggestion: Parametrize testdir and javadir in TestCaseCreator, too (actually, javadir is NOT a parameter for Citrus.java)

Better suggestion: grant more flexibility for the root of Citrus integration tests - maybe by externalizing a "testroot" property (citrusroot=src/citrus/) (or an environment variable ?) which can be replaced by a command-line value. This would be used for both the DEFAULT_TEST_DIRECTORY and DEFAULT_JAVA_DIRECTORY:
DEFAULT_CITRUS_ROOT = ... // "src/citrus/" from properties ? env var ?
DEFAULT_TEST_DIRECTORY = DEFAULT_CITRUS_ROOT+"tests/"
DEFAULT_JAVA_DIRECTORY = DEFAULT_CITRUS_ROOT+"java/"

Code illustrating the problem:
https://github.com/christophd/citrus/blob/master/modules/citrus-core/src/main/java/com/consol/citrus/Citrus.java 171:
String testDirectory = cmd.getOptionValue("testdir", CitrusConstants.DEFAULT_TEST_DIRECTORY);

https://github.com/christophd/citrus/blob/master/modules/citrus-core/src/main/java/com/consol/citrus/util/TestCaseCreator.java 139:
createFileFromTemplate(properties, CitrusConstants.DEFAULT_TEST_DIRECTORY + targetPackage + "/" + name + ".xml", getTemplateFileForXMLTest(xmlRequest != null && xmlResponse != null));

Note: similar problem for "src/citrus/java"
TestCaseCreator.java 143:
createFileFromTemplate(properties, CitrusConstants.DEFAULT_JAVA_DIRECTORY + targetPackage + "/" + name + ".java", getTemplateFileForJavaClass());

Variable extractor not working in http:receive-response XML

When using the XML DSL test cases and having a http:receive-response or http:receive-request element with variable extractor defined as http:extract elements no variables are extracted neither from message body nor message header.

Problem has already been reproduced and is because of the Citrus XML element bean definition parser not being able to handle http:extract elements correctly

XPath validation asserts only on first element of the expression result

When message reply validation is done with xpath, only the first node from a NodeList or NodeSet is validated. The xpath evaluation signature
public Object XPathExpression:evaluate(Object item, QName returnType) throws XPathExpressionException;
returns the first node in case the result is a collection.

Example: <validate path="//document/status/errorMsg" value="#ok"></validate>
Expected all document/status/errorMsg elements are tested against the expected value.

Feature Request - Support of appending nodes to XMLs prior to shipping the payload

Feature Request Description

Option to configure a data-dictionary, via the Spring bean definition, to support APPENDing a node and text, that does not exist in the payload.

Sample

Will explain it with a scenario:

Payload

<Product>
    <Name>ProductName</Name>
    <Description>Description of the product</Description>
    <Cost>10.00</Cost>
    <CountriesInStock>
        <Germany>true</Germany>
        <UnitedStates>false</UnitedStates>
        <Colombia>true</Colombia>
        <Qatar>true</Qatar>
    </CountriesInStock>
</Product>

-- This is not good XML design, and unfortunately, out in the wild, any goes.

Requirement

For testing, I would need to include the following dynamically :

<ElSalvador>
<Italy>

as 'true' within the

<CountriesInStock>

Possible Usage

Adding the tag and values via the Variables like so:

variable("ElSalvador", "true");
variable("Italy", "true");
send(action -> action.endpoint("ToThere")
.payload(new ClassPathResource(payload));

A sample context file snippet:

<citrus:xpath-data-dictionary id="xpathMappingDataDictionary">
     <citrus:mappings>
          <citrus:mapping path="//Product/Name" value="${ProductName}" />
          <citrus:mapping path="//Product/Description" value="${ProductDescription}" />
          <citrus:mapping path="//Product/Cost" value="${ProductCost}" />
          <citrus:mapping path="//CountriesInStock/Germany" value="${Germany}" />
          <citrus:mapping path="//CountriesInStock/UnitedStates" value="${UnitedStates}" />
          <citrus:mapping path="//CountriesInStock/Qatar" value="${Qatar}" />
          <citrus:mapping path="//CountriesInStock/Colombia" value="${Colombia}" />

          <citrus:mapping path="//CountriesInStock/ElSalvador" value="${ElSalvador}" append="true"/>
          <citrus:mapping path="//CountriesInStock/Italy" value="${Italy}" append="true"/>
     </citrus:mappings>
</citrus:xpath-data-dictionary>

Note the append="true" attributes which would notify Citrus to consider these special 'appendable' nodes; meaning if they do not exist, append them. False can be default.

Design Consideration

In this sample, there would be 196 entries entered into the bean definition, or located on an external file that would be referenced via citrus:mapping-file.

Conclusion

This would allow for more options to work with, in regards to the data-dictionary

Have a great day.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.