Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling Exceptions in Python Behave Testing framework

I've been thinking about switching from nose to behave for testing (mocha/chai etc have spoiled me). So far so good, but I can't seem to figure out any way of testing for exceptions besides:

@then("It throws a KeyError exception")
def step_impl(context):
try:
    konfigure.load_env_mapping("baz", context.configs)
except KeyError, e:
    assert (e.message == "No baz configuration found") 

With nose I can annotate a test with

@raises(KeyError)

I can't find anything like this in behave (not in the source, not in the examples, not here). It sure would be grand to be able to specify exceptions that might be thrown in the scenario outlines.

Anyone been down this path?

like image 495
Robert Moskal Avatar asked Jan 12 '15 03:01

Robert Moskal


People also ask

How can we handle exception handling in Python?

In Python, exceptions can be handled using a try statement. The critical operation which can raise an exception is placed inside the try clause. The code that handles the exceptions is written in the except clause. We can thus choose what operations to perform once we have caught the exception.

What is exception handling in Python explain?

In general, when a Python script encounters a situation that it cannot cope with, it raises an exception. An exception is a Python object that represents an error. When a Python script raises an exception, it must either handle the exception immediately otherwise it terminates and quits.

What is behave framework?

behave is a behavior-driven (BDD) test framework that is very similar to Cucumber, Cucumber-JVM, and SpecFlow. BDD frameworks are unique in that test cases are not written in raw programming code but rather in plain specification language that is then “glued” to code.

Does behave use Pytest?

Pytest and behave are two separate test runners. There is a pytest plugin for behavior testing which also uses Gherkin as a DSL but the implementation of the steps uses a syntax different from that of behave, so I don't think you can directly run the steps you created with it. Save this answer.


1 Answers

I'm pretty new to BDD myself, but generally, the idea would be that the tests document what behaves the client can expect - not the step implementations. So I'd expect the canonical way to test this would be something like:

When I try to load config baz
Then it throws a KeyError with message "No baz configuration found"

With steps defined like:

@when('...')
def step(context):
    try:
        # do some loading here
        context.exc = None
    except Exception, e:
        context.exc = e

@then('it throws a {type} with message "{msg}"')
def step(context, type, msg):
    assert isinstance(context.exc, eval(type)), "Invalid exception - expected " + type
    assert context.exc.message == msg, "Invalid message - expected " + msg

If that's a common pattern, you could just write your own decorator:

def catch_all(func):
    def wrapper(context, *args, **kwargs):
        try:
            func(context, *args, **kwargs)
            context.exc = None
        except Exception, e:
            context.exc = e

    return wrapper

@when('... ...')
@catch_all
def step(context):
    # do some loading here - same as before
like image 195
Barry Avatar answered Sep 30 '22 13:09

Barry