Specify
A PHPSpec-like for Python. For fun only (for now). If you're looking for a real valid PHPSpec-like, you could check flowp (but deprecated). mamba could also interest you, even if it's not exactly what you are searching.
Install
pip install specify
Usage
You can check the examples folder.
from specify import ObjectBehavior
from examples.calculator import Calculator
class CalculatorSpec(ObjectBehavior):
def _let(self):
self._describe(Calculator)
self._be_constructed_with('lorem', id=32)
def it_adds_the_numbers(self):
self.add(2, 3)._should_be(5)
The command python -m specify examples/spec/calculator_spec.py will render a valid TAP output (hopefully).
TAP version 13
1..1
ok 1 - CalculatorSpec: it adds the numbers
To have a nice and pretty output, you can then use a TAP formatter like faucet.
-
All specifications must start by
it_. -
All spec files must end by
_specfor now.
Builtin matchers
| Matcher | Details | Alias |
|---|---|---|
_should_be |
check with is |
_should_return |
_should_be_like |
check with == |
_should_return_like |
_should_not_be |
check with is not |
_should_not_return |
_should_not_be_like |
check with != |
_should_not_return_like |
_should_be_an_instance_of |
check with isinstance |
_should_return_an_instance_of |
_should_have_length |
check with len(x) |
Custom matchers
You can implement a _matchers function in your spec, to add custom matchers.
The key of the matcher is left trimmed by _should_ and the first argument
passed to your function is the value itself.
If you return false, the test will fail.
Here is an example:
class CalculatorSpec(ObjectBehavior):
# ...
def it_adds_the_numbers(self):
self.add(2, 3)._should_be_a_number()
self.add(2, 3)._should_be_greater_than(10)
def _matchers(self):
def be_a_number(value, *args):
return isinstance(value, int)
def be_greater_than(value, expected_value):
return value > expected_value
return {
'be_a_number': be_a_number,
'be_greater_than': be_greater_than
}
Fluent API
All matchers (builtin and custom) are chainable. Example:
self.add(2, 3)._should_be_a_number()._should_be(5)._should_be_greater_than(3)
Mocks
Thanks to prophepy (did you get the pun with prophecy? Hoho), you can
easily mock things in a Prophecy way.
Collaborators
Given this Displayer class:
from .calculator import Calculator
class Displayer:
def __init__(self, calculator: Calculator):
self.calculator = calculator
def display_addition(self, *args) -> str:
total = str(self.calculator.add(*args))
args = [str(arg) for arg in args]
return f"{' + '.join(args)} = {total}"
Here is the spec, mocking the Calculator:
from specify import ObjectBehavior, mock
from examples.calculator import Calculator
from examples.displayer import Displayer
class DisplayerSpec(ObjectBehavior):
@mock(Calculator)
def _let(self, calculator):
self._describe(Displayer)
self._be_constructed_with(calculator)
self.__calculator = calculator
def it_displays_addition(self):
self.__calculator.add(2, 3)._should_be_called()
self.__calculator.add(2, 3)._will_return(5)
self.display_addition(2, 3)._should_be_like('2 + 3 = 5')
Easy peasy.
Internal calls to modules
from specify import mock_internal
# ...
@mock_internal('getcwd', lambda : 'loremipsum', from_module='os')
def it_displays_addition(self):
# ...
# getcwd() will return 'loremipsum' and will be go back to default after
the test
TODO
- Handle attributes and not only methods
- Improve the way interal calls are mocked
- Make the tap output a stream as the spec say
- Improve the shitty way specs are loaded for now (maybe use ast like mamba?)
Metadata
Release files for specify 0.0.9
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| specify-0.0.9.tar.gz | 8.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| specify-0.0.9-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 25.8 kB
Release files / specify-0.0.9.tar.gz
| Download URL | specify-0.0.9.tar.gz |
|---|---|
| Size | 8.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
57d7a7d452c1fdbf208f4bd37e55eddeab8fb139b46ba491ec2fad04a07285cd
|
|
BLAKE2b-256 checksum How to use checksums |
c9254742c9e13c107050dac96ea0759278722064affa992ac7183f07d3338ef5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/0.12.11 CPython/3.7.2 Linux/4.14.98-1-MANJARO
|
Release files / specify-0.0.9-py3-none-any.whl
| Download URL | specify-0.0.9-py3-none-any.whl |
|---|---|
| Size | 17.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d25c0d689d86b141ed56fdb589a100340f976f42f382345a3c50c0cb1c7c371a
|
|
BLAKE2b-256 checksum How to use checksums |
5c9a1a97d6c7ae6475a6873d5716bd4be65fe2b5ebb2ba68dacf1b6e0c144d17
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/0.12.11 CPython/3.7.2 Linux/4.14.98-1-MANJARO
|
Security for specify 0.0.9
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.