Search code examples
pythonpython-behave

Ambiguous Step exception shown for different step names in python behave


I have two different python file under steps directory: driverlogon.py and triplogon.py

driverlogon.py defines the step

@when(u'enter the {driver_id}')
def step_enter_the_driver_id(context,driver_id):
    SelectDriver.input_driver(driver_id)

triplogon.py defines the step

@when(u'enter the configured block number')
def step_enter_the_configured_block_number(context):
    ByBlock.enter_block(context.block)

when I run this program, I get the following error message
in this case they have different text and even the content of the function is different.
why is it happening, can anyone help me to understand this? Thanks in advance

Exception AmbiguousStep: @when('enter the configured block number') has already been defined in
  existing step @when('enter the {driver_id}') at steps/driverlogon.py:26
Traceback (most recent call last):
  File "C:\Program Files (x86)\Python\Lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "C:\Program Files (x86)\Python\Lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Program Files (x86)\Python\Scripts\behave.exe\__main__.py", line 7, in <module>
  File "c:\program files (x86)\python\lib\site-packages\behave\__main__.py", line 183, in main
    return run_behave(config)
  File "c:\program files (x86)\python\lib\site-packages\behave\__main__.py", line 127, in run_behave
    failed = runner.run()
  File "c:\program files (x86)\python\lib\site-packages\behave\runner.py", line 804, in run
    return self.run_with_paths()
  File "c:\program files (x86)\python\lib\site-packages\behave\runner.py", line 809, in run_with_paths
    self.load_step_definitions()
  File "c:\program files (x86)\python\lib\site-packages\behave\runner.py", line 796, in load_step_definitions
    load_step_modules(step_paths)
  File "c:\program files (x86)\python\lib\site-packages\behave\runner_util.py", line 412, in load_step_modules
    exec_file(os.path.join(path, name), step_module_globals)
  File "c:\program files (x86)\python\lib\site-packages\behave\runner_util.py", line 386, in exec_file
    exec(code, globals_, locals_)
  File "steps\triplogon.py", line 23, in <module>
    @when(u'enter the configured block number')
  File "c:\program files (x86)\python\lib\site-packages\behave\step_registry.py", line 92, in wrapper
    self.add_step_definition(step_type, step_text, func)
  File "c:\program files (x86)\python\lib\site-packages\behave\step_registry.py", line 58, in add_step_definition
    raise AmbiguousStep(message % (new_step, existing_step))
behave.step_registry.AmbiguousStep: @when('enter the configured block number') has already been defined in
  existing step @when('enter the {driver_id}') at steps/driverlogon.py:26

Solution

  • As a solution if you want to keep these names you could write:

    driverlogon.py

    @when(u'enter the "{driver_id}"')
    def step_enter_the_driver_id(context,driver_id):
         SelectDriver.input_driver(driver_id)
    

    triplogon.py

    @when(u'enter the configured block number') 
    def step_enter_the_configured_block_number(context):
       ByBlock.block_data(context.block)
    

    Exception will not be raised in this case, but the driver_id will be passed as string and step is going to look like the following:

    When enter the "10"

    But, if you would like it to be parsed as int instead you can use predefined data types d in this case like below:

    @when(u'enter the "{driver_id:d}"')
    def step_enter_the_driver_id(context,driver_id):
         SelectDriver.input_driver(driver_id)
    

    https://behave.readthedocs.io/en/latest/parse_builtin_types.html