{"id":24810773,"url":"https://github.com/yusukehosonuma/swiftparamtest","last_synced_at":"2025-06-19T20:34:55.718Z","repository":{"id":42443442,"uuid":"181102665","full_name":"YusukeHosonuma/SwiftParamTest","owner":"YusukeHosonuma","description":"Parameterized test for Swift","archived":false,"fork":false,"pushed_at":"2024-09-03T21:00:01.000Z","size":3014,"stargazers_count":58,"open_issues_count":8,"forks_count":6,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-06-03T16:27:45.702Z","etag":null,"topics":["parameterized-tests","swift","test"],"latest_commit_sha":null,"homepage":"https://qiita.com/YusukeHosonuma/items/f3a8d6d38523813f6c68","language":"Swift","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/YusukeHosonuma.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":"2019-04-13T00:51:14.000Z","updated_at":"2025-01-06T01:23:38.000Z","dependencies_parsed_at":"2025-02-14T05:11:22.824Z","dependency_job_id":"31cd0287-f7d2-4883-8ba8-fee3d496eaab","html_url":"https://github.com/YusukeHosonuma/SwiftParamTest","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/YusukeHosonuma/SwiftParamTest","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YusukeHosonuma%2FSwiftParamTest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YusukeHosonuma%2FSwiftParamTest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YusukeHosonuma%2FSwiftParamTest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YusukeHosonuma%2FSwiftParamTest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/YusukeHosonuma","download_url":"https://codeload.github.com/YusukeHosonuma/SwiftParamTest/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YusukeHosonuma%2FSwiftParamTest/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260826689,"owners_count":23068819,"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":["parameterized-tests","swift","test"],"created_at":"2025-01-30T12:18:00.447Z","updated_at":"2025-06-19T20:34:50.708Z","avatar_url":"https://github.com/YusukeHosonuma.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SwiftParamTest\n\n![Test](https://github.com/YusukeHosonuma/SwiftParamTest/workflows/Test/badge.svg)\n[![CocoaPods](https://img.shields.io/cocoapods/v/SwiftParamTest.svg)](https://cocoapods.org/pods/SwiftParamTest)\n[![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n![SPM Compatible](https://img.shields.io/badge/SPM-compatible-4BC51D.svg?style=flat)\n[![License](https://img.shields.io/github/license/YusukeHosonuma/SwiftPrettyPrint)](https://github.com/YusukeHosonuma/SwiftPrettyPrint/blob/master/LICENSE)\n[![Twitter](https://img.shields.io/twitter/url?style=social\u0026url=https%3A%2F%2Ftwitter.com%2Ftobi462)](https://twitter.com/tobi462)\n\n![Logo](https://raw.githubusercontent.com/YusukeHosonuma/SwiftParamTest/master/Image/logo.png)\n\nParameterized-test for Swift. (with XCTest)\n\n![Screenshot](https://raw.githubusercontent.com/YusukeHosonuma/SwiftParamTest/master/Image/screenshot.png)\n\n## Code Style\n\nSwiftParamTest supports two way of code-style dependent on Swift version.\n\n### Result builders API (recommended)\n\nI recommend this API when you use Swift 5.1 or later.\n\n```swift\nassert(to: max) {\n    args(1, 2, expect: 2)\n    args(2, 1, expect: 2)\n    args(4, 4, expect: 4)\n}\n\n// You can also use tuple (with label).\n\nassert(to: max) {\n    args((x: 1, y: 2), expect: 2)\n    args((x: 2, y: 1), expect: 2)\n    args((x: 4, y: 4), expect: 4)\n}\n```\n\n### Legacy API\n\nYou can use array literal based API that like follwing when you use under Swift 5.1.\n\n```swift\nassert(to: max, expect: [\n    args(1, 2, expect: 2),\n    args(2, 1, expect: 2),\n    args(4, 4, expect: 4),\n])\n\n// You can also use tuple (with label).\n\nassert(to: max, expect: [\n    args((x: 1, y: 2), expect: 2),\n    args((x: 2, y: 1), expect: 2),\n    args((x: 4, y: 4), expect: 4),\n])\n```\n\n## Operator based API\n\nYou can specify row by use the operator `==\u003e` that like following:\n\n```swift\n// Function Builder API\nassert(to: max) {\n    expect((1, 2) ==\u003e 2)\n    expect((2, 1) ==\u003e 2)\n    expect((4, 4) ==\u003e 4)\n}\n\n// Legacy API\nassert(to: max, expect: [\n    expect((1, 2) ==\u003e 2),\n    expect((2, 1) ==\u003e 2),\n    expect((4, 4) ==\u003e 4),\n])\n```\n\n## Save or Output Markdown Table\n\nSave or output markdown table when enabled by option (default is all disable).\n\n```swift\noverride func setUp() {\n    ParameterizedTest.option = ParameterizedTest.Option(\n        traceTable: .markdown,            // output console is enabled\n        saveTableToAttachement: .markdown // save to attachement is enabled\n    )\n}\n\noverride func tearDown() {\n    ParameterizedTest.option = ParameterizedTest.defaultOption // restore to default\n}\n\nfunc testExample() {\n    assert(to: max) {\n        args(1, 2, expect: 2)\n        args(2, 1, expect: 2)\n        args(4, 4, expect: 4)\n    }\n    // =\u003e\n    // | Args 0 | Args 1 | Expected |\n    // |--------|--------|----------|\n    // |      1 |      2 |        2 |\n    // |      2 |      1 |        2 |\n    // |      4 |      4 |        4 |\n}\n```\n\nYou can also specify column header name too.\n\n```swift\nfunc testMarkdownTable() {\n    assert(to: max, header: [\"x\", \"y\"]) { // specify `header`\n        args(1, 2, expect: 2)\n        args(2, 1, expect: 2)\n        args(4, 4, expect: 4)\n    }\n    // =\u003e\n    // | x | y | Expected |\n    // |---|---|----------|\n    // | 1 | 2 |        2 |\n    // | 2 | 1 |        2 |\n    // | 4 | 4 |        4 |\n}\n```\n\n![markdown table](https://raw.githubusercontent.com/YusukeHosonuma/SwiftParamTest/master/Image/markdown-table.png)\n\nYou can also retrive markdown table from result too.\n\n```swift\nlet tableString = assert(to: max, header: [\"x\", \"y\"]) {\n                      args(1, 2, expect: 2)\n                      args(2, 1, expect: 2)\n                      args(4, 4, expect: 4)\n                  }.table\n\nprint(tableString)\n// =\u003e\n// | x | y | Expected |\n// |---|---|----------|\n// | 1 | 2 |        2 |\n// | 2 | 1 |        2 |\n// | 4 | 4 |        4 |\n```\n\nThis is useful for copy and paste the test specification table to PR or others.\n\n![markdown table in PR](https://raw.githubusercontent.com/YusukeHosonuma/SwiftParamTest/master/Image/github-pr-markdown-table.png)\n\n## Xcode Code Snippets\n\n![Xcode Code Snippets](https://raw.githubusercontent.com/YusukeHosonuma/SwiftParamTest/master/Image/xcode-snippet.gif)\n\nCopy `.codesnippet` files to the following directory from [.xcode](.xcode) directory:\n\n```text\n~/Library/Developer/Xcode/UserData/CodeSnippets/\n```\n\nand restart Xcode.\n\nOr run the following command from the root of the repository:\n\n```text\n$ make snippets\n```\n\n## Example\n\n```swift\nimport SwiftParamTest\nimport XCTest\n\nclass ExampleTests: XCTestCase {\n    override func setUp() {\n        ParameterizedTest.option = ParameterizedTest.Option(traceTable: .markdown,\n                                                            saveTableToAttachement: .markdown)\n    }\n\n    override func tearDown() {\n        ParameterizedTest.option = ParameterizedTest.defaultOption\n    }\n\n    func testExample() {\n        // for `function`\n        assert(to: abs) {\n            args( 0, expect: 0)\n            args( 2, expect: 2)\n            args(-2, expect: 2)\n        }\n\n        // for `operator`\n        assert(to: +) {\n            args(1, 1, expect: 2)\n            args(1, 2, expect: 3)\n            args(2, 2, expect: 4)\n        }\n\n        // for `instance method` (when receiver is not fixed)\n        assert(to: String.hasPrefix) {\n            args(\"hello\", \"he\", expect: true)\n            args(\"hello\", \"HE\", expect: false)\n        }\n\n        // for `instance method` (when receiver is fixed)\n        assert(to: \"hello\".hasPrefix) {\n            args(\"he\", expect: true)\n            args(\"HE\", expect: false)\n        }\n    }\n}\n```\n\n## Custom Assertion\n\nSwiftParamTest uses `XCTAssertEqual()` and owns error messages by default.\n\nBut you can use custom assertion like follows.\n\n```swift\n// custom assertion\nfunc customAssert\u003cT: Equatable\u003e(_ actual: T, _ expected: T, file: StaticString, line: UInt) {\n    let message = \"\"\"\n\n    ----\n    Expected: \\(expected)\n    Actual: \\(actual)\n    ----\n    \"\"\"\n    XCTAssert(expected == actual, message, file: file, line: line)\n}\n\n// passed by `with` arguments\nassert(to: fizzBuzz, with: customAssertion) {\n    args(1, expect: \"Fizz\")\n    // =\u003e\n    //\n    // XCTAssertTrue failed -\n    // ----\n    // Expected: 1\n    // Actual: Fizz\n    // ----\n    //\n}\n```\n\n## Limitation\n\n- Only up to **four** arguments are supported.\n\n## FAQ\n\n### Can't compile or compiler is clashed\n\nThis library use many type inference, therefore type inference are failed in sometime.\nThis may be resolved by explicitly specifying the type information.\n\nfor example:\n\n```swift\n// Legacy API\nassert(to: max, expect: [\n    args(1, 2, expect: 2),\n    args(2, 1, expect: 2),\n    args(4, 4, expect: 4),\n] as [Row2\u003cInt, Int, Int\u003e]) // `N` in `RowN` is arguments count\n\n// Function Builder API\ntypealias T = Int\nassert(to: max) {\n    args(1 as T, 2 as T, expect: 2)\n    args(2 as T, 1 as T, expect: 2)\n    args(4 as T, 4 as T, expect: 4)\n}\n```\n\n## Installation\n\n### CocoaPods\n\n```ruby\npod 'SwiftParamTest'\n```\n\n### Swift Package Manager\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/YusukeHosonuma/SwiftParamTest.git\", .upToNextMajor(from: \"2.2.0\")),\n],\ntargets: [\n    .testTarget(\n        name: \"YOUR_TEST_MODULE\",\n        dependencies: [\n            \"SwiftParamTest\",\n        ]),\n],\n```\n\n### Carthage\n\nWrite following to `Cartfile.private`.\n\n```text\ngithub \"YusukeHosonuma/SwiftParamTest\"\n```\n\n## Author\n\nYusuke Hosonuma / tobi462@gmail.com\n\n## License\n\nSwiftParamTest is available under the MIT license. See the LICENSE file for more info.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyusukehosonuma%2Fswiftparamtest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyusukehosonuma%2Fswiftparamtest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyusukehosonuma%2Fswiftparamtest/lists"}