{"id":22862415,"url":"https://github.com/dylibso/xtp-test-zig","last_synced_at":"2026-04-28T20:06:07.123Z","repository":{"id":233744840,"uuid":"787616841","full_name":"dylibso/xtp-test-zig","owner":"dylibso","description":"A Zig test framework for xtp / Extism plugins.","archived":false,"fork":false,"pushed_at":"2024-05-22T22:04:42.000Z","size":30,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-02-06T13:19:48.392Z","etag":null,"topics":["extism","plugins","testing","unit-testing","wasm","webassembly"],"latest_commit_sha":null,"homepage":"https://extism.org/docs/concepts/testing/","language":"Zig","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dylibso.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-16T21:30:05.000Z","updated_at":"2024-05-22T21:52:01.000Z","dependencies_parsed_at":"2024-05-21T06:40:54.080Z","dependency_job_id":"81955276-725d-4fe4-829d-de58c15c346b","html_url":"https://github.com/dylibso/xtp-test-zig","commit_stats":null,"previous_names":["dylibso/xtp-test-zig"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dylibso%2Fxtp-test-zig","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dylibso%2Fxtp-test-zig/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dylibso%2Fxtp-test-zig/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dylibso%2Fxtp-test-zig/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dylibso","download_url":"https://codeload.github.com/dylibso/xtp-test-zig/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246443525,"owners_count":20778247,"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":["extism","plugins","testing","unit-testing","wasm","webassembly"],"created_at":"2024-12-13T10:13:28.710Z","updated_at":"2026-04-28T20:06:07.094Z","avatar_url":"https://github.com/dylibso.png","language":"Zig","funding_links":[],"categories":[],"sub_categories":[],"readme":"# xtp-test\n\nA Zig test framework for [xtp](https://getxtp.com) /\n[Extism](https://extism.org) plugins.\n\n## Example\n\n```zig\nconst std = @import(\"std\");\nconst Test = @import(\"xtp-test\").Test;\n\nconst CountVowel = struct {\n    total: u32,\n    count: u32,\n    vowels: []const u8,\n};\n\nexport fn @\"test\"() i32 {\n    const xtp_test = Test.init(std.heap.wasm_allocator);\n    const output = xtp_test.call(\"count_vowels\", \"this is a test\") catch unreachable;\n    const cv = fromJson(output);\n    xtp_test.assertEq(\"count_vowels returns expected count\", cv.count, 4);\n\n    // create a group of tests inside a new scope, use defer to close the group at the end of the scope\n    {\n        const maintain_state_group = xtp_test.newGroup(\"plugin should maintain state\");\n        defer maintain_state_group.close();\n        var accumTotal: u32 = 0;\n        for (0..10) |_| {\n            const loop_output = xtp_test.call(\"count_vowels\", \"this is a test\") catch unreachable;\n            const loop_cv = fromJson(loop_output);\n            accumTotal += cv.count;\n            const msg = std.fmt.allocPrint(std.heap.wasm_allocator, \"count_vowels returns expected incremented total: {}\", .{accumTotal}) catch unreachable;\n            xtp_test.assertEq(msg, loop_cv.total, accumTotal);\n        }\n    }\n\n    // create a group without a scope, and close it manually at the end of your tests\n    const simple_group = xtp_test.newGroup(\"simple timing tests\");\n    const sec = xtp_test.timeSec(\"count_vowels\", \"this is a test\");\n    xtp_test.assertLt(\"it should be fast\", sec, 0.5);\n\n    const ns = xtp_test.timeNs(\"count_vowels\", \"this is a test\");\n    xtp_test.assertLt(\"it should be really fast\", ns, 1e5);\n    simple_group.close();\n\n    return 0;\n}\n\nfn fromJson(json: []const u8) CountVowel {\n    const cv = std.json.parseFromSlice(CountVowel, std.heap.wasm_allocator, json, .{}) catch unreachable;\n    return cv.value;\n}\n```\n\n## API Docs\n\nSee the [`main.zig`](/src/main.zig) file for the public API of this library.\n\n## Usage\n\n**1. Create a Zig project using the XTP Test library**\n\n```sh\nmkdir zig-xtp-test\ncd zig-xtp-test\nzig init\nzig fetch --save https://github.com/dylibso/xtp-test-zig/archive/v0.1.0.tar.gz\n# see the `build.zig` in this repo for examples on how to configure it\n```\n\n**2. Write your test in Zig**\n\n```zig\nconst std = @import(\"std\");\nconst Test = @import(\"xtp-test\").Test;\n\nconst CountVowel = struct {\n    total: u32,\n    count: u32,\n    vowels: []const u8,\n};\n\n// you _must_ export a single `test` function (in Zig, \"test\" is a keyword, so use this raw literal syntax)\nexport fn @\"test\"() i32 {\n    // initialize your test to run functions in a target plugin\n    const xtp_test = Test.init(std.heap.wasm_allocator);\n    xtp_test.assert(\"this is a test\", true, \"Expect true == true\");\n\n    // run the \"count_vowels\" function in the target plugin and assert the output is as expected\n    const output = xtp_test.call(\"count_vowels\", \"this is a test\") catch unreachable;\n    const cv = fromJson(output);\n    xtp_test.assertEq(\"count_vowels returns expected count\", cv.count, 4);\n\n    ...\n```\n\n**3. Compile your test to .wasm:**\n\nEnsure your `build.zig` is set up properly to compile to wasm32 `freestanding`\nor `wasi`. See the\n[Extism `zig-pdk` examples](https://github.com/extism/zig-pdk) or the\n`build.zig` in this repository for more details.\n\n```sh\nzig build\n# which should output a .wasm into zig-out/bin/\n```\n\n**4. Run the test against your plugin:** Once you have your test code as a\n`.wasm` module, you can run the test against your plugin using the `xtp` CLI:\n\n### Install `xtp`\n\n```sh\ncurl https://static.dylibso.com/cli/install.sh | sudo sh\n```\n\n### Run the test suite\n\n```sh\nxtp plugin test ./plugin-*.wasm --with test.wasm --mock-host host.wasm\n#               ^^^^^^^^^^^^^^^        ^^^^^^^^^             ^^^^^^^^^\n#               your plugin(s)         test to run           optional mock host functions\n```\n\n**Note:** The optional mock host functions must be implemented as Extism\nplugins, whose exported functions match the host function signature imported by\nthe plugins being tested.\n\n## Need Help?\n\nPlease reach out via the\n[`#xtp` channel on Discord](https://discord.com/channels/1011124058408112148/1220464672784908358).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdylibso%2Fxtp-test-zig","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdylibso%2Fxtp-test-zig","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdylibso%2Fxtp-test-zig/lists"}