behave-steplib 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- behave_steplib-1.0.0/.gitignore +79 -0
- behave_steplib-1.0.0/CHANGELOG.md +52 -0
- behave_steplib-1.0.0/LICENSE +21 -0
- behave_steplib-1.0.0/PKG-INFO +303 -0
- behave_steplib-1.0.0/README.md +237 -0
- behave_steplib-1.0.0/docs/api/core.rst +79 -0
- behave_steplib-1.0.0/docs/api/modules.rst +76 -0
- behave_steplib-1.0.0/docs/architecture.rst +154 -0
- behave_steplib-1.0.0/docs/autoload.rst +127 -0
- behave_steplib-1.0.0/docs/cli.rst +170 -0
- behave_steplib-1.0.0/docs/conf.py +37 -0
- behave_steplib-1.0.0/docs/i18n.rst +134 -0
- behave_steplib-1.0.0/docs/index.rst +114 -0
- behave_steplib-1.0.0/docs/installation.rst +84 -0
- behave_steplib-1.0.0/docs/modules/api.rst +168 -0
- behave_steplib-1.0.0/docs/modules/db.rst +106 -0
- behave_steplib-1.0.0/docs/modules/kafka.rst +115 -0
- behave_steplib-1.0.0/docs/modules/web.rst +113 -0
- behave_steplib-1.0.0/docs/quickstart.rst +131 -0
- behave_steplib-1.0.0/docs/step_contract.rst +258 -0
- behave_steplib-1.0.0/pyproject.toml +141 -0
- behave_steplib-1.0.0/steplib/__init__.py +18 -0
- behave_steplib-1.0.0/steplib/_version.py +24 -0
- behave_steplib-1.0.0/steplib/behave.py +58 -0
- behave_steplib-1.0.0/steplib/cli/__init__.py +1 -0
- behave_steplib-1.0.0/steplib/cli/formatters.py +166 -0
- behave_steplib-1.0.0/steplib/cli/main.py +136 -0
- behave_steplib-1.0.0/steplib/core/__init__.py +29 -0
- behave_steplib-1.0.0/steplib/core/decorators.py +92 -0
- behave_steplib-1.0.0/steplib/core/discovery.py +111 -0
- behave_steplib-1.0.0/steplib/core/ecosystem.py +98 -0
- behave_steplib-1.0.0/steplib/core/exceptions.py +42 -0
- behave_steplib-1.0.0/steplib/core/i18n.py +71 -0
- behave_steplib-1.0.0/steplib/core/metadata.py +47 -0
- behave_steplib-1.0.0/steplib/core/params.py +121 -0
- behave_steplib-1.0.0/steplib/core/registry.py +162 -0
- behave_steplib-1.0.0/steplib/core/state.py +68 -0
- behave_steplib-1.0.0/steplib/core/validation.py +97 -0
- behave_steplib-1.0.0/steplib/modules/__init__.py +1 -0
- behave_steplib-1.0.0/steplib/modules/api/__init__.py +7 -0
- behave_steplib-1.0.0/steplib/modules/api/actions.py +152 -0
- behave_steplib-1.0.0/steplib/modules/api/client.py +183 -0
- behave_steplib-1.0.0/steplib/modules/api/context.py +43 -0
- behave_steplib-1.0.0/steplib/modules/api/steps.py +261 -0
- behave_steplib-1.0.0/steplib/modules/api/transforms.py +161 -0
- behave_steplib-1.0.0/steplib/modules/db/__init__.py +7 -0
- behave_steplib-1.0.0/steplib/modules/db/actions.py +68 -0
- behave_steplib-1.0.0/steplib/modules/db/client.py +51 -0
- behave_steplib-1.0.0/steplib/modules/db/context.py +33 -0
- behave_steplib-1.0.0/steplib/modules/db/steps.py +120 -0
- behave_steplib-1.0.0/steplib/modules/kafka/__init__.py +7 -0
- behave_steplib-1.0.0/steplib/modules/kafka/actions.py +113 -0
- behave_steplib-1.0.0/steplib/modules/kafka/context.py +33 -0
- behave_steplib-1.0.0/steplib/modules/kafka/steps.py +132 -0
- behave_steplib-1.0.0/steplib/modules/web/__init__.py +7 -0
- behave_steplib-1.0.0/steplib/modules/web/actions.py +66 -0
- behave_steplib-1.0.0/steplib/modules/web/client.py +102 -0
- behave_steplib-1.0.0/steplib/modules/web/context.py +30 -0
- behave_steplib-1.0.0/steplib/modules/web/steps.py +138 -0
- behave_steplib-1.0.0/steplib/py.typed +0 -0
- behave_steplib-1.0.0/tests/__init__.py +1 -0
- behave_steplib-1.0.0/tests/conftest.py +34 -0
- behave_steplib-1.0.0/tests/e2e/__init__.py +1 -0
- behave_steplib-1.0.0/tests/e2e/api/__init__.py +1 -0
- behave_steplib-1.0.0/tests/e2e/api/api_health.feature +8 -0
- behave_steplib-1.0.0/tests/e2e/api/test_api_feature.py +108 -0
- behave_steplib-1.0.0/tests/integration/__init__.py +1 -0
- behave_steplib-1.0.0/tests/integration/test_api_integration.py +94 -0
- behave_steplib-1.0.0/tests/test_smoke.py +9 -0
- behave_steplib-1.0.0/tests/unit/__init__.py +1 -0
- behave_steplib-1.0.0/tests/unit/cli/__init__.py +1 -0
- behave_steplib-1.0.0/tests/unit/cli/test_main.py +201 -0
- behave_steplib-1.0.0/tests/unit/core/__init__.py +1 -0
- behave_steplib-1.0.0/tests/unit/core/test_decorators.py +91 -0
- behave_steplib-1.0.0/tests/unit/core/test_discovery.py +62 -0
- behave_steplib-1.0.0/tests/unit/core/test_ecosystem.py +52 -0
- behave_steplib-1.0.0/tests/unit/core/test_i18n.py +110 -0
- behave_steplib-1.0.0/tests/unit/core/test_params.py +68 -0
- behave_steplib-1.0.0/tests/unit/core/test_registry.py +193 -0
- behave_steplib-1.0.0/tests/unit/core/test_state.py +71 -0
- behave_steplib-1.0.0/tests/unit/modules/__init__.py +1 -0
- behave_steplib-1.0.0/tests/unit/modules/api/__init__.py +1 -0
- behave_steplib-1.0.0/tests/unit/modules/api/test_actions.py +212 -0
- behave_steplib-1.0.0/tests/unit/modules/api/test_transforms.py +133 -0
- behave_steplib-1.0.0/tests/unit/modules/db/__init__.py +1 -0
- behave_steplib-1.0.0/tests/unit/modules/db/test_actions.py +129 -0
- behave_steplib-1.0.0/tests/unit/modules/db/test_client.py +21 -0
- behave_steplib-1.0.0/tests/unit/modules/db/test_steps.py +96 -0
- behave_steplib-1.0.0/tests/unit/modules/kafka/__init__.py +1 -0
- behave_steplib-1.0.0/tests/unit/modules/kafka/test_actions.py +77 -0
- behave_steplib-1.0.0/tests/unit/modules/kafka/test_client.py +35 -0
- behave_steplib-1.0.0/tests/unit/modules/kafka/test_steps.py +60 -0
- behave_steplib-1.0.0/tests/unit/modules/web/__init__.py +1 -0
- behave_steplib-1.0.0/tests/unit/modules/web/test_actions.py +177 -0
- behave_steplib-1.0.0/tests/unit/modules/web/test_client.py +27 -0
- behave_steplib-1.0.0/tests/unit/modules/web/test_steps.py +106 -0
- behave_steplib-1.0.0/tests/unit/test_behave.py +88 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
*.manifest
|
|
31
|
+
*.spec
|
|
32
|
+
|
|
33
|
+
# Installer logs
|
|
34
|
+
pip-log.txt
|
|
35
|
+
pip-delete-this-directory.txt
|
|
36
|
+
|
|
37
|
+
# Unit test / coverage reports
|
|
38
|
+
htmlcov/
|
|
39
|
+
.tox/
|
|
40
|
+
.nox/
|
|
41
|
+
.coverage
|
|
42
|
+
.coverage.*
|
|
43
|
+
.cache
|
|
44
|
+
nosetests.xml
|
|
45
|
+
coverage.xml
|
|
46
|
+
*.cover
|
|
47
|
+
*.py,cover
|
|
48
|
+
.hypothesis/
|
|
49
|
+
.pytest_cache/
|
|
50
|
+
cover/
|
|
51
|
+
|
|
52
|
+
# Virtual environments
|
|
53
|
+
.env
|
|
54
|
+
.venv
|
|
55
|
+
env/
|
|
56
|
+
venv/
|
|
57
|
+
ENV/
|
|
58
|
+
env.bak/
|
|
59
|
+
venv.bak/
|
|
60
|
+
|
|
61
|
+
# IDEs
|
|
62
|
+
.idea/
|
|
63
|
+
.vscode/
|
|
64
|
+
*.swp
|
|
65
|
+
*.swo
|
|
66
|
+
*~
|
|
67
|
+
|
|
68
|
+
# OS
|
|
69
|
+
.DS_Store
|
|
70
|
+
Thumbs.db
|
|
71
|
+
|
|
72
|
+
# Sphinx documentation build
|
|
73
|
+
docs/_build/
|
|
74
|
+
|
|
75
|
+
# Generated version file (hatch-vcs)
|
|
76
|
+
steplib/_version.py
|
|
77
|
+
|
|
78
|
+
# Project-specific reference folder (not for public release)
|
|
79
|
+
ref/
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.0.0] - 2026-07-27
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Core package** (`steplib.core`): `@step` decorator, `StepInfo` metadata,
|
|
13
|
+
`StepRegistry` with behave integration, `Param` dataclass with `TypeRegistry`,
|
|
14
|
+
`SteplibState` lifecycle management, i18n pattern expansion and validation,
|
|
15
|
+
static step contract validation, ecosystem integration helpers
|
|
16
|
+
(`behave-kit`, `behave-tables`, `behave-data`).
|
|
17
|
+
- **API module** (`steplib.modules.api`): HTTP testing steps with stdlib
|
|
18
|
+
(urllib), httpx and requests backends. Configuration, requests, assertions
|
|
19
|
+
(status, body, JSON path, headers), response storage and table comparison.
|
|
20
|
+
- **Web module** (`steplib.modules.web`): Browser testing steps with Selenium
|
|
21
|
+
(Chrome, Firefox, headless). Navigation, page title, URL, element presence
|
|
22
|
+
and page content assertions.
|
|
23
|
+
- **DB module** (`steplib.modules.db`): Database testing steps with SQLAlchemy.
|
|
24
|
+
Connection configuration, query execution, row count and column assertions.
|
|
25
|
+
- **Kafka module** (`steplib.modules.kafka`): Kafka producer/consumer testing
|
|
26
|
+
steps with kafka-python-ng. Bootstrap configuration, produce, consume,
|
|
27
|
+
message count and content assertions.
|
|
28
|
+
- **Behave integration** (`steplib.behave`): `autoload(context)` for entry-point
|
|
29
|
+
discovery, `load(context, *modules)` for explicit loading, `before_all` and
|
|
30
|
+
`after_scenario` hooks.
|
|
31
|
+
- **CLI** (`steplib.cli`): `steplib list / show / validate / init` powered by
|
|
32
|
+
Typer with table and JSON output formats.
|
|
33
|
+
- **i18n**: Spanish (`es`) and Portuguese (`pt`) translations for all steps.
|
|
34
|
+
Both `i18n` dictionary and stacked decorator patterns supported.
|
|
35
|
+
- **Tests**: 164 tests covering core, modules, CLI and behave integration.
|
|
36
|
+
Coverage gate at 80% (current: 82%).
|
|
37
|
+
- **CI/CD**: GitHub Actions workflows for CI (lint, typecheck, test, coverage),
|
|
38
|
+
release (build, PyPI publish with attestations, GitHub release) and docs
|
|
39
|
+
(Sphinx + furo, GitHub Pages deployment).
|
|
40
|
+
- **Documentation**: Sphinx documentation with furo theme, autodoc API
|
|
41
|
+
reference, getting started guides, module references and architecture docs.
|
|
42
|
+
- **Community files**: `CODE_OF_CONDUCT.md`, `CONTRIBUTING.md`, `SECURITY.md`,
|
|
43
|
+
pull request template, bug report and feature request issue templates.
|
|
44
|
+
- **Project setup**: `pyproject.toml` with hatchling + hatch-vcs, `Makefile`,
|
|
45
|
+
`LICENSE` (MIT), `steplib/py.typed` marker, `.markdownlint.json`.
|
|
46
|
+
|
|
47
|
+
### Technical
|
|
48
|
+
|
|
49
|
+
- `mypy --strict` clean across 38 source files.
|
|
50
|
+
- `ruff` clean with `E`, `F`, `W`, `I`, `N`, `UP`, `B`, `SIM` rules.
|
|
51
|
+
- Python 3.11+ required.
|
|
52
|
+
- Zero mandatory runtime dependencies beyond `behave`, `parse` and `typer`.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Mathias Paulenko
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: behave-steplib
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Librería de steps reusable para behave con soporte multitecnología e i18n.
|
|
5
|
+
Project-URL: Homepage, https://github.com/MathiasPaulenko/behave-steplib
|
|
6
|
+
Project-URL: Documentation, https://mathiaspaulenko.github.io/behave-steplib
|
|
7
|
+
Project-URL: Repository, https://github.com/MathiasPaulenko/behave-steplib
|
|
8
|
+
Project-URL: Issues, https://github.com/MathiasPaulenko/behave-steplib/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/MathiasPaulenko/behave-steplib/blob/main/CHANGELOG.md
|
|
10
|
+
Author: Mathias Paulenko
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: api,bdd,behave,db,i18n,kafka,steps,web
|
|
14
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Software Development :: Testing
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.11
|
|
25
|
+
Requires-Dist: behave>=1.3.0
|
|
26
|
+
Requires-Dist: parse>=1.19
|
|
27
|
+
Requires-Dist: typer>=0.12
|
|
28
|
+
Provides-Extra: all
|
|
29
|
+
Requires-Dist: behave-data>=1.0.2; extra == 'all'
|
|
30
|
+
Requires-Dist: behave-kit>=1.3.1; extra == 'all'
|
|
31
|
+
Requires-Dist: behave-tables>=1.3.1; extra == 'all'
|
|
32
|
+
Requires-Dist: httpx>=0.27; extra == 'all'
|
|
33
|
+
Requires-Dist: kafka-python-ng>=2.0; extra == 'all'
|
|
34
|
+
Requires-Dist: selenium>=4.0; extra == 'all'
|
|
35
|
+
Requires-Dist: sqlalchemy>=2.0; extra == 'all'
|
|
36
|
+
Provides-Extra: api
|
|
37
|
+
Requires-Dist: httpx>=0.27; extra == 'api'
|
|
38
|
+
Provides-Extra: data
|
|
39
|
+
Requires-Dist: behave-data>=1.0.2; extra == 'data'
|
|
40
|
+
Provides-Extra: db
|
|
41
|
+
Requires-Dist: sqlalchemy>=2.0; extra == 'db'
|
|
42
|
+
Provides-Extra: dev
|
|
43
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
44
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
45
|
+
Requires-Dist: pre-commit>=3.7; extra == 'dev'
|
|
46
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
47
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
48
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
49
|
+
Requires-Dist: responses>=0.25; extra == 'dev'
|
|
50
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
51
|
+
Requires-Dist: twine>=5.0; extra == 'dev'
|
|
52
|
+
Provides-Extra: docs
|
|
53
|
+
Requires-Dist: furo>=2024.0; extra == 'docs'
|
|
54
|
+
Requires-Dist: myst-parser>=3.0; extra == 'docs'
|
|
55
|
+
Requires-Dist: sphinx-autodoc-typehints>=2.0; extra == 'docs'
|
|
56
|
+
Requires-Dist: sphinx>=7.0; extra == 'docs'
|
|
57
|
+
Provides-Extra: kafka
|
|
58
|
+
Requires-Dist: kafka-python-ng>=2.0; extra == 'kafka'
|
|
59
|
+
Provides-Extra: kit
|
|
60
|
+
Requires-Dist: behave-kit>=1.3.1; extra == 'kit'
|
|
61
|
+
Provides-Extra: tables
|
|
62
|
+
Requires-Dist: behave-tables>=1.3.1; extra == 'tables'
|
|
63
|
+
Provides-Extra: web
|
|
64
|
+
Requires-Dist: selenium>=4.0; extra == 'web'
|
|
65
|
+
Description-Content-Type: text/markdown
|
|
66
|
+
|
|
67
|
+
# behave-steplib
|
|
68
|
+
|
|
69
|
+
Reusable step libraries for [Behave](https://github.com/behave/behave) BDD — share, discover and install step definitions across projects. Zero mandatory dependencies; each technology is an optional extra.
|
|
70
|
+
|
|
71
|
+
[](https://github.com/MathiasPaulenko/behave-steplib/actions/workflows/ci.yml)
|
|
72
|
+
[](https://github.com/MathiasPaulenko/behave-steplib/actions/workflows/release.yml)
|
|
73
|
+
[](https://pypi.org/project/behave-steplib/)
|
|
74
|
+
[](https://www.python.org/downloads/)
|
|
75
|
+
[](https://opensource.org/licenses/MIT)
|
|
76
|
+
|
|
77
|
+
## Why behave-steplib?
|
|
78
|
+
|
|
79
|
+
Writing BDD step definitions for HTTP APIs, web browsers, databases and Kafka is repetitive. Every project re-implements the same "send a request", "check the status code", "query the database" steps. behave-steplib provides a curated, typed, multilingual library of reusable steps that you install once and share across projects.
|
|
80
|
+
|
|
81
|
+
- **Modular** — `api`, `web`, `db`, `kafka` modules activated via extras and lazy imports. Install only what you need.
|
|
82
|
+
- **Auto-registered** — `autoload(context)` discovers every installed step via Python entry points and registers it with behave in one line.
|
|
83
|
+
- **Multilingual** — steps defined in English with `es` and `pt` translations; all patterns are registered with behave so matching works regardless of the language used in feature files.
|
|
84
|
+
- **Typed** — full type hints, `mypy --strict` clean, `py.typed` marker included.
|
|
85
|
+
- **CLI** — `steplib list / show / validate / init` powered by Typer for inspecting and validating your step library from the terminal.
|
|
86
|
+
- **Pluggable** — third-party packages can register steps via the `steplib.plugins` entry point group; `autoload` discovers them automatically.
|
|
87
|
+
- **Ecosystem** — integrates with `behave-kit` (soft assertions), `behave-tables` (table conversion) and `behave-data` (test data loading) when installed.
|
|
88
|
+
- **Backends** — each module supports multiple backends (e.g. stdlib/httpx/requests for API, selenium for web) selectable at autoload time.
|
|
89
|
+
|
|
90
|
+
## Installation
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
pip install behave-steplib # core only (behave, parse, typer)
|
|
94
|
+
pip install behave-steplib[api] # + httpx HTTP client
|
|
95
|
+
pip install "behave-steplib[api,web,db,kafka]" # + all technology extras
|
|
96
|
+
pip install "behave-steplib[all]" # + every technology extra
|
|
97
|
+
pip install behave-steplib[dev] # + pytest, ruff, mypy, build, twine
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
| Extra | Packages | Description |
|
|
101
|
+
|-------|----------|-------------|
|
|
102
|
+
| `[api]` | `httpx` | HTTP API testing with httpx |
|
|
103
|
+
| `[web]` | `selenium` | Browser testing with Selenium |
|
|
104
|
+
| `[db]` | `sqlalchemy` | Database testing with SQLAlchemy |
|
|
105
|
+
| `[kafka]` | `kafka-python-ng` | Kafka producer/consumer testing |
|
|
106
|
+
| `[kit]` | `behave-kit` | Soft assertions, typed context, fixtures |
|
|
107
|
+
| `[data]` | `behave-data` | Test data loading (CSV, JSON, YAML, Excel) |
|
|
108
|
+
| `[tables]` | `behave-tables` | Table conversion helpers |
|
|
109
|
+
| `[dev]` | pytest, ruff, mypy, build, twine | Development tools |
|
|
110
|
+
| `[docs]` | sphinx, furo, myst-parser | Documentation tools |
|
|
111
|
+
| `[all]` | api, web, db, kafka, kit, data, tables | Everything except dev/docs |
|
|
112
|
+
|
|
113
|
+
## Quickstart
|
|
114
|
+
|
|
115
|
+
### Level 1 — Automatic wiring
|
|
116
|
+
|
|
117
|
+
Add three hooks to your `environment.py` and every installed step is wired automatically:
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
# features/environment.py
|
|
121
|
+
from steplib.behave import autoload
|
|
122
|
+
|
|
123
|
+
def before_all(context):
|
|
124
|
+
context.steplib = autoload(context)
|
|
125
|
+
|
|
126
|
+
def before_scenario(context, scenario):
|
|
127
|
+
context.steplib.reset()
|
|
128
|
+
|
|
129
|
+
def after_scenario(context, scenario):
|
|
130
|
+
context.steplib.cleanup()
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Or generate it with the CLI:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
steplib init
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Level 2 — Explicit load
|
|
140
|
+
|
|
141
|
+
Load only the modules you need by dotted path:
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
from steplib.behave import load
|
|
145
|
+
|
|
146
|
+
def before_all(context):
|
|
147
|
+
context.steplib = load(context, "steplib.modules.api.steps")
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Level 3 — Filtered autoload
|
|
151
|
+
|
|
152
|
+
When multiple extras are installed, narrow which steps are active:
|
|
153
|
+
|
|
154
|
+
```python
|
|
155
|
+
from steplib.behave import autoload
|
|
156
|
+
|
|
157
|
+
def before_all(context):
|
|
158
|
+
context.steplib = autoload(
|
|
159
|
+
context,
|
|
160
|
+
categories=["api"],
|
|
161
|
+
backends={"api": "httpx"},
|
|
162
|
+
)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Example feature
|
|
166
|
+
|
|
167
|
+
```gherkin
|
|
168
|
+
Feature: API health check
|
|
169
|
+
|
|
170
|
+
Scenario: GET users returns 200
|
|
171
|
+
Given the API base url is "https://api.example.com"
|
|
172
|
+
When I send a GET request to "/users"
|
|
173
|
+
Then the response status is 200
|
|
174
|
+
And the response body is valid JSON
|
|
175
|
+
And the JSON path "$.users[0].name" equals "Ada"
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Multilingual features
|
|
179
|
+
|
|
180
|
+
Steps are defined in English and translated to Spanish and Portuguese. All patterns are registered with behave — no language switch needed:
|
|
181
|
+
|
|
182
|
+
```gherkin
|
|
183
|
+
# es
|
|
184
|
+
Cuando envío una petición GET a "/users"
|
|
185
|
+
Entonces el estado de la respuesta es 200
|
|
186
|
+
|
|
187
|
+
# pt
|
|
188
|
+
Quando envio uma requisição GET para "/users"
|
|
189
|
+
Então o status da resposta é 200
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Modules
|
|
193
|
+
|
|
194
|
+
### API
|
|
195
|
+
|
|
196
|
+
HTTP API testing with stdlib (urllib), httpx or requests backends.
|
|
197
|
+
|
|
198
|
+
```gherkin
|
|
199
|
+
Given the API base url is "https://api.example.com"
|
|
200
|
+
When I send a GET request to "/users"
|
|
201
|
+
Then the response status is 200
|
|
202
|
+
And the JSON path "$.users[0].name" equals "Ada"
|
|
203
|
+
And the response header "Content-Type" is "application/json"
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Web
|
|
207
|
+
|
|
208
|
+
Browser testing with Selenium (Chrome, Firefox, headless).
|
|
209
|
+
|
|
210
|
+
```gherkin
|
|
211
|
+
Given the web base url is "https://example.com"
|
|
212
|
+
When I navigate to "/login"
|
|
213
|
+
Then the page title is "Login"
|
|
214
|
+
And the element id "username" is present
|
|
215
|
+
And the page contains "Sign In"
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### DB
|
|
219
|
+
|
|
220
|
+
Database testing with SQLAlchemy (SQLite, PostgreSQL, MySQL, ...).
|
|
221
|
+
|
|
222
|
+
```gherkin
|
|
223
|
+
Given the database connection string is "sqlite:///test.db"
|
|
224
|
+
When I execute the SQL query "SELECT * FROM users"
|
|
225
|
+
Then the query returns 3 rows
|
|
226
|
+
And the column "name" in the first row equals "Ada"
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Kafka
|
|
230
|
+
|
|
231
|
+
Kafka producer and consumer testing with kafka-python-ng.
|
|
232
|
+
|
|
233
|
+
```gherkin
|
|
234
|
+
Given the Kafka bootstrap servers are "localhost:9092"
|
|
235
|
+
When I produce a message to topic "events" with key "id" and value "hello"
|
|
236
|
+
And I consume messages from topic "events"
|
|
237
|
+
Then the consumed messages count is 1
|
|
238
|
+
And a consumed message contains "hello"
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## CLI
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
steplib list # list all registered steps
|
|
245
|
+
steplib list --category api # filter by category
|
|
246
|
+
steplib list --backend httpx # filter by backend
|
|
247
|
+
steplib list --json # output as JSON
|
|
248
|
+
steplib show "I send a {method} request to {url}"
|
|
249
|
+
steplib validate # validate step contracts
|
|
250
|
+
steplib init # generate features/environment.py
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Writing custom steps
|
|
254
|
+
|
|
255
|
+
Use the `@step` decorator to define your own steps with full metadata:
|
|
256
|
+
|
|
257
|
+
```python
|
|
258
|
+
from steplib import Param, step
|
|
259
|
+
|
|
260
|
+
@step(
|
|
261
|
+
"the invoice total is {total:f}",
|
|
262
|
+
category="invoice",
|
|
263
|
+
description="Assert the invoice total matches.",
|
|
264
|
+
parameters=[Param("total", type=float, required=True)],
|
|
265
|
+
example='Then the invoice total is 19.99',
|
|
266
|
+
i18n={
|
|
267
|
+
"es": "el total de la factura es {total:f}",
|
|
268
|
+
"pt": "o total da fatura é {total:f}",
|
|
269
|
+
},
|
|
270
|
+
tags=["invoice"],
|
|
271
|
+
version="1.0.0",
|
|
272
|
+
)
|
|
273
|
+
def step_invoice_total(context, total):
|
|
274
|
+
assert context.invoice.total == total
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Register steps in a `register(registry)` function and declare an entry point:
|
|
278
|
+
|
|
279
|
+
```toml
|
|
280
|
+
# pyproject.toml
|
|
281
|
+
[project.entry-points."steplib.plugins"]
|
|
282
|
+
mycompany = "mycompany.steps:register"
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Once installed, `autoload(context)` discovers your package automatically.
|
|
286
|
+
|
|
287
|
+
## Development
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
make dev # install with api, dev and docs extras
|
|
291
|
+
make lint # ruff + mypy --strict
|
|
292
|
+
make test-cov # pytest with >=80% coverage gate
|
|
293
|
+
make docs-build # build Sphinx documentation
|
|
294
|
+
make build # build sdist + wheel
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## Documentation
|
|
298
|
+
|
|
299
|
+
Full documentation is available at <https://mathiaspaulenko.github.io/behave-steplib>.
|
|
300
|
+
|
|
301
|
+
## License
|
|
302
|
+
|
|
303
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# behave-steplib
|
|
2
|
+
|
|
3
|
+
Reusable step libraries for [Behave](https://github.com/behave/behave) BDD — share, discover and install step definitions across projects. Zero mandatory dependencies; each technology is an optional extra.
|
|
4
|
+
|
|
5
|
+
[](https://github.com/MathiasPaulenko/behave-steplib/actions/workflows/ci.yml)
|
|
6
|
+
[](https://github.com/MathiasPaulenko/behave-steplib/actions/workflows/release.yml)
|
|
7
|
+
[](https://pypi.org/project/behave-steplib/)
|
|
8
|
+
[](https://www.python.org/downloads/)
|
|
9
|
+
[](https://opensource.org/licenses/MIT)
|
|
10
|
+
|
|
11
|
+
## Why behave-steplib?
|
|
12
|
+
|
|
13
|
+
Writing BDD step definitions for HTTP APIs, web browsers, databases and Kafka is repetitive. Every project re-implements the same "send a request", "check the status code", "query the database" steps. behave-steplib provides a curated, typed, multilingual library of reusable steps that you install once and share across projects.
|
|
14
|
+
|
|
15
|
+
- **Modular** — `api`, `web`, `db`, `kafka` modules activated via extras and lazy imports. Install only what you need.
|
|
16
|
+
- **Auto-registered** — `autoload(context)` discovers every installed step via Python entry points and registers it with behave in one line.
|
|
17
|
+
- **Multilingual** — steps defined in English with `es` and `pt` translations; all patterns are registered with behave so matching works regardless of the language used in feature files.
|
|
18
|
+
- **Typed** — full type hints, `mypy --strict` clean, `py.typed` marker included.
|
|
19
|
+
- **CLI** — `steplib list / show / validate / init` powered by Typer for inspecting and validating your step library from the terminal.
|
|
20
|
+
- **Pluggable** — third-party packages can register steps via the `steplib.plugins` entry point group; `autoload` discovers them automatically.
|
|
21
|
+
- **Ecosystem** — integrates with `behave-kit` (soft assertions), `behave-tables` (table conversion) and `behave-data` (test data loading) when installed.
|
|
22
|
+
- **Backends** — each module supports multiple backends (e.g. stdlib/httpx/requests for API, selenium for web) selectable at autoload time.
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install behave-steplib # core only (behave, parse, typer)
|
|
28
|
+
pip install behave-steplib[api] # + httpx HTTP client
|
|
29
|
+
pip install "behave-steplib[api,web,db,kafka]" # + all technology extras
|
|
30
|
+
pip install "behave-steplib[all]" # + every technology extra
|
|
31
|
+
pip install behave-steplib[dev] # + pytest, ruff, mypy, build, twine
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
| Extra | Packages | Description |
|
|
35
|
+
|-------|----------|-------------|
|
|
36
|
+
| `[api]` | `httpx` | HTTP API testing with httpx |
|
|
37
|
+
| `[web]` | `selenium` | Browser testing with Selenium |
|
|
38
|
+
| `[db]` | `sqlalchemy` | Database testing with SQLAlchemy |
|
|
39
|
+
| `[kafka]` | `kafka-python-ng` | Kafka producer/consumer testing |
|
|
40
|
+
| `[kit]` | `behave-kit` | Soft assertions, typed context, fixtures |
|
|
41
|
+
| `[data]` | `behave-data` | Test data loading (CSV, JSON, YAML, Excel) |
|
|
42
|
+
| `[tables]` | `behave-tables` | Table conversion helpers |
|
|
43
|
+
| `[dev]` | pytest, ruff, mypy, build, twine | Development tools |
|
|
44
|
+
| `[docs]` | sphinx, furo, myst-parser | Documentation tools |
|
|
45
|
+
| `[all]` | api, web, db, kafka, kit, data, tables | Everything except dev/docs |
|
|
46
|
+
|
|
47
|
+
## Quickstart
|
|
48
|
+
|
|
49
|
+
### Level 1 — Automatic wiring
|
|
50
|
+
|
|
51
|
+
Add three hooks to your `environment.py` and every installed step is wired automatically:
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
# features/environment.py
|
|
55
|
+
from steplib.behave import autoload
|
|
56
|
+
|
|
57
|
+
def before_all(context):
|
|
58
|
+
context.steplib = autoload(context)
|
|
59
|
+
|
|
60
|
+
def before_scenario(context, scenario):
|
|
61
|
+
context.steplib.reset()
|
|
62
|
+
|
|
63
|
+
def after_scenario(context, scenario):
|
|
64
|
+
context.steplib.cleanup()
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Or generate it with the CLI:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
steplib init
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Level 2 — Explicit load
|
|
74
|
+
|
|
75
|
+
Load only the modules you need by dotted path:
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
from steplib.behave import load
|
|
79
|
+
|
|
80
|
+
def before_all(context):
|
|
81
|
+
context.steplib = load(context, "steplib.modules.api.steps")
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Level 3 — Filtered autoload
|
|
85
|
+
|
|
86
|
+
When multiple extras are installed, narrow which steps are active:
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
from steplib.behave import autoload
|
|
90
|
+
|
|
91
|
+
def before_all(context):
|
|
92
|
+
context.steplib = autoload(
|
|
93
|
+
context,
|
|
94
|
+
categories=["api"],
|
|
95
|
+
backends={"api": "httpx"},
|
|
96
|
+
)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Example feature
|
|
100
|
+
|
|
101
|
+
```gherkin
|
|
102
|
+
Feature: API health check
|
|
103
|
+
|
|
104
|
+
Scenario: GET users returns 200
|
|
105
|
+
Given the API base url is "https://api.example.com"
|
|
106
|
+
When I send a GET request to "/users"
|
|
107
|
+
Then the response status is 200
|
|
108
|
+
And the response body is valid JSON
|
|
109
|
+
And the JSON path "$.users[0].name" equals "Ada"
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Multilingual features
|
|
113
|
+
|
|
114
|
+
Steps are defined in English and translated to Spanish and Portuguese. All patterns are registered with behave — no language switch needed:
|
|
115
|
+
|
|
116
|
+
```gherkin
|
|
117
|
+
# es
|
|
118
|
+
Cuando envío una petición GET a "/users"
|
|
119
|
+
Entonces el estado de la respuesta es 200
|
|
120
|
+
|
|
121
|
+
# pt
|
|
122
|
+
Quando envio uma requisição GET para "/users"
|
|
123
|
+
Então o status da resposta é 200
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Modules
|
|
127
|
+
|
|
128
|
+
### API
|
|
129
|
+
|
|
130
|
+
HTTP API testing with stdlib (urllib), httpx or requests backends.
|
|
131
|
+
|
|
132
|
+
```gherkin
|
|
133
|
+
Given the API base url is "https://api.example.com"
|
|
134
|
+
When I send a GET request to "/users"
|
|
135
|
+
Then the response status is 200
|
|
136
|
+
And the JSON path "$.users[0].name" equals "Ada"
|
|
137
|
+
And the response header "Content-Type" is "application/json"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Web
|
|
141
|
+
|
|
142
|
+
Browser testing with Selenium (Chrome, Firefox, headless).
|
|
143
|
+
|
|
144
|
+
```gherkin
|
|
145
|
+
Given the web base url is "https://example.com"
|
|
146
|
+
When I navigate to "/login"
|
|
147
|
+
Then the page title is "Login"
|
|
148
|
+
And the element id "username" is present
|
|
149
|
+
And the page contains "Sign In"
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### DB
|
|
153
|
+
|
|
154
|
+
Database testing with SQLAlchemy (SQLite, PostgreSQL, MySQL, ...).
|
|
155
|
+
|
|
156
|
+
```gherkin
|
|
157
|
+
Given the database connection string is "sqlite:///test.db"
|
|
158
|
+
When I execute the SQL query "SELECT * FROM users"
|
|
159
|
+
Then the query returns 3 rows
|
|
160
|
+
And the column "name" in the first row equals "Ada"
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Kafka
|
|
164
|
+
|
|
165
|
+
Kafka producer and consumer testing with kafka-python-ng.
|
|
166
|
+
|
|
167
|
+
```gherkin
|
|
168
|
+
Given the Kafka bootstrap servers are "localhost:9092"
|
|
169
|
+
When I produce a message to topic "events" with key "id" and value "hello"
|
|
170
|
+
And I consume messages from topic "events"
|
|
171
|
+
Then the consumed messages count is 1
|
|
172
|
+
And a consumed message contains "hello"
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## CLI
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
steplib list # list all registered steps
|
|
179
|
+
steplib list --category api # filter by category
|
|
180
|
+
steplib list --backend httpx # filter by backend
|
|
181
|
+
steplib list --json # output as JSON
|
|
182
|
+
steplib show "I send a {method} request to {url}"
|
|
183
|
+
steplib validate # validate step contracts
|
|
184
|
+
steplib init # generate features/environment.py
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Writing custom steps
|
|
188
|
+
|
|
189
|
+
Use the `@step` decorator to define your own steps with full metadata:
|
|
190
|
+
|
|
191
|
+
```python
|
|
192
|
+
from steplib import Param, step
|
|
193
|
+
|
|
194
|
+
@step(
|
|
195
|
+
"the invoice total is {total:f}",
|
|
196
|
+
category="invoice",
|
|
197
|
+
description="Assert the invoice total matches.",
|
|
198
|
+
parameters=[Param("total", type=float, required=True)],
|
|
199
|
+
example='Then the invoice total is 19.99',
|
|
200
|
+
i18n={
|
|
201
|
+
"es": "el total de la factura es {total:f}",
|
|
202
|
+
"pt": "o total da fatura é {total:f}",
|
|
203
|
+
},
|
|
204
|
+
tags=["invoice"],
|
|
205
|
+
version="1.0.0",
|
|
206
|
+
)
|
|
207
|
+
def step_invoice_total(context, total):
|
|
208
|
+
assert context.invoice.total == total
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Register steps in a `register(registry)` function and declare an entry point:
|
|
212
|
+
|
|
213
|
+
```toml
|
|
214
|
+
# pyproject.toml
|
|
215
|
+
[project.entry-points."steplib.plugins"]
|
|
216
|
+
mycompany = "mycompany.steps:register"
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Once installed, `autoload(context)` discovers your package automatically.
|
|
220
|
+
|
|
221
|
+
## Development
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
make dev # install with api, dev and docs extras
|
|
225
|
+
make lint # ruff + mypy --strict
|
|
226
|
+
make test-cov # pytest with >=80% coverage gate
|
|
227
|
+
make docs-build # build Sphinx documentation
|
|
228
|
+
make build # build sdist + wheel
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Documentation
|
|
232
|
+
|
|
233
|
+
Full documentation is available at <https://mathiaspaulenko.github.io/behave-steplib>.
|
|
234
|
+
|
|
235
|
+
## License
|
|
236
|
+
|
|
237
|
+
MIT — see [LICENSE](LICENSE).
|