Skip to content

Commit

Permalink
EXAMPLE: Using assertpy.soft_assertions in behave
Browse files Browse the repository at this point in the history
RELATED TO:
* Discussion in #1094
  • Loading branch information
jenisys committed Apr 18, 2023
1 parent 0085ff8 commit e3d7cc7
Show file tree
Hide file tree
Showing 9 changed files with 288 additions and 1 deletion.
97 changes: 97 additions & 0 deletions examples/soft_asserts/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
EXAMPLE: Use Soft Assertions in behave
=============================================================================

:RELATED TO: `discussion #1094`_

This directory provides a simple example how soft-assertions can be used
in ``behave`` by using the ``assertpy`` package.


HINT:

* Python2.7: "@soft_assertions()" decorator does not seem to work.
Use ContextManager solution instead, like: ``with soft_assertions(): ...``


Bootstrap
-----------------------------------------------------------------------------

ASSUMPTIONS:

* Python3 is installed (or: Python2.7)
* virtualenv is installed (otherwise use: pip install virtualenv)

Create a virtual-environment with "virtualenv" and activate it::


$ python3 -mvirtualenv .venv

# -- STEP 2: Activate the virtualenv
# CASE 1: BASH-LIKE SHELL (on UNIX-like platform: Linux, macOS, WSL, ...)
$ source .venv/bin/activate

# CASE 2: CMD SHELL (on Windows)
cmd> .venv/Scripts/activate

Install the required Python packages in the virtualenv::

$ pip install -r py.requirements.txt


Run the Example
-----------------------------------------------------------------------------

::

# -- USE: -f plain --no-capture (via "behave.ini" defaults)
$ ../../bin/behave -f pretty features
Feature: Use Soft Assertions in behave # features/soft_asserts.feature:1
RELATED TO: https://github.com/behave/behave/discussions/1094
Scenario: Failing with Soft Assertions -- CASE 1 # features/soft_asserts.feature:5
Given a minimum number value of "5" # features/steps/number_steps.py:16
Then the numbers "2" and "12" are in the valid range # features/steps/number_steps.py:27
Assertion Failed: soft assertion failures:
1. Expected <2> to be greater than or equal to <5>, but was not.

But note that "the step-2 (then step) is expected to fail" # None

@behave.continue_after_failed_step
Scenario: Failing with Soft Assertions -- CASE 2 # features/soft_asserts.feature:17
Given a minimum number value of "5" # features/steps/number_steps.py:16
Then the number "4" is in the valid range # features/steps/number_steps.py:21
Assertion Failed: Expected <4> to be greater than or equal to <5>, but was not.

And the number "8" is in the valid range # features/steps/number_steps.py:21
But note that "the step-2 and step-3 are expected to fail" # ../../behave4cmd0/note_steps.py:15
But note that "the step-4 should pass" # ../../behave4cmd0/note_steps.py:15

@behave.continue_after_failed_step
Scenario: Failing with Soft Assertions -- CASE 1 and CASE 2 # features/soft_asserts.feature:28
Given a minimum number value of "5" # features/steps/number_steps.py:16
Then the number "2" is in the valid range # features/steps/number_steps.py:21
Assertion Failed: Expected <2> to be greater than or equal to <5>, but was not.

And the numbers "3" and "4" are in the valid range # features/steps/number_steps.py:27
Assertion Failed: soft assertion failures:
1. Expected <3> to be greater than or equal to <5>, but was not.
2. Expected <4> to be greater than or equal to <5>, but was not.

And the number "8" is in the valid range # features/steps/number_steps.py:21
But note that "the step-2 and step-3 are expected to fail" # ../../behave4cmd0/note_steps.py:15
But note that "the step-4 should pass" # ../../behave4cmd0/note_steps.py:15

Scenario: Passing # features/soft_asserts.feature:37
Given a step passes # ../../behave4cmd0/passing_steps.py:23
And note that "this scenario should be executed and should pass" # ../../behave4cmd0/note_steps.py:15


Failing scenarios:
features/soft_asserts.feature:5 Failing with Soft Assertions -- CASE 1
features/soft_asserts.feature:17 Failing with Soft Assertions -- CASE 2
features/soft_asserts.feature:28 Failing with Soft Assertions -- CASE 1 and CASE 2

