Datadog Synthetic test Support library provides a programmatic way to manage Datadog synthetic browser and mutli-step API tests. The library contains all the necessary functions that are required to manage the synthetic tests with different steps and configurations.
Synthetic Test Support library builds up on top of the Datadog's API Java client library and provides Kotlin implementation of functions to create and edit synthetic tests.
There are 2 ways to provide the API credentials to communicate with Datadog API:
- fetching from the environment variables: DD_API_KEY and DD_APP_KEY
- fetching from AWS Secrets Manager
There are some variables like Datadog API host, library and default test settings that need to be configured in order to have the Synthetic Test library up and running. Follow the steps below to setup your configuration:
- Copy the file
configuration.yaml.sample
into theresources
folder in your source set. - Rename the file to
configuration.yaml
. - Update the variables in the file with your own specifications or specify the environment variables (and optionally default values to use when variables are not set using
${<VAR_NAME>:-<default-value>}
syntax). If the datadogCredentialsAwsArn is set in the configuration, the library will default to using the AWS Secrets Manager to fetch Datadog API credentials, alternatively ddApiKey and ddAppKey need to be provided in the configuration.
You can use AWS Secrets Manager to store and fetch Datadog API credentials to enable the library to publish the test changes to Datadog.
You need to include an additional AWS package dependency, depending on how you login to AWS:
- if you use AWS SSO, please add
software.amazon.awssdk:sso
dependency - if you use AWS STS, please add
software.amazon.awssdk:sts
dependency
Please check the currently supported AWS SDK version in build.gradle.kts
.
This library is compiled with JDK 17. Your project should be on JDK 17+ to use it.
Start using the library in a gradle project by following the steps below:
- In the gradle project, add a new source set and Gradle task to run test generation in
build.gradle.kts
file.
sourceSets {
create("syntheticTest")
}
task("publishSyntheticTests", JavaExec::class) {
group = "syntheticTest"
mainClass.set("<yourPackageName>.<kotlinFileWithMainClass>")
classpath = sourceSets["syntheticTest"].runtimeClasspath
}
val syntheticTestImplementation: Configuration by configurations
- Add dependencies:
dependencies {
// check out https://github.com/personio/datadog-synthetic-test-support/releases to get the latest version
syntheticTestImplementation("com.personio:datadog-synthetic-test-support:x.x.x")
// check out https://github.com/JetBrains/kotlin/releases to get the latest version
syntheticTestImplementation("org.jetbrains.kotlin:kotlin-stdlib:x.x.x")
}
-
Setup configuration as described in the Configuration section.
-
Implement your synthetic browser tests, for example like this:
fun `add a synthetic test`() {
syntheticBrowserTest("Test Login to the app") {
tags(listOf("env:qa"))
baseUrl(URL("https://synthetic-test.personio.de"))
browserAndDevice(SyntheticsDeviceID.CHROME_LAPTOP_LARGE)
publicLocation(Location.FRANKFURT_AWS)
testFrequency(5.minutes)
retry(1, 600.milliseconds)
useGlobalVariable("PASSWORD")
inputTextStep(
stepName = "Enter username",
targetElement = TargetElement("[name='email']"),
text = "[email protected]"
)
inputTextStep(
stepName = "Enter password",
targetElement = TargetElement("[name='password']"),
text = "{{ PASSWORD }}"
)
clickStep(
stepName = "Click login button",
targetElement = TargetElement("[name='login']")
) {
waitBeforeDeclaringStepAsFailed(30.seconds)
}
pageContainsTextAssertion(
stepName = "Check Welcome title",
expectedText = "Welcome"
)
}
}
- Implement your synthetic mutli-step API tests, for example like this:
fun `add a multi-step API synthetic test`() {
syntheticMultiStepApiTest("Test Login to the app") {
env("qa")
team("team-one")
status(SyntheticsTestPauseStatus.LIVE)
publicLocations(Location.FRANKFURT_AWS)
testFrequency(5.minutes)
retry(1, 600.milliseconds)
useGlobalVariable("PASSWORD")
steps {
step("Do http request") {
request {
url("https://synthetic-test.personio.de")
method(RequestMethod.POST)
bodyType(SyntheticsTestRequestBodyType.APPLICATION_JSON)
body(
"""
{
"key": "value",
}
""".trimIndent()
)
headers(
mapOf(
"Content-Type" to "application/json"
)
)
assertions {
statusCode(200)
bodyContainsJsonPath("\$.success", "true")
bodyContains("employee_id")
headerContains("set-cookie", "cookie_name")
}
extract("COOKIE_VARIABLE") {
headerRegex("set-cookie", "(?<=cookie_name\\=)[^;]+(?=;)")
}
}
}
}
}
}
- Create a new kotlin file with the
main
function and call the function created in Steps 4-5 to publish the tests, for example like this:
fun main() {
`add a synthetic test`()
`add a multi-step API synthetic test`()
}
- To publish the tests to Datadog, use the following command:
./gradlew publishSyntheticTests
Note:
- Test name is a unique identifier which is used during test publishing. If a test with the given name already exists in Datadog, it will be overwritten.
The following are some useful commands for working with the project.
- Run
./gradlew build
to build the whole project. - Run
./gradlew ktlintFormat
to format the project. - Run
./gradlew test
to execute all the unit tests. - Run
./gradlew e2eTest
to execute the e2e test. - Run
./gradlew publishToMavenLocal
to publish to your local .m2 repository.
A new version will be released each time there are some crucial changes or a bunch of useful improvements.
Release process is handled by the Code owners. After the release workflow is triggered, a new version is automatically published to Maven Central.
The list of releases is available on the Releases page. Each release contains the list of changes from the Changelog file corresponding to the release version and zipped repository files.
This repository maintains a separate log for each change. Refer to CHANGELOG.md
for changes to the datadog-synthetic-test-support
library. Ensure that the CHANGELOG.md
file has been updated to include the new version's changes & additions.
This project adheres to Semantic Versioning and the format is partially based on Keep a Changelog with customised sections: Breaking changes, New features & improvements, Bug fixes, Dependencies.
Feel free to contribute! Just create a new issue or a new pull request following the Contributing Guidelines.
The library is licensed under the MIT License, copyright 2023 Personio SE & Co. KG.