go-bdd / gobdd

BDD framework
https://go-bdd.github.io/gobdd/
MIT License
115 stars 19 forks source link

Add GetError to context #55

Closed sagikazarmark closed 4 years ago

sagikazarmark commented 4 years ago

Is your feature request related to a problem? Please describe. When testing a service, I often want to define business rules for happy and unhappy paths.

For example, when creating a new resource I want to test that certain invalid conditions result in an appropriate response.

Creating the resource creation itself might be described by the same step definition as the happy path.

For example:

Scenario: Add a new item to the list
    Given there is an empty todo list
    When I add entry "Call mom"
    Then I should have a todo to "Call mom"

Scenario: Cannot add an empty todo item
    Given there is an empty todo list
    When I add entry ""
    Then I should see validation error

In this case, When I add entry "" should result in calling the service in both cases.

In the invalid case I want to check the returned error, in the valid case I want the test to fail if an error is returned.

A possible solution is passing the error to the context and checking it's value in a then step. Unfortunately, there is no GetError.

Describe the solution you'd like Add GetError to the context that returns the value as an error.

Describe alternatives you've considered I'm not sure, is there a better way to conditionally test error paths?

At the moment I'm adding this to every then step:

        if err := ctx.Get("error", nil); err != nil {
            return err.(error)
        }

Maybe have builtin support for errors in the context? Chances are if a service call fails and an error is set in the context that particular step returns.

The error in the context could even cause the test to fail if it's not "handled" (eg. retrieved by a subsequent step).

bkielbasa commented 4 years ago

I'm not sure about that. Firstly, please notice that we use context package so we cannot just add a method to it.

In such cases, I was thinking about using custom helper functions like

func getError(ctx context.Context) error {
    if err, ok := ctx.Value("error"); ok {
      return err
    }

    return nil
}
bkielbasa commented 4 years ago

I'm still not convinced about the change. You can store the error as a regular value.

sagikazarmark commented 4 years ago

True, but it's a very typical use case (call a service, check if you receive an error), so I think it would make sense to make that easier somehow.

It would even be okay to have a helper function, that retrieves an error from the context.

My goal is to make the test implementation easier to read.

bkielbasa commented 4 years ago

What I can suggest adding is something like this:

if err := ctx.GetError("error"); err != nil {
    return err
}

WDYT? So it would work the same way tha GetInt etc works.

sagikazarmark commented 4 years ago

That's my original proposal 🙂