0 features passed, 1 failed, 0 skipped
1 scenario passed, 3 failed, 0 skipped
11 steps passed, 4 failed, 1 skipped, 0 undefined

.. _`discussion #1094`: https://github.com/behave/behave/discussions/1094
15 changes: 15 additions & 0 deletions examples/soft_asserts/behave.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# =============================================================================
# BEHAVE CONFIGURATION
# =============================================================================
# FILE: .behaverc, behave.ini
#
# SEE ALSO:
# * http://packages.python.org/behave/behave.html#configuration-files
# * https://github.com/behave/behave
# * http://pypi.python.org/pypi/behave/
# =============================================================================

[behave]
default_format = pretty
stdout_capture = false
show_source = true
51 changes: 51 additions & 0 deletions examples/soft_asserts/behave_run.output_example.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# -- HINT: EXECUTE: ../../bin/behave -f pretty

Feature: Use Soft Assertions in behave # features/soft_asserts.feature:1
RELATED TO: https://github.com/behave/behave/discussions/1094
Scenario: Failing with Soft Assertions -- CASE 1 # features/soft_asserts.feature:5
Given a minimum number value of "5" # features/steps/number_steps.py:16
Then the numbers "2" and "12" are in the valid range # features/steps/number_steps.py:27
Assertion Failed: soft assertion failures:
1. Expected <2> to be greater than or equal to <5>, but was not.

But note that "the step-2 (then step) is expected to fail" # None

@behave.continue_after_failed_step
Scenario: Failing with Soft Assertions -- CASE 2 # features/soft_asserts.feature:17
Given a minimum number value of "5" # features/steps/number_steps.py:16
Then the number "4" is in the valid range # features/steps/number_steps.py:21
Assertion Failed: Expected <4> to be greater than or equal to <5>, but was not.

And the number "8" is in the valid range # features/steps/number_steps.py:21
But note that "the step-2 and step-3 are expected to fail" # ../../behave4cmd0/note_steps.py:15
But note that "the step-4 should pass" # ../../behave4cmd0/note_steps.py:15

@behave.continue_after_failed_step
Scenario: Failing with Soft Assertions -- CASE 1 and CASE 2 # features/soft_asserts.feature:28
Given a minimum number value of "5" # features/steps/number_steps.py:16
Then the number "2" is in the valid range # features/steps/number_steps.py:21
Assertion Failed: Expected <2> to be greater than or equal to <5>, but was not.

And the numbers "3" and "4" are in the valid range # features/steps/number_steps.py:27
Assertion Failed: soft assertion failures:
1. Expected <3> to be greater than or equal to <5>, but was not.
2. Expected <4> to be greater than or equal to <5>, but was not.

And the number "8" is in the valid range # features/steps/number_steps.py:21
But note that "the step-2 and step-3 are expected to fail" # ../../behave4cmd0/note_steps.py:15
But note that "the step-4 should pass" # ../../behave4cmd0/note_steps.py:15

Scenario: Passing # features/soft_asserts.feature:37
Given a step passes # ../../behave4cmd0/passing_steps.py:23
And note that "this scenario should be executed and should pass" # ../../behave4cmd0/note_steps.py:15


Failing scenarios:
features/soft_asserts.feature:5 Failing with Soft Assertions -- CASE 1
features/soft_asserts.feature:17 Failing with Soft Assertions -- CASE 2
features/soft_asserts.feature:28 Failing with Soft Assertions -- CASE 1 and CASE 2

0 features passed, 1 failed, 0 skipped
1 scenario passed, 3 failed, 0 skipped
11 steps passed, 4 failed, 1 skipped, 0 undefined
Took 0m0.001s
30 changes: 30 additions & 0 deletions examples/soft_asserts/features/environment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# -*- coding: UTF-8 -*-
# FILE: features/environment.py

from __future__ import absolute_import, print_function
import os.path
import sys


HERE = os.path.abspath(os.path.dirname(__file__))
TOP_DIR = os.path.abspath(os.path.join(HERE, "../.."))


# -----------------------------------------------------------------------------
# HOOKS:
# -----------------------------------------------------------------------------
def before_all(context):
setup_python_path()


def before_scenario(context, scenario):
if "behave.continue_after_failed_step" in scenario.effective_tags:
scenario.continue_after_failed_step = True


