Package: dasty-api
Dasty: Declarative API Scenario Testing in YAMLDasty is a Python package designed to simplify the process of testing APIs by allowing tests to be defined declaratively in YAML format. This approach enables easy-to-write, easy-to-read API test scenarios, making API testing more accessible and maintainable.FeaturesDeclarative Syntax: Define API tests in a simple, human-readable YAML format.Flexible Test Scenarios: Support various HTTP methods and validations.Easy Variable Substitution: Define and use variables within your YAML test scenarios.Dynamic Variable Passing Between Steps: Extract and reuse values from responses in subsequent steps.InstallationTo install Dasty, simply use pip:pipinstalldasty_apiUsageQuickstartThis repository comes with a sample server and Scenarios that can be used for quick hands-on sandboxing.To run these Scenarios, do the following:From theexamplessub-directorycd./examplesInstall the dependencies required for the examplespipinstall-rrequirements.txtRun the simple server. This will create a simple server that listens onlocalhost:2396python3simple_server.pyIn a new terminal, run the ScenarioRunnerpython3scenario_runner.pyIf successful, the output should look as follows:Running scenario Add, Get, and Delete Users defined in examples/scenarios/add_get_delete_users.yaml...
        Running step Reset the server's memory... Success ✅
        Running step Get existing users... Success ✅
        Running step Add a new user... Success ✅
        Running step Get existing users, check that Dave was added... Success ✅
        Running step Delete a user... Success ✅
        Running step Get existing users, check that Charlie was deleted... Success ✅
        Running step Try to delete a user that doesn't exist... Success ✅
Add, Get, and Delete Users Success ✅
Running scenario Sample Service: Health Checks defined in examples/scenarios/healthchecks.yaml...
        Running step Health Check... Success ✅
        Running step Readiness Check... Success ✅
Sample Service: Health Checks Success ✅Using dasty in your projectDasty allows you to define your API test scenarios in YAML files. Here's a basic example:name:"UsersService:HealthChecks"description:-"HealthchecksfortheUsersservice"variables:BASE_URL:"http://127.0.0.1:8003/api/v1/"steps:-name:"HealthCheck"method:"GET"url:"${BASE_URL}/healthz"expected_status_code:200-name:"ReadinessCheck"method:"GET"url:"${BASE_URL}/readyz"expected_status_code:200More examples can be found in theexamplessubdirectory.The recommended structure is creating a folder nameddasty_tests, containing a sub-folder namedscenarios, containing the Scenario YAML files, along with ascenario_runner.pyfile which looks like:fromdasty_api.ScenarioRunnerimportScenarioRunnerif__name__=="__main__":runner=ScenarioRunner("./scenarios")runner.run()Then, thedasty-testsfolder should look like:.
├── scenario_runner.py
└── scenarios
    ├── ...
    └── sample_scenario.yamlOncemain.pyis executed, the output should look as follows:╰─ python3 main.py                                              
Running scenario Users Service: Health Checks defined in scenarios/healthcheck_users.yaml...
        Running step Health Check... Success ✅
        Running step Readiness Check... Success ✅
