Description: amp-cucumber-cpp-runner is a cucumber runner that provides a C++ interface for cucumber tests. amp-cucumber-cpp-runner is to be consumed as a library project as it does not provide an executable of itself.
amp-cucumber-cpp-runner requires:
- A recent C++ compiler that supports C++20. (Ranges library required)
- CMake 3.24 or higher
amp-cucumber-cpp-runner is known to build using:
- Linux gcc-12
- Linux clang-16
- Linux clang-cl-16 (targeting Windows with WinSDK 2022 downloaded through xwin)
amp-cucumber-cpp-runner is not supposed to be used standalone. It is possible to add amp-cucumber-cpp-runner as a submodule to your own project or to use cmake's FetchContent to add amp-cucumber-cpp-runner as a cmake build dependency.
En example project is provided which shows most features of amp-cucumber-cpp-runner and how to configure a cmake project to use amp-cucumber-cpp-runner. The simplest solution is to simply add a dependency on cucumber-cpp-runner like so:
FetchContent_Declare(cucumber_cpp
GIT_REPOSITORY https://github.com/philips-software/amp-cucumber-cpp-runner.git
GIT_TAG main
)
FetchContent_MakeAvailable(cucumber_cpp)
add_executable(my_test_runner)
target_sources(my_test_runner PRIVATE
steps/mysteps.cpp
hooks/myhooks.cpp
)
target_link_libraries(my_test_runner PRIVATE
cucumber_cpp.runner
)Steps are written using the GIVEN, WHEN, THEN or STEP macro's. The syntax for step definitions is:
// using cucumber expressions
STEP("cucumber expression without captures"){
// body
}
STEP("cucumber expression with an {int}", (std::int32_t arg)){
// body
}
// or as a regular expression:
STEP(R"(^a regular\?? expression without captures$)"){
}
STEP(R"(^a (regular|unregular) expression with ([1-2]) capture groups$)", (const std::string& type, const std::string& nrOfGroups)){
}The argument list has to match with the cucumber expression type:
| Cucumber Expression | Parsed as | Notes |
|---|---|---|
{int} |
std::int32_t |
|
{float} |
float |
|
{word} |
std::string |
words without whitespace |
{string} |
std::string |
"banana split" or 'banana split' |
{} |
std::string |
|
{bigdecimal} |
double |
non-standard |
{biginteger} |
std::int64_t |
non-standard |
{byte} |
std::int8_t |
|
{short} |
std::int16_t |
|
{long} |
std::int64_t |
|
{double} |
double |
See the Cucumber Expressions documentation for more details on supported types. amp-cucumber-cpp-runner has full support for cucumber expressions.
ℹ️ except for biginteger, but it's optional
There is also support for custom parameter types. They are written and used like:
struct Flight
{
std::string from;
std::string to;
};
PARAMETER(Flight, "flight", "([A-Z]{3})-([A-Z]{3})", true)
{
return { group.children[0].value.value(), group.children[1].value.value() };
}
STEP(R"({flight} has been delayed)", (const Flight& flight))
{
EXPECT_THAT(flight.from, testing::StrEq("LHR"));
EXPECT_THAT(flight.to, testing::StrEq("CDG"));
}The PARAMETER macro API is as follows:
PARAMETER(<return type>, <name>, <regular expression>, <use for snippets>)
ℹ️ <use for snippets> is not supported yet
The PARAMETER function body receives an const cucumber::messages::group& group as argument.
amp-cucumber-cpp-runner has support for custom base classes for step definitions using the GIVEN_F, WHEN_F, THEN_F or STEP_F macros. These give additional flexibility for re-using common patterns for steps. For example:
struct LoadMeOnConstruction
{
void Tadaa() const
{}
};
struct CustomFixture : cucumber_cpp::library::engine::Step
{
using Step::Step;
const LoadMeOnConstruction& alwaysAvailable{ context.Get<LoadMeOnConstruction>() };
};
GIVEN_F(CustomFixture, R"(a custom fixture background step)")
{
alwaysAvailable.Tadaa();
}amp-cucumber-cpp-runner uses GoogleTest and GoogleMock as the basis for the assertion framework. For example:
STEP(R"(the value should be {string})", (const std::string& expected_value))
{
const auto& actual = context.Get<std::string>("cell");
ASSERT_THAT(actual, testing::StrEq(expected_value));
}ℹ️ amp-cucumber-cpp-runner has been configured to throw on a failed
ASSERT_'s. However, failedEXPECT_'s continue execution.
If asserting (or expecting) is not an option then it is also safe to throw exceptions.
Hooks are executed in order of appearance (reverse for AFTER hooks), sorted by filename and line number. If any before hook is executed then all after hooks are also executed. Even if a before hook has a failure.
API:
// HOOK_BEFORE_ALL and HOOK_AFTER_ALL have optional name and order arguments
// BEFORE_ALL hooks are executed before any test is executed
HOOK_BEFORE_ALL(){}
HOOK_BEFORE_ALL(.name = "Custom Name", .order = -1){}
// AFTER_ALL hooks are executed after all tests have executed
HOOK_AFTER_ALL(.name = "Custom After All hook"){}
HOOK_AFTER_ALL(.order = 10){}
// All other hooks have an additional optional (tag) expression argument
// HOOK_BEFORE_FEATURE (non-standard) executes before the first scenario per feature file
HOOK_BEFORE_FEATURE(){}
HOOK_BEFORE_FEATURE("@smoke", "custom name", 10){}
// HOOK_AFTER_FEATURE (non-standard) executes after the last scenario per feature file
HOOK_AFTER_FEATURE(.expression = "@dummy"){}
HOOK_AFTER_FEATURE(.name = "after feature name"){}
// HOOK_BEFORE_SCENARIO and HOOK_AFTER_SCENARIO are executed before and after every scenario.
HOOK_BEFORE_SCENARIO(){}
HOOK_AFTER_SCENARIO(){}
// HOOK_BEFORE_SCENARIO and HOOK_AFTER_SCENARIO are executed before and after every step.
HOOK_BEFORE_STEP(){}
HOOK_AFTER_STEP(){}# executes all tests in the ./feature folder using the default summary formatter
$ example
# executes all tests in the ./feature folder using the prety formatter
$ example --format pretty
# executes all tests in the ./feature folder redirecting the pretty formatter to output.txt
$ example --format pretty:output.txt
# executes all tests in the ./feature folder redirecting the pretty formatter to output.txt. Also prints the pretty formatter to the console
$ example --format pretty:output.txt pretty
# executes all tests in the ./feature folder redirecting the pretty formatter to output.txt. Also prints the pretty formatter to the console. Sets the theme for all pretty formatters to plain
$ example --format pretty:output.txt pretty --format-options "{ \"pretty\": {\"theme\" : \"plain\"} }"
# executes all tests in the ./feature/acceptance and ./feature/integration folders using the prety formatter
$ example --format pretty -- ./feature/acceptance ./feature/integration
# executes all tests matching the exact tag expression in the ./feature/acceptance and ./feature/integration folders
$ example --format pretty --tags @smoke and not @ignore -- ./feature/acceptance ./feature/integration
# On windows you might need to enclose the tags in quotes:
$ example --format pretty --tags "@smoke and not @ignore" -- ./feature/acceptance ./feature/integrationℹ️ use --help to see all available arguments and options
amp-cucumber-cpp-runner uses semantic versioning and conventional commits.
Please refer to our Contributing guide when you want to contribute to this project.
cmake --preset Hostcmake --build --preset Host-Debugctest --preset Host-Debug
amp-cucumber-cpp-runner is licensed under the MIT license. See LICENSE file.