# -----------------------------------------------------------------------------
# SPECIFIC FUNCTIONALITY:
# -----------------------------------------------------------------------------
def setup_python_path():
# -- ENSURE: behave4cmd0 can be imported in steps-directory.
sys.path.insert(0, TOP_DIR)
39 changes: 39 additions & 0 deletions examples/soft_asserts/features/soft_asserts.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
Feature: Use Soft Assertions in behave

RELATED TO: https://github.com/behave/behave/discussions/1094

Scenario: Failing with Soft Assertions -- CASE 1

HINT:
Multiple assert statements in a step are executed even if a assert fails.
After a failed step in the Scenario,
the remaining steps are skipped and the next Scenario is executed.

Given a minimum number value of "5"
Then the numbers "2" and "12" are in the valid range
But note that "the step-2 (then step) is expected to fail"

@behave.continue_after_failed_step
Scenario: Failing with Soft Assertions -- CASE 2

HINT: If a step in the Scenario fails, execution is continued.

Given a minimum number value of "5"
Then the number "4" is in the valid range
And the number "8" is in the valid range
But note that "the step-2 is expected to fail"
But note that "the step-3 should be executed and should pass"

@behave.continue_after_failed_step
Scenario: Failing with Soft Assertions -- CASE 1 and CASE 2

Given a minimum number value of "5"
Then the number "2" is in the valid range
And the numbers "3" and "4" are in the valid range
And the number "8" is in the valid range
But note that "the step-2 and step-3 are expected to fail"
But note that "the step-4 should be executed and should pass"

Scenario: Passing
Given a step passes
And note that "this scenario should be executed and should pass"
38 changes: 38 additions & 0 deletions examples/soft_asserts/features/steps/number_steps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# -*- coding: UTF-8 -*-
# -- FILE: features/steps/number_steps.py
"""
Step-functions for soft-assertion example.
STEPS:
Given a minimum number value of "5"
Then the numbers "2" and "12" are in the valid range
And the number "4" is in the valid range
"""
from __future__ import print_function
from behave import given, when, then, step
from assertpy import assert_that, soft_assertions


@given(u'a minimum number value of "{min_value:d}"')
def step_given_min_number_value(ctx, min_value):
ctx.min_number_value = min_value


@then(u'the number "{number:d}" is in the valid range')
def step_then_number_is_valid(ctx, number):
assert_that(number).is_greater_than_or_equal_to(ctx.min_number_value)

@then(u'the numbers "{number1:d}" and "{number2:d}" are in the valid range')
@soft_assertions()
def step_then_numbers_are_valid(ctx, number1, number2):
assert_that(number1).is_greater_than_or_equal_to(ctx.min_number_value)
assert_that(number2).is_greater_than_or_equal_to(ctx.min_number_value)


@then(u'the positive number "{number:d}" is in the valid range')
# DISABLED: @soft_assertions()
def step_then_positive_number_is_valid(ctx, number):
# -- ALTERNATIVE: Use ContextManager instead of disabled decorator above.
with soft_assertions():
assert_that(number).is_greater_than_or_equal_to(0)
assert_that(number).is_greater_than_or_equal_to(ctx.min_number_value)
12 changes: 12 additions & 0 deletions examples/soft_asserts/features/steps/use_steplib_behave4cmd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# -*- coding: utf-8 -*-
"""
Use behave4cmd0 step library (predecessor of behave4cmd).
"""

from __future__ import absolute_import

# -- REGISTER-STEPS FROM STEP-LIBRARY:
# DISABLED: import behave4cmd0.__all_steps__
import behave4cmd0.passing_steps
import behave4cmd0.failing_steps
import behave4cmd0.note_steps
4 changes: 4 additions & 0 deletions examples/soft_asserts/py.requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
assertpy >= 1.1

-r ../../py.requirements/basic.txt
-r ../../py.requirements/testing.txt
3 changes: 2 additions & 1 deletion py.requirements/testing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ PyHamcrest < 2.0; python_version < '3.0'
# HINT: path.py => path (python-install-package was renamed for python3)
path.py >=11.5.0,<13.0; python_version < '3.5'
path >= 13.1.0; python_version >= '3.5'

# NOTE: toml extra for pyproject.toml-based config
.[toml]
# DISABLED: .[toml]


# -- PYTHON2 BACKPORTS:
Expand Down

0 comments on commit e3d7cc7

Please sign in to comment.