Users Service: Health Checks Success ✅FeaturesDynamic Variable PassingDasty supports dynamic variable passing between steps in a scenario. This allows you to extract values from the response of one step and use them in subsequent steps. For example:steps:-name:"GetuserID"method:"GET"url:"${BASE_URL}/users/name=John"extract:-name:user_idfrom:id-name:"UsetheUserIDinanotherrequest"method:"GET"url:"${BASE_URL}/users/id=${user_id}"Response Validation FunctionsDasty supports a variety of response assertion features to validate API response content.response_includesFunctionThis assertion ensures specific content is included in the API response. It's essential for verifying the presence of expected data elements. For instance, to confirm that a user object is part of the response,response_includescan be used to assert its existence.Usage Example:-name:"Checkuserpresence"method:"GET"url:"${BASE_URL}/users"expected_status_code:200response_includes:users:-name:"Alice"In this example,response_includeswill validate that within theusersarray of the response, there is an entry with thenameattribute equal to "Alice".A practical example of this feature can be seen inthis scenarioresponse_excludesFunctionConversely, this assertion ensures that certain content is definitively absent from the response. It is invaluable for confirming that sensitive data is not exposed or to ensure that an entity has been properly removed or is not present.Usage Example:-name:"Validateuserabsence"method:"GET"url:"${BASE_URL}/users"expected_status_code:200response_excludes:users:-name:"Alice"Theresponse_excludesassertion checks that theusersarray in the response does not contain any object with anameattribute equal to "Alice".With these two assertions,response_includesandresponse_excludes, testing for both the presence and absence of data in your API responses becomes straightforward and clear, providing a robust method for validating the state and security of your API endpoints.A practical example of this feature can be seen inthis scenarioresponse_lengthFunctionDasty introduces theresponse_lengthfunction, enabling you to assert the length of specific fields within your API response. This is particularly useful for validating the size of arrays or strings in your response data, ensuring your API behaves as expected in terms of data quantity or size.Usage Example:To check the number of users returned by the API:-name:"Getexistingusers,checkthecount"method:"GET"url:"${BASE_URL}/users"expected_status_code:200response_length:users:4In this example, theresponse_lengthcheck validates that theusersfield in the response contains exactly 4 items.This functionality is crucial for scenarios where the quantity of returned data matters, such as checking pagination results or ensuring an API does not return excessive data.Practical Use ofresponse_lengthYou can combineresponse_lengthwith other features likeresponse_includesto not only validate the presence of certain data but also ensure the response contains the correct number of items.Combined Example:-name:"Verifyuserlistsizeandcontent"method:"GET"url:"${BASE_URL}/users"expected_status_code:200response_includes:users:-name:"Alice"response_length:users:4In this scenario, Dasty checks that theusersarray includes a user named "Alice" and also asserts that the total number of users in the array is 4.Withresponse_length, your testing becomes more robust, allowing you to enforce not just the quality but also the quantity of the data returned by your API.outputFunctionDasty also introduces an output function, enabling you to print values extracted from a response or any dynamic variable within the scenario. This feature is especially useful for debugging or when you need to log specific information.Usage Example:steps:-name:"EchoAlice'sID"method:"POST"url:"${BASE_URL}/echo"expected_status_code:200request_body:alice_id:"${alice_id}"output:-"Alice'sIDis${alice_id}"Results in:Running step Echo Alice's ID... Success ✅
            Outputs:
            - Alice's ID is 0This feature enhances the debugging capabilities within your testing scenarios, making it easier to trace and understand the flow of data.Variable Value AssertionsexpectFunctionYou can now perform direct comparisons of extracted variables against expected values within your scenarios. This adds an extra layer of validation to your tests, ensuring not only that your API responds correctly, but also that the content of the responses holds the expected values.Equality Check (eq)Theeqoperator is used to assert that a variable is equal to a specified value.Usage Example:-name:"CheckAlice'sIDis0"method:"GET"url:"${BASE_URL}/users/name=Alice"expected_status_code:200extract:-name:alice_idfrom:user.idexpect:-variable:${alice_id}operator:eqvalue:"0"In this example, the scenario validates that the ID of the user Alice is exactly0.Inequality Check (ne)Conversely, theneoperator is used to assert that a variable is not equal to a specified value.Usage Example:-name:"CheckBob'sIDisNOT0"method:"GET"url:"${BASE_URL}/users/name=Bob"expected_status_code:200extract:-name:bob_idfrom:user.idexpect:-variable:${bob_id}operator:nevalue:"0"In this example, the scenario verifies that the ID of the user Bob is not0.Tag-Based Scenario ExecutionYou can assign one or more tags to each scenario in your testing suite. Tags are used to categorize and selectively run scenarios based on your current testing needs.Defining Tags in a Scenario:name:"Add,Get,andDeleteUsers"description:-"Gettheexistingusers,confirmingthatAlice,Bob,andCharliearepresent"tags:-"example"In this example, the scenario is tagged with"example".Running Scenarios Based on TagsWhen initializing theScenarioRunner, you can specify a list of tags. The runner will then execute only those scenarios that share at least one tag with this list. This allows for targeted testing of specific parts of your application.Example Initialization:ScenarioRunner(directory="...",tags=["example"])Scenarios with at least one common tag with the runner's tags will be included in the test run.Special Tag:ignoreIf a scenario is tagged withignore, it will be excluded from all test runs, regardless of other tags it might have. This is useful for temporarily disabling certain scenarios without removing them from the suite.Example of Ignored Scenario:name:"TemporarilyDisabledTest"tags:-"ignore"With tag-based scenario execution, Dasty provides a more dynamic and controlled testing environment, allowing you to focus on specific areas of your application as needed.