cucumber-api-steps
cucumber-api-steps copied to clipboard
Allow instance variables in paths (a la Chargify API docs)
For example, see: http://docs.chargify.com/api-charges#api-usage-json-charges-create
When I send a POST request with the json data to https://[@subdomain].chargify.com/subscriptions/[@subscription.id]/charges.json
I don't like the idea of using instance variables in cucumber scenarios. Cucumber steps should be written in business language and business language rarely operate with variables and instance variables.
/cc @jayzes
@kalys, in general I agree with you, but without more specifics your argument would be an argument against the entire cucumber-api-steps project.
Since this is a tool for specifying REST API's, it is accepted that the step definitions will be closer to the exact specification of the REST API rather than the exact business value. This tool gives you steps to commit HTTP verbs against URLs, in other words.
Now, in many cases, as you can see in the example from the Chargify API docs, portions of the URLs are going to be dependent on test state established in earlier givens, such as account ids. This pull request simply enables handling those situations in a way that would support the examples in the Chargify docs.
If you have a better idea how to support this common need, I'd love to hear it!
Thanks, -Marc
I'm not categorically opposed to having some sort of interpolatable marker(s) in paths and/or request bodies - I've definitely seen the need in my own scenarios - but I don't love the idea of step syntax being tied specifically to ruby instance variables. Can't find the article/post at the moment, but I remember something from Aslak a while back talking about the fact that instance variable carryover between steps works is something of a leaky implementation detail and should not necessarily be relied on to work consistently in future versions of Cucumber. That having been said, it's the most expedient way to accomplish this that I'm aware of, so I don't want to count it out entirely. To your point on specifying API interactions and that being closer to the implementation, I agree - my goal is to make it easy to have scenarios that read nicely for consumers of the API, so they can easily determine how interactions with it should go.
Back to the matter at hand, what are your thoughts on moving to some sort of intermediate syntax, maybe like Sinatra's routing syntax where you have parameter names prefixed with colons? That would decouple us a bit from the ivar syntax, but we could use the same sort of backend binding to ivars for the time being until something changes or a better way of achieving that some thing comes along.
@jayzes Can you give me an example of what you mean, in terms of a Given and a When which are exchanging an account.id
sort of field for use in the POST url?
I'm more than happy to switch my implementation to such an approach, but I need help to grasp:
- How do the steps share state, if not through instance vars?
- What does the colon prefixed syntax look like, and does it handle nested values, such as account.id?
Thanks, -Marc
I found a good article written by @jnicklas. http://www.elabs.se/blog/15-you-re-cuking-it-wrong
tldr: A step description should never contain regexen, CSS or XPath selectors, any kind of code or data structure. It should be easily understood just by reading the description.
Hi Kalys, I'm familiar with that article, but again it does not apply when the technical detail IS the feature, such as for an API.
If you'd be so kind, would you mind proposing a syntax for the use case at hand, specifying a REST API where some state (for example, id for a user created in the Given) must appear in the URL?
Thanks, -Marc
On Friday, March 15, 2013, Kalys Osmonov wrote:
I found a good article written by @jnicklas https://github.com/jnicklas. http://www.elabs.se/blog/15-you-re-cuking-it-wrong
tldr: A step description should never contain regexen, CSS or XPath selectors, any kind of code or data structure. It should be easily understood just by reading the description.
— Reply to this email directly or view it on GitHubhttps://github.com/jayzes/cucumber-api-steps/pull/15#issuecomment-14960163 .
Marc Siegel Technology Specialist American Technology Innovations
Email: [email protected] Phone: 1 (617) 399-8145 Cell: 1 (617) 223-1220 Fax: 1 (617) 334-7975
Ping. It's been three months, and there's been no answer to my questions in this discussion:
- @kalys - what does an API step look like, when one cannot provide the parameterized parts of the URL?
- @jayzes - how would steps share state, if not through instance variables, which is the official mechanism?
Can someone please point me to an example of an API of any basic complexity which is specified with this library? Much appreciated.
How about this approach? http://vimeo.com/30586709 around 15:54
I like the general idea, for sure. I guess the place I've always struggled with a feature like this is where to source the variables for interpolation. While I can't quite put my finger on it, there's something about trying to grab raw instance variables based on the interpolated string that seems inherently ugly or bad to me. Perhaps it's the potential for pollution of the local instance variable scope, or the possibility that you could potentially collide with cucumber internals and not necessarily know it.
I wonder if this approach combined with a step argument transform could be a nice clean solution. That way you can still inject customizations into the path based on templating, but it's up to you to figure out a strategy for managing the URL and scope instead of the gem deciding it.
Thoughts on that approach?
The step argument transform seems not working with doc string (triple quotes), where the interpolation is most needed.