brine-dsl 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-gemset +1 -0
  3. data/Gemfile.lock +24 -75
  4. data/Rakefile +5 -29
  5. data/brine-dsl.gemspec +3 -5
  6. data/feature_setup.rb +17 -0
  7. data/lib/brine/requester.rb +27 -2
  8. data/lib/brine/step_definitions/request_construction.rb +5 -0
  9. data/lib/brine/test_steps.rb +8 -2
  10. data/lib/brine/type_checks.rb +2 -1
  11. data/lib/brine/util.rb +13 -3
  12. metadata +6 -145
  13. data/.gitignore +0 -3
  14. data/.travis.yml +0 -11
  15. data/CHANGELOG.md +0 -170
  16. data/Guardfile +0 -12
  17. data/LICENSE +0 -21
  18. data/README.adoc +0 -29
  19. data/config/cucumber.yml +0 -2
  20. data/docs/build.gradle +0 -19
  21. data/docs/cookbook.html +0 -643
  22. data/docs/gradle/wrapper/gradle-wrapper.jar +0 -0
  23. data/docs/gradle/wrapper/gradle-wrapper.properties +0 -6
  24. data/docs/gradlew +0 -172
  25. data/docs/gradlew.bat +0 -84
  26. data/docs/guide.html +0 -1220
  27. data/docs/index.html +0 -486
  28. data/docs/specs.html +0 -2066
  29. data/docs/src/cookbook.adoc +0 -160
  30. data/docs/src/guide.adoc +0 -524
  31. data/docs/src/index.adoc +0 -28
  32. data/docs/src/spec.erb +0 -121
  33. data/docs/src/specs.adoc +0 -37
  34. data/features/argument_transforms/boolean.feature +0 -37
  35. data/features/argument_transforms/datetime.feature +0 -45
  36. data/features/argument_transforms/integer.feature +0 -41
  37. data/features/argument_transforms/list.feature +0 -46
  38. data/features/argument_transforms/object.feature +0 -66
  39. data/features/argument_transforms/quoted.feature +0 -41
  40. data/features/argument_transforms/regex.feature +0 -40
  41. data/features/argument_transforms/template.feature +0 -46
  42. data/features/argument_transforms/whitespace.feature +0 -51
  43. data/features/assertions/is_a_valid.feature +0 -184
  44. data/features/assertions/is_empty.feature +0 -67
  45. data/features/assertions/is_equal_to.feature +0 -60
  46. data/features/assertions/is_including.feature +0 -34
  47. data/features/assertions/is_matching.feature +0 -35
  48. data/features/assertions/is_of_length.feature +0 -43
  49. data/features/assignment/parameter.feature +0 -20
  50. data/features/assignment/random.feature +0 -25
  51. data/features/assignment/response_attribute.feature +0 -33
  52. data/features/assignment/timestamp.feature +0 -33
  53. data/features/deprecations/replaced_with.feature +0 -53
  54. data/features/request_construction/basic.feature +0 -29
  55. data/features/request_construction/body.feature +0 -26
  56. data/features/request_construction/clearing.feature +0 -46
  57. data/features/request_construction/headers.feature +0 -94
  58. data/features/request_construction/params.feature +0 -60
  59. data/features/resource_cleanup/cleanup.feature +0 -86
  60. data/features/selectors/all.feature +0 -55
  61. data/features/selectors/any.feature +0 -48
  62. data/features/step_definitions/test_steps.rb +0 -5
  63. data/features/support/env.rb +0 -10
  64. data/tutorial/missing.feature +0 -5
  65. data/tutorial/post_matching.feature +0 -12
  66. data/tutorial/post_status.feature +0 -10
  67. data/tutorial/support/env.rb +0 -2
