Repository navigation
Allowing both DocString and DataTable on a single step #2315
Description
🤔 What's the problem you're trying to solve?
Currently, a Gherkin step can have either a DocString or a DataTable, but not both.
This is limiting for cases where the two argument types represent different parts of the same action or assertion. For example, a DocString can naturally represent a request body, GraphQL query, SQL statement, template, or expected text, while a DataTable can represent structured parameters, metadata, expected rows, or assertions for that same step.
The current mutual exclusivity means downstream runners and libraries cannot model such steps directly, even though the AST/message model already has separate docString and dataTable fields.
I want to discuss whether this exclusivity is intentional and should remain, or whether Gherkin should allow one DocString and one DataTable on the same step.
✨ What's your proposed solution?
Allow a single step to contain both existing argument kinds:
- zero or one DocString
- zero or one DataTable
This is not a proposal for arbitrary multiple step arguments. It should not allow repeated DocStrings, repeated DataTables, or a general ordered stepArguments[] collection.
Example:
Given I send a request
"""
{ "name": "Bob" }
"""
| status | message |
| 201 | created |⛏ Have you considered any alternatives or workarounds?
One workaround is to split the step into multiple steps. That works, but it can make a single logical action harder to read when the DocString and DataTable are both part of the same operation.
Another workaround is to encode the structured data inside the DocString, for example as JSON or YAML. That loses the readability and ergonomics of DataTables.
A third workaround is to encode the text payload inside a DataTable cell. That is usually worse for larger text blocks, request bodies, SQL, GraphQL, XML, Markdown, etc.
I do not think supporting multiple DocStrings or multiple DataTables is a good alternative. That would be a much broader feature requiring a real collection model, ordering rules, formatter behavior, runner API changes, and probably additional syntax to distinguish repeated arguments. The proposal here is intentionally narrower.
📚 Any additional context?
This came up from a PR that attempted to allow both a DocString and a DataTable on the same step. Feedback on that PR raised valid concerns about ordering, pretty formatting, runner APIs, and broader ecosystem impact.
I would like to use this issue to gather consensus before treating the behavior as settled.
In particular, feedback would be useful from maintainers and consumers of Cucumber-JS, Cucumber-JVM, Cucumber-Ruby, Reqnroll, godog, and other projects using the Gherkin parser.
Questions to discuss:
- Should
docStringanddataTableremain mutually exclusive? - If both are allowed, should both syntactic orders be valid?
- Should there be one canonical order only?
- Should runners expose these by type/name rather than as positional arguments?
- Would this create practical compatibility issues for existing formatters or runner APIs?
Activity
kruczekrobert commentedon May 17, 2026
cucumber/gherkin#592 proposal
mpkorstanje commentedon May 17, 2026
This would up to the specific Cucumber implementation. Not every language supports named arguments. As a consequence though, positional arguments are the lowest common denominator. Which requires an order of sorts.
This depends on on the chosen solution.
If the number of arguments for a step is limited to 1 doc string and 1 data table we can probably add an
indexfield toPickleDocString,PickleTable. That looks reasonably backwards compatible. Though older implementations consuming information produced by a newer Gherkin parser might fail or omit one of the arguments as they are mutually exclusive.Otherwise it would be a considerable breaking change as
StepandPickleStepwould need a list of step arguments.gasparnagy commentedon May 19, 2026
I think the idea of having both docstring and a data table for a single step has no fundamental issues (I remember the first SpecFlow versions supported that before we moved to a shared parser). I don't see any technical issues that could not be solved in some ways.
But obviously it is a kind of change that require some time until all downstream tooling (execution frameworks, IDEs, reporting tools, etc) will support it. With the
Rulekeyword in Gherkin 6 it took 2+ years until is was generally supported.So the question is rather whether the added value is high enough so that it compensates the efforts.
For the concrete questions:
I think the docstring + data table order looks good, I would like to see another concrete example for the other order.
As @mpkorstanje mentioned, we must keep the positional arguments and I would enforce the same order as they appear after the step. So in case of the example posted, the last two stepdef param must be string and data table.
If this is implemented in Gherkin, the runners, like Reqnroll could take a two step approach:
mpkorstanje commentedon May 19, 2026
Interesting. I wasn't aware of that.
Additionally, cucumber-rs and (apperently) behave do allow both:
gherkindoesn't allow to have bothTableandDocStringfor a step cucumber-rs/gherkin#41 (comment)kruczekrobert commentedon May 20, 2026
@mpkorstanje @gasparnagy How much information are we waiting for, and when will we be able to move forward with this issue?
gasparnagy commentedon May 20, 2026
I think we should decide if we would support the table-docstring order as well or just stay with docstring-table. If we are not sure, I would stick to docstring-table.
I will discuss it today with @sebrose. Maybe he has a good insight for or against this. I will follow up later.
mpkorstanje commentedon May 20, 2026
I think table-docstring looks better. 😄
But if we support one, I'd like to support both. Introducing the other order later on would be an equally big change. And there is enough space in Cucumber messages to get the ordering in a backwards compatible manner.
The ordering info must be optional for backwards compatibility, but can default to a yet to be decided canonical table-docstring or docstring-table if both are present without ordering (bit of an edge case though).
mpkorstanje commentedon May 20, 2026
Noting that @davidjgoss isn't currently in favor cucumber/gherkin#592 (comment).
mpkorstanje commentedon May 20, 2026
@elchupanebrej, @youtux, @kieran-ryan, @jsa34, both PyTest BDD implementations are using the official Gherkin parser, would you be interested in sharing your perspective?
gasparnagy commentedon May 20, 2026
We had a chat with Seb, he was also positive about this improvement and haven't seen stuff that speaks against it.
On the order: we discussed that one too and found that probably the easiest would be to support both orders (otherwise it might be hard to understand from a parser error message what is wrong).
About the parameter position we considered two options:
Originally we had opposite votes (Seb: 2, Me: 1), but I convinced Seb for 1, mainly with the argument that when custom parameter types are used, it might not be clear from the method which one is which so then it is better to stick to the scenario usage order. But I don't feel very strong about this though, so I'm fine if we decide differently.
gasparnagy commentedon May 20, 2026
What @davidjgoss says about this feature being focused on API testing is a relevant point. It would be good to see a valid example that is not focused on technical testing.
youtux commentedon May 20, 2026
On what? The order of datatable/docstring?
mpkorstanje commentedon May 20, 2026
@youtux the whole proposal in general. For example:
If you don't particularly mind either way, that's also a valid position too.
kruczekrobert commentedon May 20, 2026
This is pure imagination, but you don't have to look far beyond technical testing.
kruczekrobert commentedon May 23, 2026
I'm back again - does anyone see any reasons why I shouldn't re-upload the pull request as a proposal for review?
elchupanebrej commentedon May 25, 2026
In my opinion, allowing more than one docstring or data table per step could be valuable. It would make it possible to express richer context directly within a step, especially when the step needs more structured input.
Of course, a similar context can also be provided through Given steps. However, that approach has a trade-off: it often requires additional communication or state sharing between steps.
My personal approach, which may not be convenient for every project, is to place YAML inside a docstring and use it to pass whatever structured data the step needs.
kruczekrobert commentedon May 26, 2026
@elchupanebrej
Multi docstring/data table per step is a massive change, this issue is more about not blocking what should already be possible
kruczekrobert commentedon May 27, 2026
To give this issue some momentum, I'm re-launching the proposal.
cucumber/gherkin#599
mpkorstanje commentedon Jun 2, 2026
Haven't had chance to discuss this internally yet.
@kruczekrobert If you are going ahead, keep in mind that:
Effectively this means that Cucumber messages would need to be changed to include an optional index parameter for the data table and doc string arguments.
kruczekrobert commentedon Jun 3, 2026
Discuss, I will make changes.
mpkorstanje commentedon Jun 9, 2026
Had a chat internally.
We can continue, and for that the following has to be done:
cucumber/messagesto include information about the ordering of thePickleDocStringandPickleTable. Presumably by adding an optionalargumentIndexproperty. schema: Allow steps to contain both DataTable and DocString messages#468cucumber/gherkinto allow steps to contain both tables and doc strings. Allow steps to contain both DataTable and DocString gherkin#599cucumber/gherkin-utilsto properly format documentscucumber/cckwith a new sample that has a table and doc strings (both orders) Add example with both DocString and DataTable compatibility-kit#291cucumber/react-componentsto render steps with both arguments correctly Render both data table and doc string in source order react-components#570cucumber/html-formatterto render steps with both arguments correctly Upgrade react-components and compatibility-kit html-formatter#552cucumber/pretty-formatterRender doc string and data table arguments in argument order pretty-formatter#131Updatecucumber/json-formatterto render steps with both arguments correctlycucumber/cucumber-jsSupport steps with both a data table and a doc string cucumber-js#2967cucumber/javascript-coreSupport both datatable and docstring javascript-core#136cucumber/cucumber-nodeSupport steps with both a data table and a doc string cucumber-node#332cucumber/cucumber-jvm[Core] Support both DocString and DataTable arguments on steps cucumber-jvm#3213cucumber/cucumber-rubycucumber/godogAdd support for both DataTable and DocString in the same step godog#773cucumber.cucumber/websiteto describe that both tables and doc strings can be combinedThis is effectively a breaking change so it will go into a major release for
gherkinandmessages. We have another major change in progress, #2232, scheduling wise that one goes out first and independent from this change to avoid stalling that smaller change.mpkorstanje commentedon Jun 9, 2026
@kruczekrobert would you be willing to create a PR for
cucumber/messages?kruczekrobert commentedon Jun 19, 2026
@mpkorstanje I have to slow down a bit with my involvement here due to the issues with the individual startup product, but I will come back here if by then you don't post information here that someone has already started it, ok?