We have a CICD process in place with defined set of TCs executed always for gating process. Sometimes its not needed to run all tests, instead we would like to trigger only set of TCs based on change made by developers. Our tests are cucumber based User Stories and hence we can control the test run by Tags. My idea is to parameterize cucumber.options from teamcity's maven command line parameters field and let Dev/support people define the tag as needed.
If i mention command line parameter as
-Dcucumber.options="--tags %env.test.scope%"
my mavenized project gets the value as cucumber.options = "--tags #Sanity (Assume env.test.scope value is #Sanity). If you note here closely, why am i getting opening double quote? It ruins my TestRunner and none of the tests are triggered. If i remove double quote, then i get mvn error as #Sanity is not recognized as valid goal (because of space issue between --tags and #) how to define my parameter (cucumber.options) value with space in it?
This seems to be more related to JVM (to run Maven) and -D than TeamCity. The correct way to pass the parameter would be
"-Dcucumber.options=--tags %env.test.scope%" as it should get as a single parameter to JVM and then be parsed to "cucumber.options" parameter with "--tags %env.test.scope%" value.
Related
I am trying to setup a Jenkins pipeline to trigger builds using gradle for multiple environments.My requirement is that the artifacts produced when I run gradlew clean build should produce artifacts with name indicating the environment for which the pipeline was run. Example my-application-dev.jar
The value of the environment would be selected by the user when build will be triggered.
What is the optimal way to achieve this ? Does build allow to configure any such property via command line or do I need to define a task in my build.gradle and define properties within that task for which I will pass value from command line
There are basically two ways.
The first one is to pass these naming-relevant pieces of information to the gradlew process, e.g. via -D or -P properties.
Then you need the Gradle build to be aware of these parameters and craft the artifact names it produces accordingly.
The second one is arguably better and more contained. You simply rename the artifacts produced by the gradlew command after it completes, in the Jenkinsfile. This works well if the pipeline decides what to do with these artifacts (e.g. publish to a repository) as opposed to the gradle script doing it (in which case you would most likely be better off using the first method).
I'm trying to run automation test using maven command.
my property for running a specific test is -DtestsToExecute
I can run a single test by passing the test name to this property:
mvn clean verify -DtestsToExecute=UITest
How can I run more than one test at once? I mean how can I pass more than one argument to the same property? I've tried putting comma between the different tests name, but with no success:
mvn clean verify -DtestsToExecute=UITest1,UITest2
I would like to use a property, which I defined inside my pom.xml. Now I would like to refer to this property value inside my TeamCity Build Step.
At the moment I'm only able to refer the other way around to use a TeamCity property inside Maven.
In particular I want to do a SSH Deployer with a target like url/path/%maven.output.type%/something with
<properties>
<!-- Art der Entwicklung -->
<output.type>testing</output.type>
</properties>
What I tried was to define a parameter in TeamCity but I have no idea how to define the value of this parameter.
Is there any way to use this property inside the TeamCity build?
You can run a script that will set a teamcity parameter that you can use in a another build step. Here are the build configuration settings I use:
Create a configuration parameter with an empty text value with a name used in the next step (e.g. outputType).
Add a build step, with runner type Command line:
Select to run a custom script.
In the custom script field, enter a script that will extract the value from the pom file, and tell teamcity to set it in the parameter. For example:
testing=sed -n 's:.*<output\.type>\(.*\)</output\.type>.*:\1:p' pom.xml
echo "##teamcity[setParameter name='outputType' value='$testing']"
This will set the teamcity parameter outputType with the value of an element named output.type found in the current project pom file.
In another build step, you can use that parameter in a field like, for instance, the target field:
somepath/%outputType%
How does quoting and escaping work for parameters passed to Maven plugins?
For example I want to pass multiple filenames as arguments to an application run by the Maven Exec plugin:
mvnDebug exec:java -Dexec.mainClass="Main" -Dexec.args="/path/to/file1 /path/to/file2"
But what if the paths have spaces?
I've tried using \":
-Dexec.args="\"/path/to/a file\" /path/to/file2"
and "":
-Dexec.args="""/path/to/a file"" /path/to/file2"
neither works :-(. Neither does moving the first quote before -D.
The source code for the Maven Exec plugin doesn't help me either, it receives a String[] from somewhere, but where?
Note that I must get this to work from the command line, without changes to the POM file.
You could try single quotes (') but I doubt that will work, either.
The problem is that you can have several argument elements inside the POM (hence the array in the plugin's source) but you have only a single property from the command line.
Options:
Patch the plugin and/or open a feature request to support several arguments (maybe exec.args.0, exec.args.1, exec.args.2, ...)
Create a module which depends on this project/module and where you can change the POM
Use an Ant or BASH script. I often use this approach to collect useful commands which aren't easily supported by Maven. mvn dependency:build-classpath -Dmdep.outputFile=... will give you the classpath in this case.
As a test developer using cuke4duke with maven2, I want to be able to optionally select tests by tags on the cmd line. It seems that since maven doesn't have conditionals, the 'optionally' part requires a hack.
The cucumber arg might be e.g. "--tags #firstTag". One way to implement this is to have in pom.xml
<cucumberArgs>
...
<cucumberArg>${tagargs}</cucumberArg>
</cucumberArgs>
Then the cmd line has
mvn integration-test -Dtagargs="--tags #firstTag"
This works fine when I want to define tags, but when I don't include that -D argument (i.e. not selecting by tags), I get
[INFO] No such file or directory - null (Errno::ENOENT)
A workaround is to define ${tagargs} in properties as a duplicate of a cucumber arg I already use:
<properties>
<tagargs>--strict</tagargs>
</properties>
So, worst case is I get "--strict --strict". Is such a hack the best maven is capable of?
I've managed to work around this problem using an ignored negative tag. Note I'm using cuke4duke 0.4.4.
Define a default value for your property that runs all scenarios that are NOT tagged with "ignore" (call it whatever you like).
<properties>
<tagargs>--tags=~#ignore</tagargs>
</properties>
Maven will use this property when you do not pass in a specific value on the command line. Therefore all of your scenarios will match and execute.