brine-dsl 0.8.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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`