cucumber-attic / cucumber-engine

Shared go binary that can be used by all language implementations
MIT License
6 stars 0 forks source link

support custom filters #5

Open charlierudolph opened 6 years ago

charlierudolph commented 6 years ago

Cucumber-Ruby supports custom filters

@brasmusson @mattwynne can you please give more detail or tag someone who can.

mattwynne commented 6 years ago

Hi @charlierudolph,

Essentially, the way Cucumber-Ruby is designed, the pickles come out of the compiler (we call them test-cases) and are passed through a chain of responsibility which handles responsibilities like:

If I was to do a cucumber rewrite I'd definitely use this pattern again. It feels like a very stable and flexible extension point. It even allowed us to add support for step defs written in TCL!

I think that this new runner could support these custom filters by adding something to the protocol between the front-end and runner that allows the test-cases to be passed out to the front-end and back again, with the possibility that they might have been modified.

The filter API in cucumber-ruby is really simple. You just implement three methods, with_receiver, test_case and done. You get a with_receiver once, and remember your receiver (that's the next filter down the chain from you). Then each time you get a test_case you either pass it on to your receiver, or you modify it somehow then pass it on, or you don't pass it on at all. When you get done you know that's the end of the stream of test cases so if, for example, you're a randomizer, you can now shuffle and pump out all the test cases you've been caching.

I hope that makes some sense. I'd be more than happy to do a bit of pairing or a zoom call to talk through how we might put it into this new shared binary, which looks really exciting.

charlierudolph commented 6 years ago

What was the use case for opening up the API in such a way? What are the different modifications of the test case that can be done?

I like the structure internally as I think streaming is great, but am less certain a user should have access to add a custom one. The binary is currently doing the following (without streaming):

generate pickles -> filter -> randomize -> for each pickle, create test case (add hooks, determine step defs) and run

mattwynne commented 6 years ago

Well it's not a piece of the API that I'm aware of any users making use of yet, but it the TCL plugin is an example of where having this as an extension point allowed us to keep code out of our repo that was useful but only to a minority of users.

You can do anything to the stream of test cases on the way through. You can remove them altogether, you could duplicate them, you can add more steps to them and pass them along (that's how we do after-step hooks, for example).

What was amazing once we had this abstraction was that masses of the code in cucumber fell into this pattern really nicely. So most of the mechanics of what cucumber does between the bare things that come out of the pickle / test-case compiler and the runner are done by small, independent objects:

https://github.com/cucumber/cucumber-ruby/tree/master/lib/cucumber/filters