{"id":26051489,"url":"https://github.com/for-get/katt","last_synced_at":"2025-04-05T22:06:55.197Z","repository":{"id":10576787,"uuid":"12784425","full_name":"for-GET/katt","owner":"for-GET","description":"KATT (Klarna API Testing Tool) is an HTTP-based API testing tool for Erlang.","archived":false,"fork":false,"pushed_at":"2024-08-29T20:28:55.000Z","size":7038,"stargazers_count":120,"open_issues_count":8,"forks_count":16,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-05T22:06:44.337Z","etag":null,"topics":["api","erlang","har","http","test"],"latest_commit_sha":null,"homepage":"https://github.com/for-GET/katt","language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/for-GET.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-09-12T13:32:13.000Z","updated_at":"2025-02-04T10:02:23.000Z","dependencies_parsed_at":"2024-07-26T17:47:42.286Z","dependency_job_id":"64e598d5-bdf9-4bc2-b806-f312a97f5b5f","html_url":"https://github.com/for-GET/katt","commit_stats":{"total_commits":585,"total_committers":18,"mean_commits":32.5,"dds":"0.20512820512820518","last_synced_commit":"5e084908505cf2e891386bcba06427ff1a28fde3"},"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/for-GET%2Fkatt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/for-GET%2Fkatt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/for-GET%2Fkatt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/for-GET%2Fkatt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/for-GET","download_url":"https://codeload.github.com/for-GET/katt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247406089,"owners_count":20933803,"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":["api","erlang","har","http","test"],"created_at":"2025-03-08T04:55:20.873Z","updated_at":"2025-04-05T22:06:55.158Z","avatar_url":"https://github.com/for-GET.png","language":"Erlang","readme":"# KATT [![Build Status][2]][1] [Docs][3]\n\nKATT (Klarna API Testing Tool) is an HTTP-based API testing tool for Erlang,\n, though it can work just as well as a CLI tool.\n\nUse for shooting HTTP requests in a sequential order and verifying the response.\nAny relevant difference between expected and actual responses will cause a\nfailure.\n\nInstall from git or https://hex.pm/packages/katt .\n\nFor convenience, [available as a Docker image too](https://hub.docker.com/r/ysoftwareab/katt): `docker run --rm -it -v $PWD:$PWD -w $PWD ysoftwareab/katt ...`.\n\nAnd [whalebrew package](https://github.com/whalebrew/whalebrew): `brew install whalebrew \u0026\u0026 sudo whalebrew install ysoftwareab/katt; katt ...`\n\n## Quick start on KATT and APIB files\n\n### Example\n\n[An example is worth a 1000 words. Have a look!](doc/example-httpbin.apib)\n\n\n### Params\n\nIf some values are static (constants) and you want to reuse them across multiple requests,\nyou can add one or more params like below\n\n```\nPARAM a_string=\"with some text\"\nPARAM a_boolean=true\nPARAM a_null=null\nPARAM a_float=1.1\nPARAM an_integer=1\n```\n\n### Validator\n\nThe builtin validator supports\n\n* basic text validation\n* more advanced validation of HTTP headers\n* JSON validation `application/json`, `application/*+json`\n* URL-encoded validation `application/x-www-form-urlencoded`\n\n\n### Tags\n\nThe validator makes use of a few tags with special meaning:\n\n`\"{{_}}\"`\nMatch anything including undefined (i.e. no real validation).\n\n`\"{{expected}}\"`\nMatch anything but undefined (i.e. no real validation, only check existence).\n\n`\"{{unexpected}}\"`\nMatch nothing (i.e. no real validation, only check lack of existence)\n\n`\"{{\u003ekey}}\"`\nStore value of the whole string (key must be unique within testcase)\n\n`\"{{\u003ckey}}\"`\nRecall stored value.\n\nThe `\"{{_}}\"` tag can also be used as a JSON object's property in order to\nvalidate any other additional properties.\n\nBy default, the builtin validator will allow additional properties in an object\nstructure, or additional items in an array structure. To counteract that\ndefault, one can do `{..., \"{{_}}\": \"{{unexpected}}\"}` or\n`[..., \"{{unexpected}}\"]`, effectively making a rule that no properties/items\nare expected beyond the ones defined.\n\n\n### Headers\n\nA request can also be configured via HTTP request headers:\n\n* `x-katt-content-type` would set a request content-type, without sending a `content-type` HTTP header\n* `x-katt-description` would take precedence over the transaction's description\n* `x-katt-request-timeout` would take precedence over the `request_timeout` param\n* `x-katt-request-sleep` would delay the request for a specific amount of milliseconds\n* `x-katt-transform` would call the `tranform` callback with its value as `id`\n\nA response can also be configured via HTTP response headers:\n* `x-katt-content-type` would set a response (expected and actual) content-type, without expecting/receiving a `content-type` HTTP header\n* `x-katt-transform` would call the `tranform` callback with its value as `id`\n\n\n### `set` extension\n\n`set` will ignore the order of an array's items, and just check for existence:\n\n```\n{\n  \"some_array\": {\n    \"{{type}}\": \"set\",\n    \"value\": [1, 2, 3]\n  }\n}\n```\n\nSo the above would validate against JSON instances such as\n`{\"some_array\": [1, 3, 2]}`, or `{\"some_array\": [3, 2, 1]}`,\nor even `{\"some_array\": [4, 3, 2, 1]}` unless we add `{{unexpected}}`.\n\n\n### `runtime_value` extension\n\n`runtime_value` would just run code (only `erlang` and `shell` supported for now),\nwhile having access to `ParentKey`, `Actual`, `ItemsMode` and `Callbacks`,\nand return the expected value and matched against the actual one.\n\n```\n{\n  \"rfc1123\": {\n    \"{{type}}\": \"runtime_value\",\n    \"erlang\": \"list_to_binary(httpd_util:rfc1123_date(calendar:now_to_datetime(erlang:now())))\"\n  }\n}\n```\n\nor in array format\n\n```\n{\n  \"rfc1123\": {\n    \"{{type}}\": \"runtime_value\",\n    \"erlang\": [\"list_to_binary(\",\n               \"  httpd_util:rfc1123_date(\",\n               \"    calendar:now_to_datetime(\",\n               \"      erlang:now()\",\n               \")))\"\n              ]\n  }\n}\n```\n\n\n### `runtime_validation` extension\n\n`runtime_validation` would just run code (only `erlang` and `shell` supported for now),\nwhile having access to `ParentKey`, `Actual`, `ItemsMode` and `Callbacks`,\nand return\n\n* `{pass, [{\"Key\", \"Value\"}]}` i.e. validation passed, store new param \"Key\" with value \"Value\"\n* `{not_equal, {Key, Expected, Actual}}`\n* `{not_equal, {Key, Expected, Actual, [{\"more\", \"info\"}]}}`\n\n```\n{\n  \"rfc1123\": {\n    \"{{type}}\": \"runtime_validation\",\n    \"erlang\": \"Expected = httpd_util:rfc1123_date(calendar:now_to_datetime(erlang:now())), case Actual =:= Expected of true -\u003e {pass, []}; false -\u003e {not_equal, {ParentKey, Expected, Actual}} end\"\n  }\n}\n```\n\nor in array format\n\n```\n{\n  \"rfc1123\": {\n    \"{{type}}\": \"runtime_validation\",\n    \"erlang\": [\"Expected = httpd_util:rfc1123_date(calendar:now_to_datetime(erlang:now())),\",\n               \"case Actual =:= Expected of\",\n               \"  true -\u003e\",\n               \"    {pass, []};\",\n               \"  false -\u003e\",\n               \"    {not_equal, {ParentKey, Expected, Actual}}\",\n               \"end\"\n              ]\n  }\n}\n```\n\n---\n\n## Command-Line Interface\n\nYou can either build the `bin/katt` executable yourself (just type `make`),\nor you can use a Docker image a call it with `docker run ysoftwareab/katt`.\n\nYou can fire up `katt` from the CLI, with\n```bash\nbin/katt base_url=http://httpbin.org my_name=Joe your_name=Mike -- doc/example-httpbin.apib\n```\n\nIf you want non-string params, use `:=` as a separator e.g. `my_int:=123`.\n\nYou can also output the result in JSON format, with `--json`, and beautify it e.g. with python\n```bash\nbin/katt --json base_url=http://httpbin.org my_name=Joe your_name=Mike -- doc/example-httpbin.apib | python -m json.tool\n```\n\nCheck `bin/katt --help` for a full list of arguments.\n\n\n---\n\n## Erlang Interface\n\nA simple example that will make requests to a third party server:\n\n```bash\nERL_LIBS=_build/default/deps erl $(for f in _build/default/lib/*/ebin; do echo \"-pa $f\"; done) -noshell -eval '\n  application:ensure_all_started(katt),\n  BlueprintFile = \"doc/example-httpbin.apib\",\n  Params = [{base_url, \"http://httpbin.org\"}, {my_name, \"Joe\"}, {your_name, \"Mike\"}],\n  io:format(\"~p~n\", [katt:run(BlueprintFile, Params)]).\n' -s init stop\n```\n... or run the code passed to -eval from the Erlang shell, assuming that you\nhave started the Erlang shell from the repo's root directory with\n`ERL_LIBS=_build/default/deps erl $(for f in _build/default/lib/*/ebin; do echo \"-pa $f\"; done)` .\n\n`katt:run` is to be called with\n\n* `filename`\n* `params` (optional)\n  * `base_url`, alternatively you can use the legacy\n    * `protocol`\n    * `hostname`\n    * `port`\n    * `base_path`\n  * `request_timeout`\n  * `scenario_timeout`\n* `callbacks` (optional)\n  * `ext` to be called with `scope` (recall_body, parse, validate_body, validate_type)\n  * `recall` to be called with `syntax`, `text`, `params`, `callbacks`\n  * `parse` to be called with `headers`, `body`, `params`, `callbacks`\n  * `request` to be called with `request`, `params`, `callbacks`\n  * `validate` to be called with `expected`, `actual`, `params`, `callbacks`\n  * `progress` to be called with `transaction_result`\n  * `text_diff` to be called with `text`, `text`\n  * `transform` to be called with `id`, `katt_request` or `{katt_response, actual_response}`, `params`, `callbacks`\n\n\n---\n\n## If you would like to convert a HAR file to an APIB file\n\nThe HTTP Archive format or HAR, is a JSON-formatted archive file format\nfor logging of a web browser's interaction with a site, [standardized by\nthe Web Performance Working Group of the World Wide Web Consortium (W3C)](https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/HAR/Overview.html).\n\nFor example, to convert [doc/example-teapot.har](doc/example-teapot.har)\ninto [doc/example-teapot.apib](doc/example-teapot.apib), run:\n\n``` bash\nbin/katt from-har --apib -- doc/example-teapot.har \u003e doc/example-teapot.apib\n```\n\n## If you would like to disable JSON support\n\n```erlang\nOnlyText = fun(_Scope) -\u003e [] end,\nkatt:run(\"text_only_scenario.apib\", [], [{ext, OnlyText}]).\n```\n\n## If you would like to add XML support\n\n```erlang\nPlusXml =\n  fun(recall_body) -\u003e\n    [ fun custom_callbacks_xml:recall_body/4\n    ] ++ katt_callbacks:ext(recall_body);\n  fun(parse) -\u003e\n    [ fun custom_callbacks_xml:parse/5\n    ] ++ katt_callbacks:ext(parse);\n  fun(validate_body) -\u003e\n    [ fun custom_callbacks_xml:validate_body/3\n    ] ++ katt_callbacks:ext(validate_body),\n  fun(validate_type) -\u003e\n    [ fun custom_callbacks_xml:validate_type/7\n    ] ++ katt_callbacks:ext(validate_type),\nkatt:run(\"xml_scenario.apib\", [], [{ext, PlusXml}]).\n```\n\nSee [src/katt_callbacks_json.erl](src/katt_callbacks_json.erl) to see how your\n`custom_callbacks_xml` module should be implemented.\n\n\n## If you would like to build KATT with almost no dependencies\n\n``` bash\nexport KATT_BARE_MODE=true\n# or\ntouch _build/BARE_MODE\n```\n\n---\n\n## Contributing\n\nA pull-request is most welcome. Please make sure that the following criteria are\nfulfilled before making your pull-request:\n\n* Include a description regarding what has been changed and why.\n* Make sure that the changed or added functionality (if you modify code) is\n  covered by unit tests.\n* Make sure that all unit tests pass.\n\n\n## License\n\n[Apache 2.0](LICENSE)\n\n\\* Despite the \"Klarna\" mention, this repository is not affiliated with Klarna AB.\nKATT was indeed born at Klarna, and Klarna AB holds copyright for parts of the code,\nbut it is now being maintained outside the company, by its original authors and new contributors.\n\n## Stargazers over time\n\n[![Stargazers over time](https://starchart.cc/for-GET/katt.svg)](https://starchart.cc/for-GET/katt)\n\n  [1]: https://github.com/for-GET/katt/actions?query=workflow%3ACI+branch%3Amaster\n  [2]: https://github.com/for-GET/katt/workflows/CI/badge.svg?branch=master\n  [3]: https://dev.erldocs.com/github.com/for-get/katt/\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffor-get%2Fkatt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffor-get%2Fkatt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffor-get%2Fkatt/lists"}