{"id":13395392,"url":"https://github.com/eykrehbein/strest","last_synced_at":"2025-09-28T21:30:56.179Z","repository":{"id":57163127,"uuid":"147927875","full_name":"eykrehbein/strest","owner":"eykrehbein","description":"⚡️ CI-ready tests for REST APIs configured in YAML","archived":true,"fork":false,"pushed_at":"2020-03-14T20:41:19.000Z","size":319,"stargazers_count":1737,"open_issues_count":21,"forks_count":60,"subscribers_count":28,"default_branch":"master","last_synced_at":"2024-05-18T18:02:40.770Z","etag":null,"topics":["cli","javascript","nodejs","rest-api","test-automation","testing","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eykrehbein.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-09-08T11:33:38.000Z","updated_at":"2024-04-28T17:08:55.000Z","dependencies_parsed_at":"2022-09-01T17:31:23.817Z","dependency_job_id":null,"html_url":"https://github.com/eykrehbein/strest","commit_stats":null,"previous_names":["eykhagen/strest"],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eykrehbein%2Fstrest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eykrehbein%2Fstrest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eykrehbein%2Fstrest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eykrehbein%2Fstrest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eykrehbein","download_url":"https://codeload.github.com/eykrehbein/strest/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234563140,"owners_count":18853060,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","javascript","nodejs","rest-api","test-automation","testing","typescript"],"created_at":"2024-07-30T17:01:56.116Z","updated_at":"2025-09-28T21:30:50.741Z","avatar_url":"https://github.com/eykrehbein.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","cli"],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n  \u003cimg src=\"https://res.cloudinary.com/eykhagen/image/upload/v1536487016/logo.png\" height=\"300\" width=\"300\"/\u003e\n  \u003cp align=\"center\" style=\"font-size: 0.5em\"\u003e:rocket: Flexible REST Tests\u003c/p\u003e\n\u003c/h1\u003e\n\n![](https://img.shields.io/github/license/eykrehbein/strest.svg)\n![](https://img.shields.io/github/package-json/v/eykrehbein/strest.svg)\n![](https://img.shields.io/npm/v/@strest/cli.svg)\n\n**:link: Connect multiple requests**: _Example_ Embed an authorization token you got as a response from a login request in your following requests automatically\n\n**:memo: YAML Syntax**: Write all of your tests in YAML files\n\n**:tada: Easy to understand**: You'll understand the concept in seconds and be able to start instantly (seriously!)\n\n## Try it with Gitpod\n\n[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io#https://github.com/eykrehbein/strest)\n\nRun some Tests\n\n```bash\nnpm i -g @strest/cli\nstrest tests/success/postman.strest.yml\n```\n\n## Getting Started in your own environment\n\n```bash\n# Via Yarn\nyarn global add @strest/cli\n```\n\n```bash\n# Via npm\nnpm i -g @strest/cli\n```\n\n```bash\n# Via Docker\n# The image contains everything in the tests directory\ndocker run -it eykrehbein/strest:latest strest tests/success/chaining/\n\n# Bring your own test and environment\ndocker run -it --env STREST_URL=https://jsonplaceholder.typicode.com -v ${PWD}:/app/data eykrehbein/strest:latest strest /data/tests/success/Env/\n```\n\nWe'll be using the [postman-echo](https://docs.postman-echo.com) test API in this tutorial.\n\nTo get started, we're using [this file](tests/success/postman.strest.yml) _(The extension needs to be `.strest.yml` or `.strest.yaml`)_\n\n```yaml\nversion: 2                            # only version at the moment\n\nrequests:                             # all test requests will be listed here\n  testRequest:                        # name the request however you want\n    request:\n      url: https://postman-echo.com/get  # required\n      method: GET                       # required\n      queryString:\n      - name: foo1\n        value: bar1\n      - name: foo2\n        value: bar2\n    # log: true # uncomment this to log the response\n```\n\nTo run the test, open your terminal and type\n\n```bash\nstrest tests/success/postman.strest.yml\n```\n\nYou may also run multiple test files at the same time by pointing to the directory, where the files are stored\n\n```bash\nstrest tests/success/chaining\n# or\nstrest # this will recursively search for all .strest.yml files in the cwd and it's subdirectories\n```\n\nSuccess! If you've done everything correctly, you'll get a response like this\n\n```shell\n[ Strest ] Found 4 test file(s)\n[ Strest ] Schema validation: 4 of 4 file(s) passed\n\nExecuting tests in ./\n✔ Testing login succeeded (0.463s)\n✔ Testing verify_login succeeded (0.32s)\n✔ Testing verify_login_chained succeeded (0.233s)\nExecuting tests in: ./var/\n✔ Testing chaining_var1 succeeded (0.128s)\n✔ Testing chaining_var2 succeeded (0.131s)\n\n[ Strest ] ✨  Done in 1.337s\n```\n\n## Writing .strest.yml test files\n\nThe examples in [tests/success](tests/success/) are used for testing this library. Read through the examples to see what is possible.\n\n## VS Code extension\n\nSend requests directly from the yml file.\n\n[source](https://github.com/jgroom33/vscode-strest-client)\n\n[extension](https://marketplace.visualstudio.com/items?itemName=jgroom.strest)\n\n![alt text](https://raw.githubusercontent.com/jgroom33/vscode-strest-client/master/images/strest_preview.gif \"extension demo\")\n\n## Documentation\n\n- [How to write Tests](SCHEMA.md)\n- [Validation Types](VALIDATION.md)\n- [Examples](tests/success/)\n\n## Using \u0026 Connecting multiple requests\n\nWith traditional tools like [Postman](https://www.getpostman.com/) or [Insomnia](https://insomnia.rest/) it's common to perform only a single request at a time. Moreover, you have to trigger each request on your own with a click on a button.\n\nWith __Strest__ you're able to predefine a very well structured test file once, and every time you make any changes to your API you can test it with just one command in your terminal. Additionally, you can add hundreds or thousands of requests and endpoints which will run synchronously one after the other.\n\nTo create multiple requests, simply add multiple entries into the `requests` yaml object.\n\n```yaml\nversion: 2\n\nrequests:\n  requestOne:\n    ...\n  requestTwo:\n    ...\n  requestThree:\n    ...\n```\n\nRunning this will result in something like\n\n```shell\n[ Strest ] Found 1 test file(s)\n[ Strest ] Schema validation: 1 of 1 file(s) passed\n\n✔ Testing requestOne succeeded (0.1s)\n✔ Testing requestTwo succeeded (0.32s)\n✔ Testing requestThree succeeded (0.11s)\n\n[ Strest ] ✨  Done in 0.62s\n```\n\n### Chaining multiple requests\n\n**What is meant by _chaining multiple requests_?**\n\nChaining multiple requests means that you write a request and in each of the following requests you are able to use and insert any of the data that was responded by this request.\n\nEach reponse is stored as a dictionary for future requests to use.  The format is [HAR](http://www.softwareishard.com/blog/har-12-spec/#response).  This format is used by browsers to store request and response history.\n\n```json\n{\n  \"login\": {\n    \"status\": 200,\n    \"statusText\": \"OK\",\n    \"headers\": {\n      \"content-type\": \"application/json; charset=utf-8\",\n      \"date\": \"Mon, 12 Nov 2018 19:04:52 GMT\",\n      \"vary\": \"Accept-Encoding\",\n      \"content-length\": \"22\",\n      \"connection\": \"Close\"\n    },\n    \"content\": {\n      \"authenticated\": true\n    }\n  }\n}\n```\n\n#### Chaining Example\n\n```yaml\nrequests:\n  login: # will return { authenticated: true }\n    ...\n  authNeeded:\n    request:\n    ...\n      headers:\n      - name: Authorization\n        value: Bearer \u003c$ login.content.authenticated $\u003e  # It's possible to use the status code, headers, and status text from previous calls.\n```\n\nAs you could see, the usage is very simple. Just use `\u003c$ requestName.content.jsonKey $\u003e` to use any of the JSON data that was retrieved from a previous request. If you want to use raw data, just use `\u003c$ requestName.content $\u003e` without any keys.\n\nYou can use this syntax __*anywhere*__ regardless of whether it is inside of some string like `https://localhost/posts/\u003c$ postKey.content.key $\u003e/...` or as a standalone term like `Authorization: \u003c$ login.content.token $\u003e`\n\nThis can also be used across files as demonstrated [here](tests/success/chaining)\n\n### JsonPath\n\nUse JsonPath to extract specific data from previous.  [This](https://github.com/dchester/jsonpath) library is used.\n\n```yaml\nversion: 2\nrequests:\n  set_JsonPath:\n    request:\n      url: https://jsonplaceholder.typicode.com/posts\n      method: POST\n      postData:\n        mimeType: application/json\n        text:\n          firstName: John\n          lastName: doe\n          age: 26\n          address:\n              streetAddress: 'naist street'\n              city: Nara\n              postalCode: 630-0192\n          phoneNumbers:\n              - {type: iPhone, number: 0123-4567-8888}\n              - {type: home, number: 0123-4567-8910}\n  JsonPath:\n    request:\n      url: https://postman-echo.com/get\n      method: GET\n      queryString:\n      - name: foo\n        value: \u003c$ JsonPath(\"set_JsonPath.content.phoneNumbers[?(@.type == \\\"home\\\")].number\") $\u003e\n    validate:\n    - jsonpath: content.args.foo\n      expect: 0123-4567-8910\n\n```\n\nPractice [here](http://jsonpath.com/)\n\n## Using random values with Faker\n\nIf you need to generate some random values, you are able to do so by using [Faker API](http://marak.github.io/faker.js/) templates.\n\n### Example - Faker\n\n```yaml\nversion: 2\n\nrequests:\n  fake:\n    request:\n      url: https://postman-echo.com/get\n      method: GET\n      queryString:\n        - name: first\n          value: \u003c$ Faker(\"name.firstName\") $\u003e\n        - name: first_last\n          value: \u003c$ Faker(\"name.firstName\") $\u003e \u003c$ Faker(\"name.lastName\") $\u003e\n    log: true\n```\n\nVisit [Faker.js Documentation](http://marak.github.io/faker.js/) for more methods\n\n## Replacing values with predefined environment variables\n\n### Example - Environment Variables\n\n```bash\nexport STREST_URL=https://jsonplaceholder.typicode.com\nstrest tests/success/Env/environ.strest.yml\n```\n\n```yaml\nversion: 2\n# ensure the ENV var is set: `export STREST_URL=https://jsonplaceholder.typicode.com`\nrequests:\n  environment:\n    request:\n      url: \u003c$ Env(\"STREST_URL\") $\u003e/todos/1\n      method: GET\n```\n\n## Replacing values with predefined custom variables\n\n### Example - User Defined Variables\n\n```yml\nversion: 2\n\nvariables:  # Define variables here\n  testUrl: https://jsonplaceholder.typicode.com/todos/1\n  to_log: true\n\nrequests:\n  my_variable_request:\n    request:\n      url: \u003c$ testUrl $\u003e\n      method: GET\n    log: \u003c$ to_log $\u003e\n\n```\n\n## Only Execute If\n\nWith **Strest** you can skip a response by setting a match criteria\n\n```yaml\nversion: 2\n\nrequests:\n  if_Set:\n    request:\n      url: https://jsonplaceholder.typicode.com/posts\n      method: POST\n      postData:\n        mimeType: application/json\n        text:\n          foo: 1\n  skipped:\n    if:\n      operand: \u003c$ if_Set.content.foo $\u003e\n      equals: 2\n    request:\n      url: https://jsonplaceholder.typicode.com/todos/2\n      method: GET\n  executed:\n    if:\n      operand: \u003c$ if_Set.content.foo $\u003e\n      equals: 1\n    request:\n      url: https://jsonplaceholder.typicode.com/todos/2\n      method: GET\n```\n\n## Use strest file name as parameter in the tests\nYou can use the strest file name as a parameter in the tests .\n\n*note* that the strest suffix is removed \n\n**Usage**\nThe file name for this example is postman-echo.strest.yml\n\n```yml\nversion: 2                            \nrequests:                             \n  test-file-name:                       \n    request:\n      url: https://\u003c$ Filename() $\u003e.com/get  \n      method: GET                       \n    validate:\n    - jsonpath: status\n      expect: 200\n```\n\n## Using dates and dates format \nYou can insert dates times plus format them using the custom [nunjucks date filter](https://www.npmjs.com/package/nunjucks-date)\nunder the hood its a wrapper for [momentjs](https://momentjs.com/) so all its [formatting](https://momentjs.com/docs/#/displaying/) is supported  \n\n**Usage**\nYou can use the date filter inside a nunjuck brackets in the request and inside the validate parts.\n\n```yml\nrequests:\n    moment-in-request:\n      request:\n        url: https://postman-echo.com/get\n        method: GET\n        queryString:\n        - name: foo\n          value: \u003c$ now | date('YYYY') $\u003e\n      validate:\n      - jsonpath: content.args.foo\n        expect: \"\u003c$ '2019-10-10' | date('YYYY') $\u003e\"\n    moment-in-validate:\n      request:\n        url: https://postman-echo.com/time/format?timestamp=2019-10-10\u0026format=YYYY\n        method: GET\n      validate:\n      - jsonpath: content.format\n        expect: \"\u003c$ '2019-10-10' | date('YYYY') $\u003e\"\n```\n\n## Sending JSON requests from external files\n\nIf you have a JSON file that represents the body of your request, you can use the `json` option.\n\nStrest will read the JSON file you have specified and add it to the body of the request, you won't even need to worry about the Content-Type header, Strest will take care of that for you.\n\n```yaml\nversion: 2\n\nrequests:\n  jsonfile:\n    request:\n      url: https://postman-echo.com/post\n      method: POST\n      json: tests/success/jsonfile/data.json  # You have to put the whole path relative to the current directory that you run strest\n    log: true\n```\n\n## Sending files and form data\nSending files and form data is easy, use params type in the postData prop.\n```yaml\nversion: 2\nrequests:\n  postwithfile:\n    request:\n      url: https://postman-echo.com/post\n      method: POST\n      postData:\n        mimeType: multipart/form-data\n        params:\n          - name: userId\n            value: \"1\"\n          - name: avatar\n            value: \u003c$ file(\"tests/strest.png\") $\u003e\n\n```\n## Response Validation\n\nThe immediate response is stored in [HAR Format](http://www.softwareishard.com/blog/har-12-spec/#response)\n\nWith **Strest** you can validate responses with:\n\n- exact match (expect)\n- regex\n- type _[List of all valid Types](VALIDATION.md)_\n- jsonschema\n\nRead [jsonpath](https://github.com/dchester/jsonpath#jpvalueobj-pathexpression-newvalue) for more info and see [this file](tests/success/validate/jsonpath.strest.yml) for more complex example\n\n### Expect\n\n```yaml\nrequests:\n  example:\n    ...\n    validate:\n    - jsonpath: content\n      expect: \"the response has to match this string exactly\"\n```\n\n### Type\n\n```yaml\nversion: 2\n\nrequests:\n  typeValidate:\n    request:\n      url: https://jsonplaceholder.typicode.com/todos\n      method: GET\n    validate:\n    - jsonpath: headers[\"content-type\"]\n      type: [ string ]\n    - jsonpath: status\n      type: [ boolean, string, number ]\n    - jsonpath: content.0.userId\n      type: [ number ]\n```\n\n### Regex\n\nRegex can be used to validate status code or any other returned param\n\n```yml\nversion: 2\n\nrequests:\n  codeValidate:\n    request:\n      url: https://jsonplaceholder.typicode.com/todos\n      method: GET\n    validate: # Multiple ways to use regex to validate status code\n    - jsonpath: status\n      regex: 2\\d+\n    - jsonpath: status\n      regex: 2[0-9]{2}\n    - jsonpath: status\n      regex: 2..\n    - jsonpath: status\n      regex: 2.*\n```\n\n### jsonschema\n\nValidate the response using a specified json(yaml) schema.  The schema can be defined in the variables portion or within the request.\n\n```yaml\nversion: 2\nvariables:\n  schemaValidate:\n    properties:\n      fruits:\n        type: array\n        items:\n          type: string\n      vegetables:\n        type: array\n        items:\n          \"$ref\": \"#/definitions/veggie\"\n    definitions:\n      veggie:\n        type: object\n        required:\n        - veggieName\n        - veggieLike\n        properties:\n          veggieName:\n            type: string\n          veggieLike:\n            type: boolean\n\nrequests:\n  jsonschema1:\n    request:\n      url: https://postman-echo.com/post\n      method: POST\n      postData:\n        mimeType: application/json\n        text:\n          fruits:\n            - apple\n            - orange\n            - pear\n          vegetables:\n          - veggieName: potato\n            veggieLike: true\n          - veggieName: broccoli\n            veggieLike: false\n    validate:\n    - jsonpath: content.data\n      jsonschema: \u003c$ schemaValidate | dump | safe $\u003e\n  jsonschema2:\n    request:\n      url: https://postman-echo.com/post\n      method: POST\n      postData:\n        mimeType: application/json\n        text:\n          fruits:\n            - apple\n            - orange\n            - pear\n          vegetables:\n          - veggieName: potato\n            veggieLike: true\n          - veggieName: broccoli\n            veggieLike: false\n    validate:\n    - jsonpath: content.data\n      jsonschema:\n        properties:\n          fruits:\n            type: array\n            items:\n              type: string\n          vegetables:\n            type: array\n            items:\n              \"$ref\": \"#/definitions/veggie\"\n        definitions:\n          veggie:\n            type: object\n            required:\n            - veggieName\n            - veggieLike\n            properties:\n              veggieName:\n                type: string\n              veggieLike:\n                type: boolean\n```\n\n### Retry until validation succeeds\n\n```yaml\nrequests:\n  waiter:\n    request:\n      url: https://postman-echo.com/time/now\n      method: GET\n    delay: 900\n    maxRetries: 30\n    validate:\n    - jsonpath: status\n      expect: 200\n    - jsonpath: content\n      expect: \"Tue, 09 Oct 2018 03:07:20 GMT\"\n```\n\n```bash\nexport STREST_GMT_DATE=$(TZ=GMT-0 date --date='15 seconds' --rfc-2822 | sed \"s/+0000/GMT/g\")\nstrest tests/success/validate/maxRetries.strest.yml\n```\n\n## Reusing Objects\n\nstREST uses [nunjucks](https://mozilla.github.io/nunjucks/templating.html) to parse everything inside \u003c$ $\u003e\n\nThis allows passing complex objects between requests using the [`dump` filter](https://mozilla.github.io/nunjucks/templating.html#dump)\n\n```yaml\nversion: 2\nrequests:\n  objectSet:\n    request:\n      url: https://postman-echo.com/post\n      method: POST\n      postData:\n        mimeType: application/json\n        text:\n          foo: bar\n          baz: 1\n    log: true\n  objectReset:\n    request:\n      url: https://postman-echo.com/post\n      method: POST\n      postData:\n        mimeType: application/json\n        text:\n          new: \u003c$ objectSet.content.data | dump | safe $\u003e\n    validate:\n      - jsonpath: content.data\n        expect: {\"new\":{\"foo\":\"bar\",\"baz\":1}}\n    log: true\n```\n\n## Errors\n\n**Strest** is a testing library so of course, you'll run into a few errors when testing an endpoint. Error handling is made very simple so can instantly see what caused an error and fix it.\nIf a request fails, the process will be exited with _exit code 1_ and no other requests will be executed afterwards.\n\n### Example\n\n```shell\n[ Strest ] Found 1 test file(s)\n[ Strest ] Schema validation: 1 of 1 file(s) passed\n\n✖ Testing test failed (0.2s)\n\n[ Validation ] The required item test wasn't found in the response data\n\n[ Strest ] ✨  Done in 0.245s\n```\n\n## Allow Insecure certs\n\nBoolean to allow:\n\n- insecure certificates\n- self-signed certificates\n- expired certificates\n\n### Example - Allow Insecure certs\n\n```yaml\nallowInsecure: true\nrequests:\n  someRequest:\n    ...\n```\n\n## Print out the equivalent curl commands\n\nTo print out the equivalent curl commands for each request, add the following flag to the command\n\n```bash\nstrest ... --output curl\n```\n\n## Exiting on a failed request\n\nBy default, **Strest** will exit the process with an exit code 1 if any request failed.\nBut you can also manipulate this by adding the `-n` or `--no-exit` flag into the command. This will instruct the program to go on\nwith the following request if the request failed.\n\n## Bulk tests\n\nSpecify a list of tests or directories to execute.\n\n`strest tests/success/bulk.yml -b`\n\nContents of bulk.yml:\n\n```yaml\n---\n- tests/success/postman.strest.yml\n- tests/success/two.strest.yml\n- tests/success/chaining/\n```\n\n## Configuration\n\nYou can create a file in your Computer's home directory called `.strestConfig.yml` which will be the custom config for **Strest**.\n\n```yaml\nconfig:\n  primaryColor: \"#2ed573\" # Hexadecimal Color Code (don't forget the quotation marks)\n  secondaryColor: \"#ff4757\" # Hexadecimal Color Code\n  errorColor: \"#576574\" # Hexadecimal Color Code\n```\n\n## License\n\nStrest is [MIT Licensed](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feykrehbein%2Fstrest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feykrehbein%2Fstrest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feykrehbein%2Fstrest/lists"}