When I send a POST to the URL "/foo-resource/12"
--
Posting rules: http://cukes.info/posting-rules.html
---
You received this message because you are subscribed to the Google Groups "Cukes" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cukes+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
Matt,Can you explain why you "want it to show up inside the text of the scenario definition"?
What value does the actual UUID this give the readers of the scenario beyond saying "the UUID of foo-resource"?
On Wednesday, January 29, 2014 12:41:11 AM UTC-8, Seb Rose wrote:Matt,Can you explain why you "want it to show up inside the text of the scenario definition"?
What value does the actual UUID this give the readers of the scenario beyond saying "the UUID of foo-resource"?I suppose in the end it doesn't make a whole lot of difference, and it is just about the same to use something like "<fooResourceId>" in the url. What I really want to know is not so much how to get the string into the scenario -- but how to handle ids like these. Do you put them in the scenario (and modify the db to match that id); or do you put some generic text in the scenario (and keep the actual value in some hidden variable)? Or is there a better way? Is there a "best practices" for something like this?
On Wednesday, January 29, 2014 12:41:11 AM UTC-8, Seb Rose wrote:Matt,Can you explain why you "want it to show up inside the text of the scenario definition"?
What value does the actual UUID this give the readers of the scenario beyond saying "the UUID of foo-resource"?I suppose in the end it doesn't make a whole lot of difference, and it is just about the same to use something like "<fooResourceId>" in the url. What I really want to know is not so much how to get the string into the scenario -- but how to handle ids like these. Do you put them in the scenario (and modify the db to match that id); or do you put some generic text in the scenario (and keep the actual value in some hidden variable)? Or is there a better way? Is there a "best practices" for something like this?
On 29 January 2014 20:17, Matt Hauck <matt...@gmail.com> wrote:
On Wednesday, January 29, 2014 12:41:11 AM UTC-8, Seb Rose wrote:Matt,Can you explain why you "want it to show up inside the text of the scenario definition"?
What value does the actual UUID this give the readers of the scenario beyond saying "the UUID of foo-resource"?I suppose in the end it doesn't make a whole lot of difference, and it is just about the same to use something like "<fooResourceId>" in the url. What I really want to know is not so much how to get the string into the scenario -- but how to handle ids like these. Do you put them in the scenario (and modify the db to match that id); or do you put some generic text in the scenario (and keep the actual value in some hidden variable)? Or is there a better way? Is there a "best practices" for something like this?The general rule of thumb is to "avoid incidental details". The actual ID is incidental - the important thing is that the ID requested is the same as the one that is returned when the resource is created. Use domain language to describe this in the scenario and hide the implementation in the code.You could, for instance, pass the name "foo-resource" as an argument to your step definitions, storing the ID in a map when you create the resource and retrieving it on a get - thus freeing you up to deal with multiple, named resources without confusing the reader with impenetrable UUIDs
--
Posting rules: http://cukes.info/posting-rules.html
---
You received this message because you are subscribed to the Google Groups "Cukes" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cukes+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
On 30 January 2014 13:41, Roberto Lo Giacco <rlog...@gmail.com> wrote:
Il giorno mercoledì 29 gennaio 2014 22:58:48 UTC+1, Seb Rose ha scritto:On 29 January 2014 20:17, Matt Hauck <matt...@gmail.com> wrote:
On Wednesday, January 29, 2014 12:41:11 AM UTC-8, Seb Rose wrote:Matt,Can you explain why you "want it to show up inside the text of the scenario definition"?
What value does the actual UUID this give the readers of the scenario beyond saying "the UUID of foo-resource"?I suppose in the end it doesn't make a whole lot of difference, and it is just about the same to use something like "<fooResourceId>" in the url. What I really want to know is not so much how to get the string into the scenario -- but how to handle ids like these. Do you put them in the scenario (and modify the db to match that id); or do you put some generic text in the scenario (and keep the actual value in some hidden variable)? Or is there a better way? Is there a "best practices" for something like this?The general rule of thumb is to "avoid incidental details". The actual ID is incidental - the important thing is that the ID requested is the same as the one that is returned when the resource is created. Use domain language to describe this in the scenario and hide the implementation in the code.You could, for instance, pass the name "foo-resource" as an argument to your step definitions, storing the ID in a map when you create the resource and retrieving it on a get - thus freeing you up to deal with multiple, named resources without confusing the reader with impenetrable UUIDsMay I add that providing insight information on the resource ID format breaks the fundamental rule of REST to have totally transparent URIs?Your REST API users shouldn't be building their URIs, you should provide them all the necessary links (RMM level 3) but, in case you are not yet at that stage, it would really help to move toward that if your users don't make any assumption on the URI format: whatever is the value returned within the ID field is what they have to append to the retrievel URL:POST /foo <json-payload>201 CREATED<resource-id>GET /foo/<resource-id>200 OK<resource-representation>
<controversial>Personally I think putting url information in API tests is a bad idea. I see this as an implementation detail that is subject to alot of change. Requiring features to be re-written when implementation details change makes features much more expensive to live with. It also breaks DRY, as the detail is defined in (at least) two places.Instead I think features for api's should you use business language focusing on why you are talking to the api and what you are expecting from it. In this way you can explore the mapping between natural language 'I want a foo' and your api GET /foo. The features talk about why you want a foo, and what you expect to get from the foo, step definitions deal with GET'ing a foo and the technical contents of the response.So for me1. No URL's, id's in features2. No json response hashes etc. in featuresIf you want to test at that level use RSpec, and test much more in isolation.There is some more to this, things like thinking about version 2 of the API. Overall think about the cost of upkeep features like this impose on the API.</contreversial>HTH
You received this message because you are subscribed to a topic in the Google Groups "Cukes" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/cukes/yaAGaJ45XYU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to cukes+un...@googlegroups.com.
I would use:Given a resource foo with id 123 exists with the following data| attribute name | attribute value |...When the system receives a GET request for resource foo with id 123And the request content type is "application/xml"Then the response code is 200 OKAnd the response payload is```<xml here>```I wouldn't use a different terminology to abstract something like that in _this_ case, but it obviously depends on the parties involved on the spec definition.
--
Posting rules: http://cukes.info/posting-rules.html
---
You received this message because you are subscribed to the Google Groups "Cukes" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cukes+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
You received this message because you are subscribed to a topic in the Google Groups "Cukes" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/cukes/yaAGaJ45XYU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to cukes+un...@googlegroups.com.
You received this message because you are subscribed to the Google Groups "Cukes" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cukes+un...@googlegroups.com.
On Thursday, January 30, 2014 at 5:08 PM, George Dinwiddie wrote:
Matt,On 1/29/14, 12:15 AM, Matt Hauck wrote:I've run into this problem in the past and have run into it again so Ithought I'd ask the group and see if anyone has a better solution forthis issue than mine.So, I'm (again) using cucumber to spec a publicly facing backend RESTAPI. I quite like how I am able to specify the exact inputs and outputsof the API in full text so that consumers of the API can see exactlywhat needs to be input and what exactly they can expect as output.Anyhoo, part of this is that I want to be able to explicitly list outthe URL inside the step; something like:When I send a POST to the URL "/foo-resource/12"When you talk with the business people, do they *really* ask forsoftware in terms of POSTs and URLs? Or do they have some other languagethat they use to describe what they want to accomplish?- George
------------------------------------------------------------------------* George Dinwiddie * http://blog.gdinwiddie.comSoftware Development http://www.idiacomputing.comConsultant and Coach http://www.agilemaryland.org----------------------------------------------------------------------
--
On 30 January 2014 15:50, Roberto Lo Giacco <rlog...@gmail.com> wrote:
I would generally agree with you, but you still have to provide examples in order to be able to spec out your system. In this case the example might be expressed by using JSON or XML or any other data format which is clearly understood by the parties defining the specs.On an end user product I would use terms like "Click on the start button", "Select the filename field" and so forth, but on a REST API you have a predefined terminology which is the base of the convention:- resources and their identifiers (URI)- HTTP protocol (methods, response codes, headers, etc...)- content typesHow would you spec out that when your REST service receives a request for /foo/123 with a Content-Type header value of XML the response must be the XML representation of resource foo with ID 123?I wouldn't, not in a feature anyhow. Instead I would askWhy would anyone want a foo?
Who, or what, would want a foo?
How would I know what foo to get? (this touches on the idea of navigability of the service)
What is required to get a foo?id?authentication?
If I require something, say an id, how do I get it, how do I know I've got the right one, how do I stop people using the wrong one, what happens if someone uses the wrong one, why do I need an id, etc. etc.I feel this is the sort of information that should be captured and expressed in features.
If some of these questions were answered, then it would be possible to give foo context and meaning, and perhaps produce example scenarios that were more meaningful.Once you are 'stuck' in the implementation details of the service, it is really hard to see another way, particularly one that is so much more abstract; so I don't expect people to get this, hence the 'controversy'
I would use:Given a resource foo with id 123 exists with the following data| attribute name | attribute value |...When the system receives a GET request for resource foo with id 123And the request content type is "application/xml"Then the response code is 200 OKAnd the response payload is```<xml here>```I wouldn't use a different terminology to abstract something like that in _this_ case, but it obviously depends on the parties involved on the spec definition.--Posting rules: http://cukes.info/posting-rules.html
---
You received this message because you are subscribed to the Google Groups "Cukes" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cukes+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
You received this message because you are subscribed to a topic in the Google Groups "Cukes" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/cukes/yaAGaJ45XYU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to cukes+un...@googlegroups.com.
On Thu, Jan 30, 2014 at 11:50 PM, Andrew Premdas <apre...@gmail.com> wrote:
On 30 January 2014 15:50, Roberto Lo Giacco <rlog...@gmail.com> wrote:
I would generally agree with you, but you still have to provide examples in order to be able to spec out your system. In this case the example might be expressed by using JSON or XML or any other data format which is clearly understood by the parties defining the specs.On an end user product I would use terms like "Click on the start button", "Select the filename field" and so forth, but on a REST API you have a predefined terminology which is the base of the convention:- resources and their identifiers (URI)- HTTP protocol (methods, response codes, headers, etc...)- content typesHow would you spec out that when your REST service receives a request for /foo/123 with a Content-Type header value of XML the response must be the XML representation of resource foo with ID 123?I wouldn't, not in a feature anyhow. Instead I would askWhy would anyone want a foo?Because they want to use that resource. Being an API, there might be many different reasons behind it. Let me explain: I have a temperature sensor on my Arduino, why do I want to get its value? Well you might say I want to know the room temperature, or the chip temperature or the board temperature... but I might be interested in getting a soil temperature to adjust accordingly the soil moisture sensor readings. What matters with regards to the API is I want to get the temperature sensor reading.
This is different when I say the user is able to push the leftmost button to move to the previous menu item: that is a UI, which is linked to an objective, something you give to the user as an option, within a limited set of choices.
I'm not trying to be dogmatic here, I'm just trying to reinforce my feeling that an API shouldn't limit it's possible usages "by design".Who, or what, would want a foo?That's interesting: what if I answer as "the system implementing the API"? I mean, unless you want to differentiate your resource on a per authentication profile (I wouldn't do that as it prevents any caching system to step in and help your back end, I would rather provide different resources for different profiles) then it doesn't really matter who is requesting the resource.
How would I know what foo to get? (this touches on the idea of navigability of the service)Yes, this is something I would agree, and this is part of the API definition and what I believe it needs to be spec out, but by using examples....What is required to get a foo?id?authentication?Correct, I agree with that. Where I don't agree is on how you would write that....If I require something, say an id, how do I get it, how do I know I've got the right one, how do I stop people using the wrong one, what happens if someone uses the wrong one, why do I need an id, etc. etc.I feel this is the sort of information that should be captured and expressed in features.Again, we agree on this, but how would you describe these with examples?
If some of these questions were answered, then it would be possible to give foo context and meaning, and perhaps produce example scenarios that were more meaningful.Once you are 'stuck' in the implementation details of the service, it is really hard to see another way, particularly one that is so much more abstract; so I don't expect people to get this, hence the 'controversy'Here is where we strongly disagree, I believe because we have different points of view on what is "implementation details".When we say GET/POST/PUT/DELETE for a web application that is an implementation detail (99% of the times) because the user is not submitting such request, he is clicking on a button, typing something or interacting with visual objects somehow and the HTTP method used to communicate that UI information to the back-end is an implementation detail... even the existence of the back-end is an implementation detail!When you are interacting with a REST API, using a GET or a POST method *is not* anymore an implementation detail, that's one of the core distinguishing elements of REST concept!
The same *does not* applies to the URL you are requesting if your REST API implements a RMM level 3, but if it's a level 2 the previous might not be true.I believe you have to follow the usual rule of thumb: feature files should explicitly describe WHAT the api will do, not HOW it is going to be done.Why don't we try to put up an example on this?Suggestion: a REST API to calculate the distance between two locations capable of providing the response in XML or JSON using miles or kilometers.Let's use a feature file to describe this.... How would you do that?
In case some of you may not be aware of how the hack works and what the hell am I even talking about, allow me to illustrate it for you:
I've run into this problem in the past and have run into it again so I thought I'd ask the group and see if anyone has a better solution for this issue than mine.So, I'm (again) using cucumber to spec a publicly facing backend REST API. I quite like how I am able to specify the exact inputs and outputs of the API in full text so that consumers of the API can see exactly what needs to be input and what exactly they can expect as output.Anyhoo, part of this is that I want to be able to explicitly list out the URL inside the step; something like:When I send a POST to the URL "/foo-resource/12"The difficulty with this is that I do not know the value of "12" at the time of writing the steps because that gets generated randomly by the database, and it could obviously change every time the test is run, depending on what order the tests are run in. (To make matters worse perhaps, our code doesn't even use the id value, it uses a java.util.UUID.randomUUID()). The point is, it is a value different each time the test is run, but I still want it to show up inside the text of the scenario definition.I have come up with the following two ways to solve this in times past doing something similar with cucumber, but neither are entirely satisfying:1) Embed a substitution variable in the definitionUse something like "/foo-resource/:foo-id" in the scenario definition, and then do a string replacement in the step definition that swaps out ":foo-id" for the actual foo-id that was captured at some other step definition when the foo-resource was actually created. yuck. this is hard to follow and it just isn't a clean way of doing it.
2) Embed what the id should be in the creation step, and make the change in the databaseIn the step that creates the foo-resource, say something like: `When I create a foo-resource (with id "12")`, which follows the normal way of creating a foo-resource, and then sneaks into the database and updates the appropriate value to the expected id value. The problem with this is it requires backend manipulation doesn't follow the normal way of doing things and so is a bit funky.
This seems like a general enough problem that I'm hoping the community has a better answer than mine. Thanks for any help you may offer!
--
Posting rules: http://cukes.info/posting-rules.html
---
You received this message because you are subscribed to the Google Groups "Cukes" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cukes+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.