Behat Step argument transformations

Profile picture for user devraj

A pattern can’t automatically determine the datatype of its matches, so all method arguments coming from step definitions are passed as strings. For example:

Then 2 items added to cart

Here 2 will be treated as string by default, you can verify the same by executing below step definition:

/**
 * @Then :arg1 items added to cart
 */
public function itemsAddedToCart($arg1)
{
    echo gettype($arg1);
}

Here gettype() function which return type of different variable, will return string here. This is not a feature or limitation of Behat, but rather the inherent way string matching works. It is your responsibility to cast string arguments to integers, floats or booleans where applicable given the code you are testing. Casting arguments to specific types can be accomplished using step argument transformations.

To implement, replace arg1 with count and add following method in FeatureContext

/**
 * @Then :count items added to cart
 */
public function itemsAddedToCart($count)
{
    echo gettype($count);
}
/**
 * @Transform :count
 */
public function castStringToNumber($string)
{
    return intval($string);
}

Here intval() a php method which return the integer value of different variables. So, Step argument transformations allow you to abstract common operations performed on step definition arguments into reusable methods. In addition, these methods can be used to transform a normal string argument that was going to be used as an argument to a step definition method, into a more specific data type or an object.

Each transformation method must return a new value. This value then replaces the original string value that was going to be used as an argument to a step definition method.

Transformation methods are defined using the same annotation style as step definition methods, but instead use the @Transform keyword, followed by a matching pattern.

You can automatically cast all numeric arguments to integers with the following context class code:

/**
 * @Transform /^(\d+)$/
 */
public function castStringToNumber($string)
{
    return intval($string);
}

For now you may not be able to understand this regular expression, don't worry you can read another topic on PHP regular expression.

You can also create a transformation method that takes an incoming string argument and returns a specific object.

Tags