tavern icon indicating copy to clipboard operation
tavern copied to clipboard

Question about list slicing in response validaton using tavern.request_vars

Open adrpp opened this issue 1 year ago • 2 comments

Hello,

having a request consisting of top-level object holding a list, how do I refer to such list element in response validation using "{tavern.request_vars}" ?

tavern version: 2.11.0

example:

- name: some test
    request:
      url: <truncated>
      method: POST
      json:
        requestBodyList:
          - complexListElement:
              attribute: some_value
    response:
      status_code: 200
      json:
        responseBodyList:
          - attribute: "{tavern.request_vars.json.requestBodyList[0].attribute}" 

Output (with the syntax above, e.g. "{tavern.request_vars.json.requestBodyList[0].attribute}" ):

Errors:
E   tavern._core.exceptions.MissingFormatError: tavern.request_vars.json.requestBodyList[0].attribute
------------------------------ Captured log call -------------------------------
ERROR    tavern._core.dict_util:dict_util.py:41 Failed to resolve string '{tavern.request_vars.json.requestBodyList[0].attribute}' 
ERROR    tavern._core.dict_util:dict_util.py:44 Key(s) not found in format: tavern.request_vars.json.requestBodyList[0].attribute

Tested the other notation mentioned in docs, thing.nested.0, gives String.Formatter error, as mentioned in docs, this got most probably deprecated up from 1.0 version, e.g.

...
response:
      status_code: 200
      json:
        responseBodyList:
          - attribute: "{tavern.request_vars.json.requestBodyList.0.attribute}" 
field_name = 'tavern.request_vars.json.requestBodyList.0.attribute', args = []
kwargs = <truncated>

    def get_field(self, field_name, args, kwargs):
        first, rest = _string.formatter_field_name_split(field_name)
    
        obj = self.get_value(first, args, kwargs)
    
        # loop through the rest of the field_name, doing
        #  getattr or getitem as needed
        for is_attr, i in rest:
            if is_attr:
>               obj = getattr(obj, i)
E               AttributeError: 'BoxList' object has no attribute '0'

Didn't find an example for this in the docs, besides of https://tavern.readthedocs.io/en/latest/basics.html#response -> "thing.nested[0]" , however this applies to save keyword/section.

Is there known way how to achieve list slicing while using tavern.request_vars in the response.json section ?

Thanks for any hint, Regards, Adrian

adrpp avatar Jun 13 '24 11:06 adrpp

I've added some more tests/examples in https://github.com/taverntesting/tavern/pull/938 for this, it should work - I'm guessing it's not your actual data but in the example you've posted it's probably because you're missing the complexListElement element and it should be:

    response:
      status_code: 200
      json:
        responseBodyList:
          - attribute: "{tavern.request_vars.json.requestBodyList[0].complexListElement.attribute}" 

I don't know if there is a way this could be made more obvious to the end user though, it should already print what format vars are available if you have debug logging turned on

michaelboulton avatar Jun 16 '24 14:06 michaelboulton

Hi @michaelboulton,

sorry for the response delay in first place :) In meanwhile I've refactored the code to call custom callable to flatten the response object, so I had to refactor it back to be able to confirm that what you've written works well too :)

thanks for the support

adrpp avatar Jun 24 '24 10:06 adrpp

No problem, glad its working :confetti_ball:

michaelboulton avatar Sep 21 '24 17:09 michaelboulton