Skip to main content

planterbox

https://api.travis-ci.org/npilon/planterbox.png?branch=master

A plugin for running behavior-driven tests using gherkin inside nose2.

Usage

To enable planterbox for your project, you’ll want to add the following lines (or similar) to your unittest.cfg:

[unittest]
plugins = planterbox

[planterbox]
always-on = True

planterbox is compatible with nose2.plugins.mp.

Writing Tests

planterbox tests exist inside a python package which provides a context for their execution. You should write your tests in .feature files in the package directory. .feature files have access to all steps defined in or imported into their package’s __init__.py. For example, with the directory structure:

planterbox/
  tests/
    test_feature/
      __init__.py
      basic.feature

If __init__.py contains:

from planterbox import step


@step(r'I add (\d+) and (\d+)')
def add(test, a, b):
    a = int(a)
    b = int(b)
    test.result = a + b


@step(r'the result should be (\d+)')
def check_result(test, value):
    value = int(value)
    test.assertEqual(test.result, value)

basic.feature could contain:

Feature: Basic Tests
    I want to exercise generation of a simple test from a feature.

    Scenario: I need to verify basic arithmetic.
        Given I add 1 and 1
        Then the result should be 2

We could then run this test either by running all of the tests in the suite with nose2 or run it specifically with nose2 planterbox.tests.test_feature:basic.feature. We could even run the first scenario specifically with nose2 planterbox.tests.test_feature:basic.feature:0.

Writing Steps

planterbox steps are python functions decorated with @planterbox.step(PATTERN). PATTERN can be a python regular expression, which must start matching expected step text after the gherkin step prefixes.

Groups matched within PATTERN are provided to the decorated function as arguments. All steps are provided with the ScenarioTestCase object for the currently executing scenario as their first argument. Unnamed groups are provided to the step as positional arguments after this. Named groups will be passed as keyword arguments. PATTERN cannot mix unnamed and named groups. If any named groups are used, all groups must be named groups.

All the steps in a feature’s package will be available to that feature’s scenario. These steps can be defined in the package or imported from somewhere else.

Hooks, Setup, and Teardown

setUpModule and tearDownModule methods in a feature’s __init__.py will be run before and after all features in that package, respectively. planterbox provides some extra hooks for doing preparation or cleanup. Functions can be registered as hooks by decorating them with @planterbox.hook(TIMING, STAGE). TIMING can be 'before' or 'after' and STAGE any of 'feature', 'scenario', 'step', 'failure', or 'error'.

All hooks are expected to take one argument: the TestCase subclass for the active feature.

As with steps, hooks must be directly present in the feature’s __init__.py in order to be run.

Scenario Outlines

planterbox supports scenario outlines. These allow you to execute a scenario multiple times with different values. For example:

Feature: Example Tests
    I want to exercise generation of a test with examples from a feature.

    Scenario Outline: I need to verify basic arithmetic with examples.
        Given I add <x> and <y>
        Then the result should be <z>
        Examples:
            x | y | z
            1 | 1 | 2
            1 | 2 | 3
            2 | 1 | 3
            2 | 2 | 4

You may also specify Examples in a .csv file by using Examples file: followed by the path to the .csv file on the next line.

Feature: Example Tests
  I want to exercise using a csv file for examples

    Scenario Outline: I want to exercise using a csv file for examples
        Given I squiggly-add {<x>} and {<y>}
        Then the result should be <z>
        Examples file:
          /tests/test_feature/examples.csv

Your 'before' and 'after' 'scenario' hooks will only run once for the entire scenario outline.

Invoking Tests

You can run tests by allowing nose2’s autodiscovery to find all of your tests, or you can specify specific tests to be run on the command line. When specifying specific tests, you can either specify an entire package, an entire feature, or individual scenarios. Individual scenarios can be specified either by index (from 0) or by name.

nose2 planterbox.tests.test_feature
nose2 planterbox.tests.test_feature:basic.feature planterbox.tests.test_hooks:hooks.feature
nose2 planterbox.tests.test_feature:basic.feature:1
nose2 planterbox.tests.test_feature:basic.feature:0
nose2 planterbox.tests.test_feature:basic.feature:"I need to verify basic arithmetic"
nose2 planterbox.tests.test_feature:basic.feature:"I need to verify basic arithmetic."

