Question

The following Gherking test defines the desired behaviour for one of my servers:

  Scenario Outline: Calling the server with a valid JSON
     Given A GIS update server
     When I call /update with the json in the file <filename>
     Then the response status code is <status_code>
     And the response is a valid JSON
     And the response JSON contains the key status
     And the response JSON contains the key timestamp
     And the response JSON contains the key validity

  Examples:
  | filename                    | status_code |
  | valid_minimal.json          | 200         |
  | valid_minimal_minified.json | 200         |
  | valid_full.json             | 200         |
  | valid_full_minified.json    | 200         |
  | valid_full_some_nulls.json  | 200         |
  | valid_full_all_nulls.json   | 200         |

I wrote this code for unit testing a Flask server. The steps file, which interpret the Gherkin directives, open a test client and make the necessary calls and assertions:

@given(u'A GIS update server')
def step_impl(context):
    context.app = application.test_client()

The feature file is similar for unit and functional tests. The only difference is in a few steps file which would have to make HTTP calls rather than calling the test client's methods.

What's the right way to re-use this behave feature file by passing parameters to the steps file?

Was it helpful?

Solution

Expanding on Parva's comments, I suggest sending parameters via the command line which will be detected in your step definitions and adjust behaviour for unit vs functional testing (the decision of whether you separate your unit and functional tests for clarity is up to you ;).

There is an example given in the Behave documentation around Debug on error, which gives a good example of using environmental attributes in modifying the execution of your steps method:

# -- FILE: features/environment.py
# USE: BEHAVE_DEBUG_ON_ERROR=yes     (to enable debug-on-error)
from distutils.util import strtobool as _bool
import os

BEHAVE_DEBUG_ON_ERROR = _bool(os.environ.get("BEHAVE_DEBUG_ON_ERROR", "no"))

def after_step(context, step):
    if BEHAVE_DEBUG_ON_ERROR and step.status == "failed":
        # -- ENTER DEBUGGER: Zoom in on failure location.
        # NOTE: Use IPython debugger, same for pdb (basic python debugger).
        import ipdb
        ipdb.post_mortem(step.exc_traceback)

You may change that to detect a command line passed variable such as UNIT_TESTING and have it hit a different endpoint or perform alternate functionality for your tests.

OTHER TIPS

REQUIRES: behave >= 1.2.5

I think, the test stage concept should help you with your needs. It allows you to use different step implementations for different test stages.

behave --stage=functional

If your changes are minor, use the userdata concept to pass a flag to your step implementation, like:

behave -D test_stage=unit …
behave -D test_stage=functional …
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top