Type Definition Basics

Workflow

Preparation/setup phase:

  1. The user registers a data type, for example in environment.py.

The parse module is the workhorse:

  1. The parse.Parser class matches a string for a data type.

  2. Then it calls the type-converter function to convert the matched text into an object of this data type.

Simple Example

The following example shows how a user-defined type can be provided.

# file:features/steps/step_tutorial10.py
# ----------------------------------------------------------------------------
# USER-DEFINED TYPES:
# ----------------------------------------------------------------------------
from behave import register_type

def parse_number(text):
    """
    Convert parsed text into a number.
    :param text: Parsed text, called by :py:meth:`parse.Parser.parse()`.
    :return: Number instance (integer), created from parsed text.
    """
    return int(text)
# -- REGISTER: User-defined type converter (parse_type).
register_type(Number=parse_number)

See also

Tutorial 10: User-defined Data Type for more information on this example.

Example with Regular Expression Pattern

For better matching of user-defined data types, the parse supports an optional pattern attribute for type-converter functions. If this attribute is provided, it contains a textual regular expression for this data type. This regular expression pattern is used to match the data type.

The regular expression pattern can be defined by using the parse.with_pattern() function decorator:

# file:step_matcher.features/steps/step_optional_part.py
# ------------------------------------------------------------------------
# USER-DEFINED TYPES:
# ------------------------------------------------------------------------
from behave import register_type
import parse

@parse.with_pattern(r"a\s+")
def parse_word_a(text):
    """Type converter for "a " (followed by one/more spaces)."""
    return text.strip()

register_type(a_=parse_word_a)

# -- NEEDED-UNTIL: parse_type.cfparse.Parser is used by behave.
# from parse_type import TypeBuilder
# parse_opt_word_a = TypeBuilder.with_optional(parse_word_a)
# type_dict = {"a_?": parse_opt_word_a}
# register_type(**type_dict)


or by assigning the pattern attribute, like:

parse_word_a.pattern = r"a\s+"