Configuration
Substeps uses a number of config files to be able to control environment specific settings. This can be useful for urls, usernames, passwords etc.
The config files use typesafe config, properties can be combined, reference other properties, include other config files and be overridden by environment variables. See the docs on Github for more details and examples.
Prior to v1.0.4, Substeps used .properties files for configuration, Typesafe config can also use such files albeit with less functionality compared to the .conf files. If you wish to continue using .properties files you can, pass -Dsubsteps.use.dot.properties=true
as a VM property to the tests.
In v1.1.0, the configuration of Substeps was rebuilt, still using Typesafe config, but support for .properties files was dropped. All substeps configuration is located in config files. Config previously specified in the maven pom.xml has been moved. If you’re interested, see the notes on 1.1.0 Upgrade for the reasons why.
Config files should be placed on the project classpath under src/main/resources
or src/test/resources
.
Configuration loading and resolving
This process follows a number of steps, building on standard behaviour of Typesafe config.
-
Reference.conf is loaded from any libraries (substeps and webdriver-substeps included). These are the default settings
-
Application.conf is loaded from the project and overlays reference.conf values. see typesafe docs for how to change the filename loaded at this point.
-
An environment override config file is then loaded to overlay the previous two sets, the environment is specified as an environment property (defaulting to localhost):
-Denvironment=<name of property file>
eg. -Denvironment=uat
to refer to uat.conf.
-
Finally a set of maven properties is constructed and injected in to allow maven like parameters (
${project.build.testOutputDirectory)
) to be used and expanded. -
The configuration format specifies a
baseExecutionConfig
section plus multipleexecutionConfigs
. For each iteration of execution, the executionConfig in question is extracted and used to override the baseExecutionConfig. The remaining config, plus the final executionConfig is passed to the runner to perform the actual tests. -
Sounds complicated ? maybe so.. the intention is to reduce the amount of boiler plate config that was required and maximise re-use, whilst providing the ability to tweak aspects of executions (eg. tags, timeouts, drivers).
-
The previous interfaces to the configuration have been maintained, however the actual values are lo longer held as an enum and thus can be reloaded with different values.
A typical project configuration
Most projects won’t need to override all of the possible settings, below is a typical application.conf (that also includes some keys from webdriver-substeps for illustrative purposes).
The example below has two executionConfigurations that would be executed sequentially and differ in the webdriver related keys, description and output directories
org.substeps.config {
description="Self Test Features"
checkForUncalledAndUnused=true
glossary{
excludeStepImplementationClassNames=[
"org.substeps.webdriver.TestWebdriverStepImplementations"
]
}
}
org.substeps.baseExecutionConfig {
featureFile=${project.build.testOutputDirectory}"/features"
stepImplementationClassNames=[
"com.technophobia.webdriver.substeps.impl.BaseWebdriverSubStepImplementations",
"org.substeps.webdriver.TestWebdriverStepImplementations"
]
substepsFile=${project.build.testOutputDirectory}"/substeps"
tags="@visual"
}
org.substeps.executionConfigs=[
{
dataOutputDir="1"
description="Chrome Self Test Features"
webdriver {
remote.driver.base.capability=chrome
remote.driver.version=48.0
}
},
{
dataOutputDir="2"
description="Firefox Self Test Features"
webdriver {
remote.driver.base.capability=firefox
remote.driver.version=45.0
}
nonFatalTags="fails-in-firefox"
}
]
Add your own configuration
Additional keys and values can be added to the configuration to suit your needs. If the configuration is self contained, add under a specific namespace
com.org.project{
a.b.c="21"
}
or weave into the Substeps config if configuration values has default values that can be overridden in execution configs
org.substeps.baseExecutionConfig {
com.org.project.somekey="abc"
}
org.substeps.executionConfigs=[
{
// com.org.project.somekey="abc" // inherited from the baseExecutionConfig
},
{
com.org.project.somekey="overridden"
}
]
Complete Substeps core config
Below is the full set of configuration items used by the Substeps framework combining the default reference.conf and application config files, this can be found in github
# An annotated example of Substeps config
org.substeps.config {
current {
branchname="" // automatically populated by JGit, if using git
projectversion="" // automatically populated via maven
}
description="Substeps test suite" // name of the whole test suite
executionResultsCollector="org.substeps.report.ExecutionResultsCollector"
// class responsible for collecting execution result data
jmxPort=9999 // JMX port used when Substeps run in forked mode
log.unused.uncalled=false
// when set to true, uncalled and unsued steps and step impls are logged
// can lead to spurious results if running a set of tags or specific scenarios
parameter.substitution {
enabled=true // allows ${} syntax in steps and scenarios
start="${" // token delimiters used for the expression
end="}"
normalizeValue=false // if true then values located will be converted from one charset to another
// useful when the config files contains accented characters pasted in
normalize {
from=ISO-8859-1 // the from charset
to=UTF-8 // converted to..
}
}
report {
data {
base.dir=target // legacy value to specify root location of report
pretty.print=false // pretty print report json
}
rootNodeDescriptionProvider="org.substeps.report.DefaultDescriptionProvider"
// class to describe the root level node in the report
}
reportBuilder="org.substeps.report.ReportBuilder"
// class that builds the report
reportDir="target/substeps_report"
// directory in which to build the report
rootDataDir="target/substeps-data"
// directory in which to write results into, and for the report builder to pick up from
runTestsInForkedVM=false // run the substeps in a forked VM ?
step.depth.description=6 // beyond 6 deep, the Junit runner won't render a description
glossary{
// list of step impls not to be included in the glossary - generally test step impls that might be written to aid the testing of the tests, but not shippable..
excludeStepImplementationClassNames=[
"org.substeps.webdriver.TestWebdriverStepImplementations"
]
}
}
org.substeps.baseExecutionConfig {
// all execution configs (below) inherit this config. These properties can be overriden in any of the
// executionConfigs below
executionListeners=[
// set of listeners that receive test started / passed / failed events
"com.technophobia.substeps.runner.logger.StepExecutionLogger"
]
fastFailParseErrors=true
// if true, parse failures of all scenarios and substeps result in immediate termination.
// During development it may be beneficial to relax this. Parse errors found during execution are
// still treated as an error
featureFile="target/test-classes/features"
substepsFile="target/test-classes/substeps"
stepImplementationClassNames=[
"com.org.my.StepImplementations"
]
}
org.substeps.executionConfigs=[
// an array of execution configs, each one will be executed sequentially
{
dataOutputDir="1"
// the subdir, relative to rootDataDir, where the results data from this execution config will be written
description="Set 1 Substeps tests"
// the description of this iteration
tags="set1"
// the tagged scenarios to include
nonFatalTags="set1-wip"
// tagged scenarios and features that can fail, without failing the build
},
{
dataOutputDir="2"
description="Set 2 Substeps tests"
tags="set2"
}
]