Skip to main content

Hypothesis extension to allow generating protobuf messages matching a schema.

Project description

# hypothesis-protobuf
[![Build Status](https://travis-ci.org/hchasestevens/hypothesis-protobuf.svg?branch=master)](https://travis-ci.org/hchasestevens/hypothesis-protobuf)
[![PyPI version](https://badge.fury.io/py/hypothesis-pb.svg)](https://pypi.org/project/hypothesis-pb)
![PyPI - Python Version](https://img.shields.io/pypi/pyversions/hypothesis-pb.svg)

[Hypothesis](http://hypothesis.works/) extension to allow generating [protobuf](https://developers.google.com/protocol-buffers/) messages matching a schema.

## Installation
```
pip install hypothesis-pb
```

## Usage
Given a compiled protobuf schema module, `hypothesis-protobuf` allows for hypothesis strategies to be generated which match the types of the protobuf messages.

### Simple example
Using an example protobuf schema for an instant messaging application:
```proto
syntax = "proto3";
package im;

enum Client {
CLIENT_UNKNOWN = 0;
CLIENT_NATIVE_APP = 1;
CLIENT_WEB_APP = 2;
CLIENT_API = 3;
}

message User {
uint64 id = 1;
string screen_name = 2;
}

message InstantMessage {
uint64 timestamp = 1;
Client client = 2;
fixed32 sender_ip = 3;
User sender = 4;
User recipient = 5;
string message = 6;
repeated bytes image_attachments = 7;
}
```
a strategy for `InstantMessage` can be generated from the compiled schema (`im_pb2.py`) by executing:
```python
from hypothesis_protobuf import modules_to_strategies
import im_pb2

protobuf_strategies = modules_to_strategies(im_pb2)
instant_message_strategy = protobuf_strategies[im_pb2.InstantMessage]
```
which in turn can be used to generate `InstantMessage` examples:
```python
>>> instant_message_strategy.example()
timestamp: 14420265017158477352
client: CLIENT_NATIVE_APP
sender_ip: 1465109037
sender {
id: 9509488734701077048
screen_name: "\364\210\240\2233\007\352\212\222i\354\217\251"
}
recipient {
id: 14863054719025962687
screen_name: "\351\274\240"
}
message: "M\361\265\247\224\310\224\362\202\r\347\227\245\n\352\202M]\361\253\237\2700"
image_attachments: "\236rN\267\252\363-s\235"
image_attachments: "\256\376ZP-"
image_attachments: "\340"

```
or as a strategy for use in testing (see the [hypothesis quick-start guide](https://hypothesis.readthedocs.io/en/latest/quickstart.html)):
```python
from hypothesis import given

@given(instant_message=protobuf_strategies[im_pb2.InstantMessage])
def test_instant_message_processor(instant_message):
assert process_message(instant_message) # will be run using multiple InstantMessage examples
```

### Overriding strategies
When generating strategies for a given protobuf module, field-specific overrides can be provided. These overrides must be mappings from full field names to strategies, like so:
```python
from hypothesis_protobuf import modules_to_strategies
from hypothesis import strategies as st
import im_pb2

strategy_overrides = {
'im.InstantMessage.timestamp': st.floats(
min_value=0,
max_value=2e9
)
}
protobuf_strategies = modules_to_strategies(im_pb2, **strategy_overrides)
instant_message_strategy = protobuf_strategies[im_pb2.InstantMessage]
```
`hypothesis-protobuf` also offers a `full_field_name` utility, allowing the above override to be specified as:
```python
from hypothesis_protobuf import full_field_name
from hypothesis import strategies as st
import im_pb2

strategy_overrides = {
full_field_name(im_pb2.InstantMessage, 'timestamp'): st.floats(
min_value=0,
max_value=2e9
)
}
```
In cases where the message strategy should choose either from the override provided or from the default field value, the `optional` function can be used:
```python
from hypothesis_protobuf import optional
from hypothesis import strategies as st

strategy_overrides = {
'im.InstantMessage.timestamp': optional(
st.floats(min_value=0, max_value=2e9)
)
}
```
Finally, overrides can also be provided as functions, taking the field's default strategy and returning a new strategy. Using this method, the above can be rewritten as:
```python
strategy_overrides = {
'im.InstantMessage.timestamp': (
lambda strategy: strategy.filter(lambda value: value <= 2e9)
)
}
```

## License
`hypothesis-protobuf` is available under the MIT license.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hypothesis-pb-1.2.0.tar.gz (5.5 kB view details)

Uploaded Source

File details

Details for the file hypothesis-pb-1.2.0.tar.gz.

File metadata

  • Download URL: hypothesis-pb-1.2.0.tar.gz
  • Upload date:
  • Size: 5.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.11.0 pkginfo/1.4.2 requests/2.19.1 setuptools/40.2.0 requests-toolbelt/0.8.0 tqdm/4.24.0 CPython/2.7.12

File hashes

Hashes for hypothesis-pb-1.2.0.tar.gz
Algorithm Hash digest
SHA256 6361add3371277959c7cc2dc8a0d225dbbcb99e49f670f405304ac0f1ad5ff3d
MD5 aea1fad77fcb4995fcd3088f1e1694fe
BLAKE2b-256 009b837eef75deb3d517bb0c2cf7373884bc98e67065278bfa0c01ae66bd5edc

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page