Package: hypothesis-pb
# 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```## UsageGiven a compiled protobuf schema module, `hypothesis-protobuf` allows for hypothesis strategies to be generated which match the types of the protobuf messages.### Simple exampleUsing an example protobuf schema for an instant messaging application:```protosyntax = "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:```pythonfrom hypothesis_protobuf import modules_to_strategiesimport im_pb2protobuf_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: 14420265017158477352client: CLIENT_NATIVE_APPsender_ip: 1465109037sender {id: 9509488734701077048screen_name: "\364\210\240\2233\007\352\212\222i\354\217\251"}recipient {id: 14863054719025962687screen_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)):```pythonfrom 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 strategiesWhen 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:```pythonfrom hypothesis_protobuf import modules_to_strategiesfrom hypothesis import strategies as stimport im_pb2strategy_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:```pythonfrom hypothesis_protobuf import full_field_namefrom hypothesis import strategies as stimport im_pb2strategy_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:```pythonfrom hypothesis_protobuf import optionalfrom hypothesis import strategies as ststrategy_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:```pythonstrategy_overrides = {'im.InstantMessage.timestamp': (lambda strategy: strategy.filter(lambda value: value <= 2e9))}```## License`hypothesis-protobuf` is available under the MIT license.