If your feature includes multiple scenarios with the same name, all will be run when that name is given. Names with a trailing period can be specified with or without the trailing period.

Validating Tests

You can use the --planterbox-check-only flag to verify that your features are correct without running them:

nose2 --planterbox-check-only planterbox.tests.test_feature

----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK

While a failure would produce a traceback:

nose2 --planterbox-check-only planterbox.tests.test_feature
Traceback (most recent call last):
  File "planterbox_ve/bin/nose2", line 11, in <module>
    sys.exit(discover())
  File "nose2/main.py", line 306, in discover
    return main(*args, **kwargs)
  File "nose2/main.py", line 100, in __init__
    super(PluggableTestProgram, self).__init__(**kw)
  File "/opt/python/lib/python3.6/unittest/main.py", line 94, in __init__
    self.parseArgs(argv)
  File "nose2/main.py", line 133, in parseArgs
    self.createTests()
  File "nose2/main.py", line 258, in createTests
    self.testNames, self.module)
  File "nose2/loader.py", line 68, in loadTestsFromNames
    for name in event.names]
  File "nose2/loader.py", line 68, in <listcomp>
    for name in event.names]
  File "nose2/loader.py", line 83, in loadTestsFromName
    result = self.session.hooks.loadTestsFromName(event)
  File "nose2/events.py", line 225, in __call__
    result = getattr(plugin, self.method)(event)
  File "nose2/plugins/loader/discovery.py", line 247, in loadTestsFromName
    return Discoverer.loadTestsFromName(self, event)
  File "nose2/plugins/loader/discovery.py", line 84, in loadTestsFromName
    self._find_tests_in_module(event, module, top_level_dir))
  File "nose2/plugins/loader/discovery.py", line 229, in _find_tests_in_module
    event, full_path, top_level_dir):
  File "nose2/plugins/loader/discovery.py", line 161, in _find_tests_in_dir
    event, path, entry_path, top_level):
  File "nose2/plugins/loader/discovery.py", line 176, in _find_tests_in_file
    result = self.session.hooks.handleFile(evt)
  File "nose2/events.py", line 225, in __call__
    result = getattr(plugin, self.method)(event)
  File "planterbox/planterbox/plugin.py", line 106, in handleFile
    feature_path=feature_path,
  File "planterbox/planterbox/plugin.py", line 75, in makeSuiteFromFeature
    config=self.config,
  File "planterbox/planterbox/feature.py", line 81, in __init__
    self.check_scenarios()
  File "planterbox/planterbox/feature.py", line 227, in check_scenarios
    raise UnmatchedStepException("Unmatched steps:\n" + '\n'.join(unmatched))
planterbox.exceptions.UnmatchedStepException: Unmatched steps:
        Given I bad 1 and 1

Metadata

Release files for planterbox 0.7.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for planterbox 0.7.2
File Size Uploaded Provenance
planterbox-0.7.2.tar.gz 19.6 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for planterbox 0.7.2
File Interpreter ABI Platform
planterbox-0.7.2-py3-none-any.whl Python 3 none any Details

Total release size: 40.4 kB

Release files / planterbox-0.7.2.tar.gz

Download URL planterbox-0.7.2.tar.gz
Size 19.6 kB
Tags Source
SHA-256 checksum
How to use checksums
1da2d403f68eb82dd8caa5ed1a34c435aa3bb0f1a7b2d443590b6e50da345398
BLAKE2b-256 checksum
How to use checksums
262885a5dd7911796b2817c2f092f95e86dce692df3b921244739ca5459509eb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.1 importlib_metadata/4.0.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.9.2

Release files / planterbox-0.7.2-py3-none-any.whl

Download URL planterbox-0.7.2-py3-none-any.whl
Size 20.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
79ca197a90848658872c9717552ddce5da59451d8aee76fb37b5b127143f741e
BLAKE2b-256 checksum
How to use checksums
66391912345431a969983511ecd18495a24ad2fef59e9d3d19979acd5de94975
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.1 importlib_metadata/4.0.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.9.2

Security for planterbox 0.7.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page