3.9. Step - 06 : Hooks

Let’s add some hooks to features/environment.py

# environment.py


import libmath

DEBUG = True

# Environmental Controls
#
# The environment.py module may define code to run before and after certain
# events during your testing:

# before_all(context), after_all(context)
#   These run before and after the whole shooting match.

# before_feature(context, feature), after_feature(context, feature)
#   These run before and after each feature file is exercised.

# before_scenario(context, scenario), after_scenario(context, scenario)
#   These run before and after each scenario is run.

# before_step(context, step), after_step(context, step)
#   These run before and after every step.

# before_tag(context, tag), after_tag(context, tag)
#   These run before and after a section tagged with the given name. They are
#   invoked for each tag encountered in the order they're found in the feature
#   file. See controlling things with tags.

def before_all(context):
    if DEBUG:
        print("DEBUG: before_all")

def after_all(context):
    if DEBUG:
        print("DEBUG: after_all")

def before_feature(context, feature):
    if DEBUG:
        print("DEBUG: before_feature %s"%feature)

def after_feature(context, feature):
    if DEBUG:
        print("DEBUG: after_feature %s"%feature)

def before_scenario(context, scenario):
    """ Let's start with a new clean object before every test. """
    if DEBUG:
        print("DEBUG: before_scenario")
        context.math = libmath.libMath()

def after_scenario(context, scenario):
    if DEBUG:
        print("DEBUG: after_scenario")

def before_step(context, step):
    # It's called but not shown without --no-capture
    # https://github.com/behave/behave/issues/653
    if DEBUG:
        print("DEBUG: before_step '%s'\n"%step)

def after_step(context, step):
    # It's called but not shown without --no-capture
    # https://github.com/behave/behave/issues/653
    if DEBUG:
        print("DEBUG: after_step '%s'\n"%step)

def before_tag(context, tag):
    if DEBUG:
        print("DEBUG: before_tag '%s'"%tag)

def after_tag(context, tag):
    if DEBUG:
        print("DEBUG: after_tag '%s'"%tag)

We have to run behave with --no-capture, so that console output from before_step and after_step are also shown:

behave --no-color --no-timings --no-capture --no-source

The output of the command is as follows:

DEBUG: before_all
DEBUG: before_feature <Feature "Simple Addition": 2 scenario(s)>
Feature: Simple Addition
  Showcase simple addition for the BDD Book.DEBUG: before_scenario

  Scenario: Addition of single digit numbers 
    Given I have '1' and '3'
DEBUG: before_step '<given "I have '1' and '3'">'

DEBUG: after_step '<given "I have '1' and '3'">'

    When I add them
DEBUG: before_step '<when "I add them">'

DEBUG: after_step '<when "I add them">'

    Then The result must be '4'
DEBUG: before_step '<then "The result must be '4'">'

DEBUG: after_step '<then "The result must be '4'">'

DEBUG: after_scenario
DEBUG: before_scenario

  Scenario: Addition of double digit numbers 
    Given I have '70' and '29'
DEBUG: before_step '<given "I have '70' and '29'">'

DEBUG: after_step '<given "I have '70' and '29'">'

    When I add them
DEBUG: before_step '<when "I add them">'

DEBUG: after_step '<when "I add them">'

    Then The result must be '99'
DEBUG: before_step '<then "The result must be '99'">'

DEBUG: after_step '<then "The result must be '99'">'

DEBUG: after_scenario
DEBUG: after_feature <Feature "Simple Addition": 2 scenario(s)>

DEBUG: before_feature <Feature "Tabulated maths": 1 scenario(s)>
Feature: Tabulated maths
DEBUG: before_scenario

  Scenario Outline: Addition from a table -- @1.1  
    Given I have '1' and '2'
DEBUG: before_step '<given "I have '1' and '2'">'

DEBUG: after_step '<given "I have '1' and '2'">'

    When I add them
DEBUG: before_step '<when "I add them">'

DEBUG: after_step '<when "I add them">'

    Then The result must be '3'
DEBUG: before_step '<then "The result must be '3'">'

DEBUG: after_step '<then "The result must be '3'">'

DEBUG: after_scenario
DEBUG: before_scenario

  Scenario Outline: Addition from a table -- @1.2  
    Given I have '10' and '20'
DEBUG: before_step '<given "I have '10' and '20'">'

DEBUG: after_step '<given "I have '10' and '20'">'

    When I add them
DEBUG: before_step '<when "I add them">'

