Skip to content
Back to top
View this page

# Quickstart

This is a lightning introduction to the most important features of Hypothesis; enough to get you started writing tests. The tutorial introduces these features (and more) in greater detail.

## Install Hypothesis

    pip install hypothesis

## Write your first test

Create a new file called `example.py`, containing a simple test:

    # contents of example.py
    from hypothesis import given, strategies as st

    @given(st.integers())
    def test_integers(n):
        print(f"called with {n}")
        assert isinstance(n, int)

    test_integers()

`@given` is the standard entrypoint to Hypothesis. It takes a strategy, which describes the type of inputs you want the decorated function to accept. When we call `test_integers`, Hypothesis will generate random integers (because we used the `integers()` strategy) and pass them as `n`. Let’s see that in action now by running `python example.py`:

    called with 0
    called with -18588
    called with -672780074
    called with 32616
    ...

We just called `test_integers()`, without passing a value for `n`, because Hypothesis generates random values of `n` for us.

Note

By default, Hypothesis generates 100 random inputs. You can control this with the `max_examples` setting.

## Running in a test suite

A Hypothesis test is still a regular python function, which means pytest or unittest will pick it up and run it in all the normal ways.

    # contents of example.py
    from hypothesis import given, strategies as st

    @given(st.integers(0, 200))
    def test_integers(n):
        assert n < 50

This test will clearly fail, which can be confirmed by running `pytest example.py`:

    $ pytest example.py

        ...

        @given(st.integers())
        def test_integers(n):
    >       assert n < 50
    E       assert 50 < 50
    E       Falsifying example: test_integers(
    E           n=50,
    E       )

## Arguments to `@given`

You can pass multiple arguments to `@given`:

    @given(st.integers(), st.text())
    def test_integers(n, s):
        assert isinstance(n, int)
        assert isinstance(s, str)

Or use keyword arguments:

    @given(n=st.integers(), s=st.text())
    def test_integers(n, s):
        assert isinstance(n, int)
        assert isinstance(s, str)

Note

See `@given` for details about how `@given` handles different types of arguments.

## Filtering inside a test

Sometimes, you need to remove invalid cases from your test. The best way to do this is with `.filter()`:

    @given(st.integers().filter(lambda n: n % 2 == 0))
    def test_integers(n):
        assert n % 2 == 0

For more complicated conditions, you can use `assume()`, which tells Hypothesis to discard any test case with a false-y argument:

    @given(st.integers(), st.integers())
    def test_integers(n1, n2):
        assume(n1 != n2)
        # n1 and n2 are guaranteed to be different here

Note

You can learn more about `.filter()` and `assume()` in the Adapting strategies tutorial page.

## Dependent generation

You may want an input to depend on the value of another input. For instance, you might want to generate two integers `n1` and `n2` where `n1 <= n2`.

You can do this using the `@composite` strategy. `@composite` lets you define a new strategy which is itself built by drawing values from other strategies, using the automatically-passed `draw` function.

    @st.composite
    def ordered_pairs(draw):
        n1 = draw(st.integers())
        n2 = draw(st.integers(min_value=n1))
        return (n1, n2)

    @given(ordered_pairs())
    def test_pairs_are_ordered(pair):
        n1, n2 = pair
        assert n1 <= n2

In more complex cases, you might need to interleave generation and test code. In this case, use `data()`.

    @given(st.data(), st.text(min_size=1))
    def test_string_characters_are_substrings(data, string):
        assert isinstance(string, str)
        index = data.draw(st.integers(0, len(string) - 1))
        assert string[index] in string

## Combining Hypothesis with pytest

Hypothesis works with pytest features, like pytest.mark.parametrize:

    import pytest

    from hypothesis import given, strategies as st

    @pytest.mark.parametrize("operation", [reversed, sorted])
    @given(st.lists(st.integers()))
    def test_list_operation_preserves_length(operation, lst):
        assert len(lst) == len(list(operation(lst)))

Hypothesis also works with pytest fixtures:

    import pytest

    @pytest.fixture(scope="session")
    def shared_mapping():
        return {n: 0 for n in range(101)}

    @given(st.integers(0, 100))
    def test_shared_mapping_keys(shared_mapping, n):
        assert n in shared_mapping