-
Notifications
You must be signed in to change notification settings - Fork 4
Writing Your First Test As Python Code
Now that we now how to navigate Hedra's built in documentation, let's write our first test as Python code! To begin, create a file called my_test.py by running the command:
touch my_test.py
Let's then adding the following imports at the top of the file:
from hedra.testing import ( ActionSet, use, action, Test )
We'll be introducing parts of Hedra's Testing library piece by piece here, starting with test configuration via the Test class. Add the following code below the imports:
class Config(Test): embedded_stats=True engine_type='fast-http' batch_size=8000 batch_time=10 total_time="00:01:00" reporter_type="statstream" reporter_config={ "save_to_file": True }
We begin by creating a Config class that inherits the Test class, then specify several class parameters as below:
-
embedded_stats - Runs an embedded instance of Statserve, a GRPC-based streaming stats computation service, for results calculation.
-
engine_type - The type of engine we wish to use, analogous to the --engine CLI argument.
-
batch_size - The size of each concurrent "batch".
-
batch_time - The amount of time Hedra will wait for a batch to complete before moving on to the next batch.
-
total_time - The total amount of time the test should run.
-
reporter_type - Which Reporter we want to use.
-
reporter_config - The config required by the selected Reporter.
Hedra knows to automatically import the class inheriting the Test class prior to running any test specified in the file, and will consume the configuration specified.
Note that you can only specify one such class per test file, and that Hedra will apply the specified configuration to all tests specified within the given file. This is to ensure streamlined execution of code-based tests.
Next, lets declare our test! Much like with the Test class, we'll create a class that inherits the ActionSet class:
class ExampleTest(ActionSet): pass
As with the Config class, Hedra will automatically import the class inheriting the ActionSet class. However, unlike the Config class, we can declare as many classes that inherit from the ActionSet class as we want. This allows us to write independent workflows and organize tests as independent modules.
Let's take the next step in writing our test by utilizing the use "hook" to make our ExampleTest class aware of the test configuration.
@use(Config) class ExampleTest(ActionSet): pass
Hooks are functions provided by the Hedra's Testing library that wrap classes or functions, providing an accessible interface by which we can configure and specify test or individual action behavior. In the example above, we wrap our ExampleTest class with the use() hook, passing our Config class. This makes the configuration available to the ExampleTest class and provides pre-configured internal objects (such as an HTTP client session) to the selected engine.
The use() hook also allows us to (optionally) pass custom session objects for certain engines, however for this example we won't be needing this functionality.
Let's next write our first as-code action. Actions are specified as async methods of a given class that inherits from ActionSet wrapped in the action() hook.
@use(Config) class ExampleTest(ActionSet):
@action('httpbin_get')
async def httpbin_get(self):
return await self.execute({
'method': 'GET',
'endpoint': '/get',
'host': '<https://httpbin.org'>
})
Here, we define an action called httpbin_get that makes a GET request to https://httpbin.org/get, return the result once completed. We declare the action as asynchronous method with no additional parameters, wrapping the method in the action() hook and passing the name of the action to the hook (this is a required argument for the action() hook). Within the method, we call the execute() method, which is inherited from the ActionSet class, passing a Python dictionary containing the data required by an action for the engine type selected.
Now that we completed writing our test, let's run it! In your terminal, run the following command:
hedra --code-filepath my_test.py
Hedra will first boot up the embedded instance of Statserve, then run the stages specified for the pipeline (setup, execute, and results in this case). Beginning with the setup stage, Hedra will parse the config specified by our Config class as well as the action(s) specified by our ExampleTest class. Upon parsing the config and actions, Hedra will then setup and configure the Persona and Engines specified.
Note that we did not specify a Persona in our Config class, so Hedra will utilize the Default persona. Had we explicitly specified a Persona as a class attribute of our Config class, Hedra would have used that Persona instead.
Next, Hedra will begin executing the test utilizing the fast-http engine we specified.
Hedra will execute tests in concurrent batches of the size we specified in our Config class, waiting the amount of time (in seconds) we likewise specified for each batch to complete before moving on to the next batch. Upon completion of a batch, Hedra will check to make sure it has not exceeded the total execution time we provided to the Config class, exiting the execution stage and returning non-aggregated results for processing during the results stage.
During the results stage, Hedra will aggregate results. Hedra will then submit aggregated results via the Reporter for storage.
By default, Hedra will utilize the Statstream Reporter and will output aggregated results to a JSON results.json file in the same directory in which the hedra command was run.
Upon completing the results stage, Hedra will then exit.
Congratulations! You have run your first test! In summary, we wrote the test below in a file my_test.py:
from hedra.testing import ( ActionSet, use, action, Test )
class Config(Test): embedded_stats=True engine_type='fast-http' batch_size=8000 batch_time=10 total_time="00:01:00" reporter_type="statstream" reporter_config={ "save_to_file": True }
@use(Config) class ExampleTest(ActionSet):
@action('httpbin_get')
async def httpbin_get(self):
return await self.execute({
'method': 'GET',
'endpoint': '/get',
'host': '<https://httpbin.org'>
})
Then ran the command:
hedra --code-filepath my_test.py
Upon which Hedra automatically imported and executed the test based upon the actions and configuration specified.