Integrations

grappa is library/framework agnostic, so you can use it with your preferred testing framework, such as nose, pytest, behave

This page provides some useful information and configuration tips for a better and more friendly integration between grappa and testing framework.

pytest

Friendly error traceback

pytest, by default, provides a custom error reporting based on the traceback analysis, pretty much as grappa does, but unfortunately in a less friendly way for the developer.

You can partially or completely disable this in pytest behavior in order to have more friendly errors generated by grappa.

In order to do that you should simply pass the following flag to:

$ pytest --tb=native

Or alternatively, you can simply partially disable it:

$ pytest --tb=short

The difference would be from this:

________________ test_expect_context_manager ________________
tests/should_test.py:277: in test_expect_context_manager
    should('foo').be.equal('bar')
grappa/assertion.py:16: in __call__
    return self._fn(expected, *args, **kw)
grappa/resolver.py:60: in wrapper
    return self.test._trigger()
grappa/test.py:145: in _trigger
    raise err
E   AssertionError: Oops! Something went wrong!
E
E     The following assertion was not satisfied
E       subject "foo" should be equal "bar"
E
E     What we expected
E       a value that is equal to "foo"
E
E     What we got instead
E       an value of type "str" with data "foo"
E
E     Where
E       File "tests/should_test.py", line 277, in test_expect_context_manager
E
E       269|      with pytest.raises(AssertionError):
E       270|          10 | should.not_be.between.to(5, 10)
E       271|
E       272|      with pytest.raises(AssertionError):
E       273|          None | should.be.between.numbers(10, 10)
E       274|
E       275|
E       276|  def test_expect_context_manager():
E       277| >    should('foo').be.equal('bar')
E       278|
E       279|      with should('foo'):
E       280|          should.be.equal('foo')
E       281|          should.have.length.of(3)
E       282|          should.have.type('string')
E       283|
E       284|      with should('foo'):

Into this:

Traceback (most recent call last):
  File "tests/should_test.py", line 277, in test_expect_context_manager
    should('foo').be.equal('bar')
  File "grappa/assertion.py", line 16, in __call__
    return self._fn(expected, *args, **kw)
  File "grappa/resolver.py", line 60, in wrapper
    return self.test._trigger()
  File "grappa/test.py", line 145, in _trigger
    raise err
AssertionError: Oops! Something went wrong!

  The following assertion was not satisfied
    subject "foo" should be equal "bar"

  What we expected
    a value that is equal to "foo"

  What we got instead
    an value of type "str" with data "foo"

  Where
    File "tests/should_test.py", line 277, in test_expect_context_manager

    269|      with pytest.raises(AssertionError):
    270|          10 | should.not_be.between.to(5, 10)
    271|
    272|      with pytest.raises(AssertionError):
    273|          None | should.be.between.numbers(10, 10)
    274|
    275|
    276|  def test_expect_context_manager():
    277| >    should('foo').be.equal('bar')
    278|
    279|      with should('foo'):
    280|          should.be.equal('foo')
    281|          should.have.length.of(3)
    282|          should.have.type('string')
    283|
    284|      with should('foo'):

Dependency injection using fixtures

In order to minimize boilerplate across tests, you can create a pytest fixture that would be automatically injected via across test functions/methods in your test suites:

First, create a conftest.py file in the directory where your test files lives with the following content:

# tests/conftest.py
import pytest
from grappa import should as _should, expect as _expect

@pytest.fixture
def should():
    return _should


@pytest.fixture
def expect():
    return _expect

Then, from a test file module, you can simply declare a test function that accepts a fixture argument, such as:

# tests/sample_test.py

def test_should_fixture(should):
    'foo' | should.have.length.of(3) | should.be.equal.to('foo')


def test_expect_fixture(expect):
    'foo' | expect.to.have.length.of(3) | expect.to.be.equal.to('foo')