#rest #scripting-language #api-testing #gherkin #request-headers #syntax-for-test

apirquest_core

ApiRquest is a library for testing Api Rest. Written in Rust, it allows you to use the Rhai scripting language to increase test flexibility. It uses Gherkin syntax for test scenarios.

3 unstable releases

0.7.1 Jun 25, 2025
0.6.3 Mar 30, 2025
0.6.2 Mar 9, 2025

#441 in HTTP server

Download history 4/week @ 2025-03-18 104/week @ 2025-03-25 38/week @ 2025-04-01 24/week @ 2025-04-08 15/week @ 2025-04-15 12/week @ 2025-04-22 5/week @ 2025-04-29 7/week @ 2025-05-06 24/week @ 2025-05-13 1/week @ 2025-05-20 18/week @ 2025-06-10 3/week @ 2025-06-17 157/week @ 2025-06-24 12/week @ 2025-07-01

190 downloads per month
Used in apirquest_bin

Apache-2.0

115KB
2K SLoC

ApiRquest_core

ApiRquest is a a library for testing Api Rest. Written in Rust, it allows you to use the Rhai scripting language to increase test flexibility. It uses Gherkin syntax for test scenarios.

Features

Example

Feature:  api.restful-api.dev

Background:
    # Use for command line
    # https://restful-api.dev/
    * def url = https://api.restful-api.dev
    * def load read_rhai("scripts_rhai/scripts.rhai")

@scenario_get
Scenario: get
    # Recovery of all items
    Given path /objects
    And header content-type: application/json
    And request
"""
"""
    When method get
    Then status 200
    And print "Response.response: ${response}"

@scenario_unknown_url
Scenario: Unknown url
    Given path /objectsx
    And header content-type: application/json
    And request
"""
"""
    When method get
    Then status 404
    And print "Response.response: ${response}"
    And match ${response} == {"timestamp":"#string","status": 404,"error":"Not Found","path":"/objectsx"}

Scripting with Rhai

ApiRquest use Rhai for scripting scenario.

Predefined variables

Variables can be used in Rhai scripts

Variable Description Example
status code status http 200
headers list of http request headers (map) #{"content-length": "105", "content-type": "application/json", "date": "Fri, 24 Jan 2025 20:58:48 GMT", "server": "Rocket"}
response The http response (string) {"date_event":"2025-01-24 20:55:00","temperature":20.05316,"humidite":60.10489,"sensor_name":"legardien"}
request_duration_millis Query duration in milliseconds (u128) 80

.Define the rhai script to load

    * def url = https://api.restful-api.dev
    * def load read_rhai("scripts_rhai/scripts.rhai")

.Call a function with a parameter

# index retrieval (id)
# Call a function with a parameter
And call id = get_json_field ${response} "id"

The id variable can be reused later in the delete operation.

.Path with a parameter

   And print "Delete ${id}"
   Given path /objects/${id}

Include ApiRquest in yours tests

use log::{debug, error};
use apirquest_core::Runner;

fn main() {
    log4rs::init_file("config/log4rs.yaml", Default::default()).unwrap();
    debug!("runner: apiRquest");
    debug!("Load script file: ../../features/api_restful_api.feature");
    let mut runner = Runner::new("./features/api_restful_api.feature".to_string());
    runner.tags(vec!["@scenario_get"]);
    let r = runner.run();

    r.unwrap_or_else(|e| error!("Error: {}", e))
}

Include ApiRquest in yours tests

  @scenario_call_read
    Scenario: Adding a new object
    Given path /objects
    And header content-type: application/json
    And request
    """
    {
       "name": "Apple MacBook Pro 16",
       "data": {
          "year": 2025,t
          "price": 1849.99,
          "CPU model": "Intel Core i9",
          "Hard disk size": "1 TB"
       }
    }
    """
    When method post
    Then status 200
    And print "Post Response.response: ${response}"
    And def rep_add = ${response}
    And def id = ${response/id}
    
    * def get_rep = read_call("features/api_restful_api_get.feature" id)
    And match ${get_rep/body} contains ${rep_add}

Using ApiRquest in a Cargo project

You can use apiRquest in your project to test your apirest.

[dev-dependencies]
apirquest_core = { version = "0.7.0" }
#[cfg(test)]
mod tests {
use log::error;
use super::*;

    #[test]
    fn runner_run() {
        let mut runner = Runner::new("my.feature".to_string());
        runner.tags(vec!["My@Scenario"]);
        let r = runner.run();
        
        r.map(|_| debug!("Success")).unwrap_or_else(|e| error!("Error: {}",e));
    }
}

Dependencies

~13–28MB
~417K SLoC