Scripting
Scripting involves writing code to automate, test, and customize API requests and responses. These scripts can be used to set variables to Stores, authentication, extract data from responses, perform conditional logic, testing API and more.
How to use?
Here is a complete example:
# 'ctx' (context) is imported automatically
# or import them directly:
# from zapy.ctx import hooks, store
# import any library on your venv or local modules
from decimal import Decimal
import unittest
import my_local_module
# print logs to Response Console
print("Hello world")
# use 'ctx.store' to store and retrieve variables among requests
ctx.store.my_var = Decimal('0.1')
ctx.store['my_var_2'] = Decimal('0.2')
# Use the lifecycle hooks to modify, debug or test
@ctx.hooks.pre_request
async def on_pre_request(httpx_args):
print("pre_request")
@ctx.hooks.post_request
async def on_response(httpx_response):
print("post_request")
# example, persist the id to use on other request
ctx.store['my_saved_id'] = httpx_response.data.id
@ctx.hooks.test
class TestResponse(unittest.TestCase):
def test_status_code(self):
self.assertEqual(self.response.status_code, 200)
Request Context module
This module is automatically imported on each request as ctx
. It contains the following variables:
hooks
pre_request
: decorator for async or sync functionpost_request
: decorator for async or sync functiontest
: decorator for testing. Cannot be async
store
auto
: special function used for inferring the header Content-Typeload_file
: special function used for loading files on body with Content-Type asmultipart/form-data
Hooks
All request script hooks are optional and should register only once. These hooks are applied only to the current request. Hooks are triggered at a specific time in a request lifecycle:
- evaluate script
- declare variables
- pre_request hook
@ctx.hooks.pre_request
- send request
- post_request hook
@ctx.hooks.post_request
- test hook
@ctx.hooks.test
pre_request
@ctx.hooks.pre_request
async def on_pre_request(httpx_args):
print("pre_request")
post_request
@ctx.hooks.post_request
async def on_response(httpx_response):
print("post_request")
# example, persist the id to use on other request
ctx.store['my_saved_id'] = httpx_response.data.id
test
Register a unittest.TestCase
class. It contains special attributes such as:
self.response
: thehttpx
responseself.request
: thehttpx
requestself.httpx_args
: thehttpx
request arguments forhttpx.Request
andclient.send
See more info on testing.
# test hook expects a unittest.TestCase class, cannot be async
import unittest
@ctx.hooks.test
class TestResponse(unittest.TestCase):
def test_status_code(self):
self.assertEqual(self.response.status_code, 200)
Stores
Store is the mechanism to persist and share variables among requests. Use ctx.store
to store and retrieve variables among requests. Read more here.
ctx.store.my_var = Decimal('0.1')
ctx.store['my_var_2'] = Decimal('0.2')
And then access use the variable on the next requests
my_var: {{ ctx.store.my_var }}
Printing
To show information on the Console tab use the print
function.
print('hello world')
Importing modules
Note
Importing local modules requires the use of a main file.
Printing (stdout) on imported modules won't be on the Console tab, they will appear on the terminal.
Import local modules by using a path relative to the main file.
For example, if we have the following files:
my_main.py # Main file for starting the server
my_module.py # Local module at same level
test_dir/
__init__.py
test_dir_1.py # Local module inside directory (aka package)
Then, we can import as:
# installed library
import httpx
# local module
import my_module
# local package
import test_dir.test_dir_1
# or
from test_dir import test_dir_1