DEBUG: after_step '<when "I add them">'

    Then The result must be '30'
DEBUG: before_step '<then "The result must be '30'">'

DEBUG: after_step '<then "The result must be '30'">'

DEBUG: after_scenario
DEBUG: before_scenario

  Scenario Outline: Addition from a table -- @1.3  
    Given I have '22' and '33'
DEBUG: before_step '<given "I have '22' and '33'">'

DEBUG: after_step '<given "I have '22' and '33'">'

    When I add them
DEBUG: before_step '<when "I add them">'

DEBUG: after_step '<when "I add them">'

    Then The result must be '55'
DEBUG: before_step '<then "The result must be '55'">'

DEBUG: after_step '<then "The result must be '55'">'

DEBUG: after_scenario
DEBUG: before_scenario

  Scenario Outline: Addition from a table -- @1.4  
    Given I have '22' and '33'
DEBUG: before_step '<given "I have '22' and '33'">'

DEBUG: after_step '<given "I have '22' and '33'">'

    When I add them
DEBUG: before_step '<when "I add them">'

DEBUG: after_step '<when "I add them">'

    Then The result must be '55'
DEBUG: before_step '<then "The result must be '55'">'

DEBUG: after_step '<then "The result must be '55'">'

DEBUG: after_scenario
DEBUG: after_feature <Feature "Tabulated maths": 1 scenario(s)>

DEBUG: after_all
2 features passed, 0 failed, 0 skipped
6 scenarios passed, 0 failed, 0 skipped
18 steps passed, 0 failed, 0 skipped, 0 undefined
Took 0m0.001s

3.10. Changes

As compared to previous section Step - 05 : Tabulated entries, the changes in files is:

diff '--unified=3' --new-file --ignore-all-space --text --recursive --show-c-function --report-identical-files old/features/environment.py new/features/environment.py
--- old/features/environment.py	2022-12-11 00:00:00.000000000 +0530
+++ new/features/environment.py	2022-12-11 00:00:00.000000000 +0530
@@ -1,7 +1,74 @@
 # environment.py
 
+
 import libmath
 
+DEBUG = True
+
+# Environmental Controls
+#
+# The environment.py module may define code to run before and after certain
+# events during your testing:
+
+# before_all(context), after_all(context)
+#   These run before and after the whole shooting match.
+
+# before_feature(context, feature), after_feature(context, feature)
+#   These run before and after each feature file is exercised.
+
+# before_scenario(context, scenario), after_scenario(context, scenario)
+#   These run before and after each scenario is run.
+
+# before_step(context, step), after_step(context, step)
+#   These run before and after every step.
+
+# before_tag(context, tag), after_tag(context, tag)
+#   These run before and after a section tagged with the given name. They are
+#   invoked for each tag encountered in the order they're found in the feature
+#   file. See controlling things with tags.
+
+def before_all(context):
+    if DEBUG:
+        print("DEBUG: before_all")
+
+def after_all(context):
+    if DEBUG:
+        print("DEBUG: after_all")
+
+def before_feature(context, feature):
+    if DEBUG:
+        print("DEBUG: before_feature %s"%feature)
+
+def after_feature(context, feature):
+    if DEBUG:
+        print("DEBUG: after_feature %s"%feature)
+
 def before_scenario(context, scenario):
     """ Let's start with a new clean object before every test. """
+    if DEBUG:
+        print("DEBUG: before_scenario")
     context.math = libmath.libMath()
+
+def after_scenario(context, scenario):
+    if DEBUG:
+        print("DEBUG: after_scenario")
+
+def before_step(context, step):
+    # It's called but not shown without --no-capture
+    # https://github.com/behave/behave/issues/653
+    if DEBUG:
+        print("DEBUG: before_step '%s'\n"%step)
+
+def after_step(context, step):
+    # It's called but not shown without --no-capture
+    # https://github.com/behave/behave/issues/653
+    if DEBUG:
+        print("DEBUG: after_step '%s'\n"%step)
+
+def before_tag(context, tag):
+    if DEBUG:
+        print("DEBUG: before_tag '%s'"%tag)
+
+def after_tag(context, tag):
+    if DEBUG:
+        print("DEBUG: after_tag '%s'"%tag)
Files old/features/simple-addition.feature and new/features/simple-addition.feature are identical
Files old/features/steps/steps_addition.py and new/features/steps/steps_addition.py are identical
Files old/features/table-addition.feature and new/features/table-addition.feature are identical
Files old/libmath.py and new/libmath.py are identical