@@ -1,160 +0,0 @@
1
- = icon:cutlery[] Brine Cookbook
2
- Matt Whipple <http://github.com/mwhipple[@mwhipple]>
3
- :description: Cookbook for the Brine REST Testing DSL
4
- :keywords: Brine, Cucumber, REST, DSL
5
- :gh_repo: https://github.com/brightcove/brine
6
-
7
- == Overview
8
-
9
- The following are some recipes to address issues which may arise while using
10
- Brine but are not considered part of Brine's (current) responsibility.
11
- Many of these are focused on simplicity and ease rather than robustness or
12
- elegance, and modification to address specific cases should be expected.
13
-
14
- Many of these will also be platform specific and be subject to further
15
- organization once platforms beyond ruby are supported.
16
-
17
- == Intercepting of HTTP Calls
18
-
19
- === Context
20
-
21
- There may be cases where the request or reponse may need to be modified
22
- in some way before or after transmission, for example to add a custom header
23
- which is somehow specific to the testing configuration and therefore outside
24
- of anything that belongs in the specification.
25
-
26
- === Solution
27
-
28
- This can be done through the registration of custom Faraday middleware on
29
- the Brine client. All of the registered middleware attaches
30
- to the generated connection through an array of functions in
31
- {gh_repo}/blob/master/lib/brine/requester.rb[requester.rb].
32
- Each function accepts the connection object as its single parameter.
33
- The array of functions is exposed as `connection_handlers` and can be modified
34
- through getting that property from either the default `World`
35
- (for the default client) or from an appropriate `ClientBuilder`
36
- if creating custom clients and mutating it accordingly (setting the reference
37
- is not suported).
38
- You could just build your own client without the facilities provided by Brine.
39
-
40
- === Recipe
41
-
42
- An example to add a custom header could be implemented as follows:
43
-
44
- [source,ruby]
45
- ----
46
- require 'faraday'
47
- class CustomHeaderAdder < Faraday::Middleware
48
- def initialize(app, key, val)
49
- super(app)
50
- @key = key
51
- @val = val
52
- end
53
-
54
- def call(env)
55
- env[:request_headers].merge!({@key => @val})
56
- @app.call(env)
57
- end
58
- end
59
-
60
- ...
61
-
62
- connection_handlers.unshift(proc do |conn|
63
- conn.use CustomHeaderAdder, 'x-header', 'I am a test'
64
- end)
65
- ----
66
-
67
- == "Assurances"
68
-
69
- === Context
70
-
71
- Ideally all tests should be as self-contained and isolated as possible;
72
- when writing functional tests, however, there are cases where this isn't
73
- feasible or possible. In some cases a system depends on another external
74
- system which is not a system that is under test and which (for whatever reason)
75
- cannot be easily worked with. In white box testing such a system would likely be
76
- represented by some form of test double, but this may be unfeasible and/or
77
- undesirable when testing a deployed system.
78
-
79
- An example of such a system is user/account management which often incurs
80
- additional overhead to provision a new account. When testing a secured
81
- system valid accounts are needed for representative testing, but provisioning
82
- a new account may be difficult or outside the scope of the system that is being
83
- actively tested. If tested functionality involves enacting account-wide changes
84
- and the number of accounts is limited, then that is likely to unfortunately
85
- prevent complete test isolation.
86
-
87
- === Solution
88
-
89
- In such cases a standard solution is to designate certain resources to be
90
- reused for certain tests. These are analogous to the concept of "fixtures" in
91
- some test suites though there may be slight differences in implementation and
92
- reliance on them. Here the term "assurances" is used...primarily because it
93
- starts with `a` which lends itself to relevant files being listed towards the
94
- beginning alphabetically in a given directory.
95
-
96
- The goal of assurances is to specify conditions which are expected before other
97
- tests are to be run. Preferably the dependent tests should also explicitly
98
- declare the dependency but a significant solution for that is not established.
99
- Assurances therefore validate that preconditions are met; ideally if such
100
- preconditions can be established idempotently then the assurances can do so
101
- before the validation.
102
-
103
- ==== Assurances are NOT Tests
104
-
105
- **Assurances validate a state which is desired to be consistently retained
106
- within the system rather than being changed**. This means that they should _not_
107
- be used for tests as that would require state changes, nor should they clean up
108
- after themselves (as that would also imply a state change). If assurances are
109
- configured for a system which should also be tested, then appropriate tests
110
- should exist (including those that may validate any behavior relied upon by
111
- the assurance).
112
-
113
- ==== Consequences
114
-
115
- As mentioned previously assertions help in cases where tests cannot be fully
116
- isolated, and therefore some known state must be established and reused across
117
- tests (and such state should *not* change). A practical reason for this is to
118
- allow for overlapping test executions.
119
- If tests are not fully isolated, state is being changed, and test runs overlap,
120
- then tests may fail non-deterministically due to one test run pulling the state
121
- out from another. This in the simplest form can be a nuisance but it also
122
- effectively precludes the ability to speed up test runs through the use of
123
- parallelism/asynchronicity.
124
-
125
- _TODO: Enumerate drawbacks_
126
-
127
- === Recipe
128
-
129
- This can be done using standard cucumber tags. Assurances can be defined in
130
- designated `assure_*.feature` files where each Feature is appropriately tagged:
131
-
132
- [source,gherkin]
133
- ----
134
- @assure
135
- Feature: Some preconditions are verified...
136
- ----
137
-
138
- And then a Rake task is added to run those tagged features:
139
-
140
- [source,ruby]
141
- ----
142
- Cucumber::Rake::Task.new(:assure) do |t|
143
- t.cucumber_opts = "#{ENV['CUCUMBER_OPTS']} --tags @assure"
144
- end
145
- ----
146
-
147
- The Rake task that runs the other tests then depends on that task:
148
-
149
- [source,ruby]
150
- ----
151
- task :invoke_cuke => [:assure] do
152
- #Run cucumber, potentially in parallel and likely with --tags `@assure`
153
- end
154
- ----
155
-
156
- This approach tests preconditions and will avoid running the rest of the tests
157
- if they are not (relying on standard Rake behavior). The assurances can also be
158
- run with different Cucumber behavior so that the full test suite can be more
159
- stochastic (randomized/non-serialized) while the assurances can be more
160
- controlled.
@@ -1,524 +0,0 @@
1
- = icon:book[] Brine User Guide
2
- Matt Whipple <http://github.com/mwhipple[@mwhipple]>
3
- :description: The User Guide for using the Brine REST Testing DSL
4
- :keywords: Brine, Cucumber, REST, DSL
5
- :grave: `
6
- :response_attribute: (body|status|headers)
7
-
8
- Cucumber DSL for testing REST APIs
9
-
10
- == Introduction
11
-
12
- === Motivation
13
-
14
- REpresentational State Transfer APIs expose their functionality
15
- through combinations of fairly coarse primitives that generally
16
- revolve around the use of transferring data in a standard exchange
17
- format (such as JSON) using HTTP methods and other aspects of the very
18
- simple HTTP protocol. Tests for such an API can therefore be defined
19
- using a domain specific language (DSL) built around those higher level
20
- ideas rather than requiring a general purpose language (the equivalent
21
- of scripted `curl` commands with some glue code and assertions).
22
- This project provides such a DSL by using select libraries
23
- integrated into Cucumber, where Cucumber provides a test-oriented
24
- framework for DSL creation.
25
-
26
- === Sample Usage
27
-
28
- The general usage pattern revolves around construction of a request
29
- and performing assertions against the received response.
30
-
31
- [source,gherkin]
32
- ----
33
- When the request body is assigned:
34
- """
35
- {"first_name": "John",
36
- "last_name": "Smith"}
37
- """
38
- And a POST is sent to `/users`
39
- Then the value of the response status is equal to `200`
40
- And the value of the response body is including:
41
- """
42
- {"first_name": "John",
43
- "last_name": "Smith"}
44
- """
45
- ----
46
-
47
- === Key Features
48
-
49
- Variable Binding/Expansion::
50
- In cases where dynamic data is in the response or is desired for the
51
- request, then values can be bound to identifiers which can then be
52
- expanded using http://mustache.github.io[Mustache] templates in your
53
- feature files.
54
-
55
- Type Transforms::
56
- Different types of data can be expressed directly in the feature files
57
- or expanded into variables by using the appropriate syntax for that
58
- type.
59
-
60
- Type Coercion::
61
- Related to transforms, a facility to coerce types is also provided. This
62
- allows more intelligent comparison of inputs which have been transformed to a
63
- richer data type with those that have not been transformed (normally strings).
64
- As an example comparing a date/time value with a string will attempt to parse
65
- the string to a date/time so that the values can be compared using the proper
66
- semantics.
67
-
68
- <<_resource_cleanup>>::
69
- Tests are likely to create resources which should then be cleaned up,
70
- restoring the pre-test state of the system: steps to facilitate this
71
- are provided.
72
-
73
- Authentication::
74
- Presently OAuth2 is supported to issue authenticated requests during a
75
- test (likely using a feature `Background`).
76
-
77
- Request Construction and Response Assertion Step Definitions::
78
- The previous features combined with the library of provide steps should
79
- cover all of the functionality needed to exercise and validate all of
80
- the functionality exposed by your REST API.
81
-
82
- == Installation
83
-
84
- Brine is published as `brine-dsl` on rubygems, the page for which is
85
- at https://rubygems.org/gems/brine-dsl. The latest version and other
86
- gem metadata can be viewed on that page. Brine can be used by
87
- declaring that gem in your project Gemfile such as:
88
-
89
- [source,ruby]
90
- ----
91
- gem 'brine-dsl', '~> 1.0'
92
- ----
93
-
94
- (after version 1.0 is released).
95
-
96
- Brine can then be "mixed in" to your project (which adds assorted
97
- modules to the `World` and loads all the step definitions and other
98
- Cucumber magic) by adding the following to your `support/env.rb` or
99
- other ruby file:
100
-
101
- [source,ruby]
102
- ----
103
- require 'brine'
104
-
105
- World(brine_mix)
106
- ----
107
-
108
- Select pieces can also be loaded (to be documented). With the above,
109
- feature files should be able to be written and executed without
110
- requiring any additional ruby code.
111
-
112
- == Tutorial
113
-
114
- We'll write some tests against http://myjson.com/api
115
- (selected fairly arbitrary from the list at
116
- https://github.com/toddmotto/public-apis).
117
- The API is being explored for the sake of this tutorial,
118
- which also serves to bolster this library to support the effort.
119
-
120
- === Selecting a ROOT_URL
121
-
122
- Brine expects steps to use relative URLs. The feature files specify
123
- the behavior of an API (or multiple APIs), while the root of the
124
- URLs define where that API is, so this is a natural mapping.
125
- More practically, when developing an API it's likely to
126
- be promoted across various environments such as
127
- local, qa, stage, and production so having a parameterized root for
128
- the URLs eases this while encouraging inter-environment consistency.
129
-
130
- For simple cases where all tests are to be run against the same root,
131
- the root url can be specified with the environment variable `ROOT_URL`,
132
- such as `ROOT_URL=https://api.myjson.com/ cucumber`, or letting `rake`
133
- take care of this for you such as:
134
-
135
- [source,ruby]
136
- ----
137
- Cucumber::Rake::Task.new do
138
- ENV['ROOT_URL'] = 'https://api.myjson.com/'
139
- end
140
- ----
141
-
142
- which could then be called with `rake cucumber`. The rake approach
143
- can be extended for different tasks for each environment, each
144
- of which sets the appropriate environment variables allowing the
145
- test code itself to follow
146
- https://12factor.net/config[Twelve-Factor App guidelines]
147
- where Rake provides sugary convenience.
148
-
149
- === A Basic GET
150
-
151
- Most tests will involve some form of issuing requests and performing assertions
152
- on the responses. Let's start with a simple version of that pattern,
153
- testing the response status from a GET request.
154
-
155
- [source,gherkin]
156
- ----
157
- include::../../tutorial/missing.feature[]
158
- ----
159
-
160
- === A Write Request
161
-
162
- For POST, PATCH and PUT requests you'll normally want to include a request body.
163
- To support this, additional data can be added to the requests before they are
164
- sent (see <<_request_construction>>).
165
-
166
- [source,gherkin]
167
- ----
168
- include::../../tutorial/post_status.feature[]
169
- ----
170
-
171
- === Test Response Properties
172
-
173
- The API that was chosen for testing returns the link to the created resource
174
- which is based off of a generated id. That means that the exact response cannot
175
- be verified, but instead property based testing can be done to verify that the
176
- data is sane and therefore likely trustworthy. In this case we
177
- can check that the `uri` response child matches the expected pattern.
178
-
179
- [source,gherkin]
180
- ----
181
- include::../../tutorial/post_matching.feature[]
182
- ----
183
-
184
- ////
185
- === Known Response Data
186
-
187
- One of the simplest and most obvious things to test for is that the response
188
- contains data for which exact values are expected. Continuing from above we
189
- can check that the response body returns the fields that we provided.
190
-
191
- [source,gherkin]
192
- ----
193
- include::../../tutorial/post_including.feature[]
194
- ----
195
- ////
196
-
197
- == Environment Variables
198
-
199
- Some Brine behavior can be tuned by passing it appropriate environment
200
- variables, listed here.
201
-
202
- `BRINE_LOG_HTTP`::
203
- Output HTTP traffic to stdout. Any truthy value will result in request and
204
- response metadata being logged, a value of `DEBUG` (case insensitive) will
205
- also log the bodies.
206
-
207
- `BRINE_LOG_BINDING`::
208
- Log values as they are assigned to variables in Brine steps.
209
-
210
- == Language Conventions
211
-
212
- === The use of ``{grave}``s
213
-
214
- Backticks/grave accents are used as _parameter delimiters_. It is perhaps
215
- most helpful to think of them in those explicit terms rather than thinking of
216
- them as an alternate _quote_ construct. In particular quoting implies that the
217
- parameter value is a string value, while the step transforms allow for
218
- alternative data types.
219
-
220
- ``{grave}``s were chosen as they are less common than many other syntactical
221
- elements and also allow for the use of logically significant
222
- quoting within paremeter values while hopefully avoiding the need for escape
223
- artistry (as used for argument transforms).
224
-
225
- == Selection and Assertion
226
-
227
- As tests are generally concerned with performing assertions, a testing DSL
228
- should be able to express the variety of assertions that may be needed. Because
229
- these are likely to be numerous, it could easily lead to duplicated logic or
230
- geometric growth of code due to the combinations of types of assertions and the
231
- means to select the inputs for the assertion.
232
-
233
- To avoid this issue the concepts of selection and assertion are considered
234
- separate operations in Brine. Internally this corresponds to two steps: the
235
- first assigns a selector;
236
- the second passes the assertion to that selector which is responsible for
237
- applying the assertion against the selected value(s). In standard step use this
238
- will still be expressed as a single step,
239
- and dynamic step definitions are used to split the work appropriately.
240
-
241
- For example the step:
242
-
243
- [source,gherkin]
244
- ----
245
- Then the value of the response body is equal to `foo`
246
- ----
247
-
248
- Will be split where the subject of the step (`the value of the response body`)
249
- defines the selector and the predicate of the step
250
- `is equal to {grave}foo{grave}` defines the assertion (which is translated to a
251
- step such as `Then it is equal to {grave}foo{grave}`).
252
-
253
- The result of this is that the assertion steps will always follow a pattern
254
- where the subject resembles `the value of ...` and the predicate always
255
- resembles `is ...`. Learning the selection phrases and the assertion phrases
256
- and combining them should be a more efficient and flexible way to become
257
- familiar with the language instead of focusing on the resulting combined steps.
258
-
259
- The chosen approach sacrifices eloquence for the sake of consistency.
260
- The predicate will always start with `is` which can lead to awkward language
261
- such as `is including` rather than simply `includes`.
262
- The consistency provides additional benefits such as consistent modification:
263
- for instance `is not` can always be use for negation rather than working out the
264
- appropriate phrasing for a more natural sounding step (let alone the logic).
265
-
266
- One of the secondary goals of this is that assertion step definitions should
267
- be very simple to write and modifiers (such as negation) should be provided for
268
- free to those definitions.
269
- As assertion definitions are likely to be numerous and potentially customized,
270
- this should help optimize code economy.
271
-
272
- === Selection Modifiers
273
-
274
- To pursue economical flexibility Brine steps attempt to balance step definitions
275
- which accommodate variations while keeping the step logic and patterns fairly
276
- simple. Selection steps in particular generally accept some parameters that
277
- affect their behavior. This allows the relatively small number of selection
278
- steps to provide the flexibility to empower the more numerous assertion steps.
279
-
280
- ==== Traversal
281
-
282
- Selection steps can generally target the root of the object specified (such as
283
- the response body) or some nodes within the object if it is a non-scalar value
284
- (for instance a child of the response body). This is indicated in the
285
- <<_selection,step reference selection steps>> by the `[$TRAVERSAL]` placeholder.
286
- `child {grave}$EXPRESSION{grave}` or `children {grave}$EXPRESSION{grave}` can
287
- optionally be inserted at the placeholder to select nested nodes as described
288
- in <<_traversal_2>>.
289
-
290
- ==== Negation
291
-
292
- The selectors also currently handle negation of the associated assertions.
293
- This is potentially counter-intuitive but as previously mentioned the intent is
294
- that this should ease the creation of assertions. If negation is added to a
295
- selector that it is expected that the assertion will _fail_.
296
-
297
- Negation will be normally indicated in the
298
- <<_selection,step reference selection steps>> by the presence
299
- of the `[not]` placeholder. A similar placeholder may be used that is more
300
- readable but leads to an equivalent inversion of the semantics of the statement.
301
- To negate the step, the text within the ``[]``s should be inserted
302
- in the indicated position.
303
-
304
- [NOTE, caption='Future Versions']
305
-
306
- Handling this in the selectors is (as mentioned) counter-intuitive and
307
- unnecessarily couples the selector to the assertion. It is currently done for
308
- practical reasons but is likely to be replaced in a future version after (or as
309
- part of) the initial port of the library to another platform. When it is
310
- replaced, all existing steps will remain supported through at least one more
311
- major revision and most should (most should remain unchanged).
312
-
313
- === Chained Assertions
314
-
315
- [WARNING, caption='Unsupported Feature']
316
-
317
- Use at your own risk, this feature is *not presently supported*.
318
-
319
- For anyone that likes to live on the (relative) edge or if this gathers notable
320
- interest...the above also provides an implicit feature: after a value is
321
- selected multiple assertions could be performed against it.
322
-
323
- For instance:
324
-
325
- [source,gherkin]
326
- ----
327
- Then the value of the response body is equal to `foo`
328
- And it is of the type `String`
329
- ----
330
-
331
- Though this may work in simple cases the present design is likely to produce
332
- surprising results since some aspects (such as negation) are handled by the
333
- selector so it would be inherited by the conjunctions even though it wouldn't
334
- read that way.
335
-
336
- == Traversal
337
-
338
- The language exposed by Brine is flat but the data returned by the server is
339
- likely to include deeper data structures such as objects and collections. To
340
- allow selection within such structures a `traversal` language is embedded within
341
- some steps which will be indicated by the use of the `TRAVERSAL` placeholder.
342
-
343
- The traversal language consists of a selected subset of
344
- http://goessner.net/articles/JsonPath/[JsonPath].
345
-
346
- [NOTE, caption='The Selected Subset']
347
-
348
- The subset of JsonPath functionality has been chosen that is believed to support
349
- all needed test cases without requiring deep familiarity with JsonPath. This may
350
- lead to more numerous simple steps in place of fewer steps that use unsupported
351
- expressions. Additionally Brine is intended to be ported to a range of platforms
352
- and so only those steps outlined here will be supported across those platforms.
353
- JsonPath expressions _not_ listed below will not be explicitly disallowed but
354
- are not officially supported (will not be tested and will not be ported to
355
- another platform if needed).
356
-
357
- === Cardinality
358
-
359
- Each traversal expression will select _all_ matching nodes which is therefore
360
- represented as a collection. Often, however, only a single node is expected or
361
- desired. Therefore the traversal expression will also be accompanied by a phrase
362
- which defines the expected cardinality, normally `child` vs. `children`.
363
- `children` will _always_ return an array while `child` will return what would be
364
- the first element in that array. `child` should be used when accessing a
365
- specific node within the tree, while `children` should be used for what amounts
366
- to a query across multiple nodes (such as testing the value of a field for every
367
- element in a collection).
368
-
369
- === Expressions
370
-
371
- `.$KEY`::
372
- Access the `KEY` named child of the starting node. The leading `.` can be
373
- omitted if at the start of an expression.
374
-
375
- `.[$INDEX]`::
376
- Access the element of the array at index `INDEX`
377
-
378
- `.[$FROM:$TO]`::
379
- Access a slice of the array containing the elements at index `FROM` through
380
- `TO` (including both limits).
381
-
382
- == Resource Cleanup
383
-
384
- All test suites should clean up after themselves as a matter of hygiene and to
385
- help enforce test independence and reproducibility. This is particularly
386
- important for this library given that it is likely the systems under test
387
- are likely to remain running; accumulated uncleaned resources are at best a
388
- nuisance to have to weed through and at worst raise some costs or other due to
389
- heightened consumption of assorted resources (as opposed to more ephemeral test
390
- environments).
391
-
392
- Brine therefore provides mechanisms to assist in cleaning up those resources
393
- which are created as part of a test run. A conceptual hurdle for this type of
394
- functionality is that it is very unlikely to be part of the feature that is
395
- being specified, and therefore should ideally not be part of the specification.
396
- Depending on the functionality (and arguably the
397
- https://www.martinfowler.com/articles/richardsonMaturityModel.html[maturity])
398
- of the API, most or all of the cleanup can be automagically done based on
399
- convention. There are tentative plans to support multiple techniques for
400
- cleaning up resources based on how much can be implicitly
401
- ascertained...though presently there exists only one.
402
-
403
- === Step indicating resource to DELETE
404
-
405
- If the API supports DELETE requests to remove created resources but it is either
406
- desirable or necessary to specify what those resource PATHS are, a step can be
407
- used to indicate which resources should be DELETEd upon test completion.
408
-
409
- _see <<_cleanup,Cleanup Step Definitions>>_
410
-
411
- == Step Reference
412
-
413
- === Request Construction
414
-
415
- link:specs.html#_request_construction[icon:cogs[] Specification]
416
-
417
- The requests which are sent as part of a test are constructed using
418
- a https://en.wikipedia.org/wiki/Builder_pattern[Builder].
419
-
420
- `When a $METHOD is sent to {grave}$PATH{grave}`::
421
- As every request to a REST API is likely to have a significant
422
- HTTP `METHOD` and `PATH`, this step is considered required and is therefore
423
- used to send the built request. This should therefore be the *last* step for
424
- any given request that is being built.
425
-
426
- `When the request body is assigned:`::
427
- The multiline content provided will be assigned to the body of the request.
428
- This will normally likely be the JSON representation of data.
429
-
430
- `When the request query parameter {grave}$PARAMETER{grave} is assigned
431
- {grave}$VALUE{grave}`::
432
- Assign `VALUE` to the request query `PARAMETER`.
433
- The value will be URL encoded and the key/value pair appended to the URL using
434
- the appropriate `?` or `&` delimiter.
435
- The order of the parameters in the resulting URL should be considered
436
- undefined.
437
-
438
- `When the request header {grave}$HEADER{grave} is assigned {grave}$VALUE{grave}`::
439
- Assign `VALUE` to the request header `HEADER`.
440
- Will overwrite any earlier value for the specified header, including earlier
441
- steps or defaults.
442
-
443
- === Cleanup
444
-
445
- `When a resouce is created at {grave}$PATH{grave}`::
446
- Mark `PATH` as a resource to DELETE after the test is run.
447
- See <<_resource_cleanup>>
448
-
449
- === Assignment
450
-
451
- link:specs.html#_assignment[icon:cogs[] Specification]
452
-
453
- `When {grave}$IDENTIFIER{grave} is assigned {grave}$VALUE{grave}`::
454
- Assigns `VALUE` to `IDENTIFIER`.
455
-
456
- `When {grave}$IDENTIFIER{grave} is assigned a random string`::
457
- Assigns a random string (UUID) to `IDENTIFIER`.
458
- This is particularly useful to assist with test isolation.
459
-
460
- `When {grave}$IDENTIFIER{grave} is assigned a timestamp`::
461
- Assigns to `IDENTIFIER` a timestamp value representing the instant at
462
- which the step was evaluated.
463
-
464
- `When {grave}$IDENTIFIER{grave} is assigned the response {response_attribute} [$TRAVERSAL]`::
465
- Assigns to `IDENTIFIER` the value extracted from the specified response
466
- attribtute (at the optional traversal path).
467
-
468
- === Selection
469
-
470
- link:specs.html#_selection[icon:cogs[] Specification]
471
-
472
- _see <<_selection_and_assertion>>_
473
-
474
- _TODO: Replace all the explicit attributes._
475
-
476
- `Then the value of the response {response_attribute} is`::
477
- Select the sepecified attribute of the current HTTP response.
478
-
479
- `Then the value of the response body [$TRAVERSAL] is [not]`::
480
- Select the value from the body of the response.
481
-
482
- `Then the value of the response body [$TRAVERSAL] does have any element that is [not]`::
483
- Select any (at least one) element from the structure within the response body.
484
-
485
- `Then the value of the response body [$TRAVERSAL] has elements which are all`::
486
- Select all elements from the structure within the response body.
487
-
488
- === Assertion
489
-
490
- link:specs.html#_assertion[icon:cogs[] Specification]
491
-
492
- _see <<_selection_and_assertion>>_
493
-
494
- `Then it is equal to {grave}$VALUE{grave}`::
495
- Assert that the current selected value is equivalent to `VALUE`
496
-
497
- `Then it is matching {grave}$VALUE{grave}`::
498
- Assert that the current select value matches the regular expression `VALUE`
499
-
500
- `Then it is including {grave}$VALUE{grave}`::
501
- Assert that the current select value includes/is a superset of `VALUE`.
502
-
503
- `Then it is empty`::
504
- Assert that value is empty or null. Any type which is not testable for
505
- emptiness (such as booleans or numbers) will always return false. Null is
506
- treated as an empty value so that it can be treated as such for endpoints that
507
- return null in place of empty collections, and non-null empty values can
508
- easily be tested for using conjunction.
509
-
510
- `Then it is of length {grave}$VALUE{grave}`::
511
- Assert that the value exposes a length attribute and the value of that
512
- attribute is `VALUE`.
513
-
514
- `Then it is a valid {grave}$TYPE{grave}`::
515
- Assert that the selected value is a valid instance of a `TYPE`. Presently this
516
- is focused on standard data types (intially based on those specified by JSON),
517
- but it is designed to handle user specified domain types pending some minor
518
- wiring and documentation. The current supported types are:
519
- * `Object`: A JSON style object/associative array
520
- * `String`
521
- * `Number`
522
- * `Integer`
523
- * `Array`
524
- * `Boolean`