{"id":36419121,"url":"https://github.com/pavelicii/allpairs4j","last_synced_at":"2026-01-11T17:02:07.531Z","repository":{"id":57734450,"uuid":"462925488","full_name":"pavelicii/allpairs4j","owner":"pavelicii","description":"🧮Pairwise combinations generator with constraints for Java","archived":false,"fork":false,"pushed_at":"2023-12-16T14:51:40.000Z","size":101,"stargazers_count":17,"open_issues_count":0,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2023-12-16T15:58:36.892Z","etag":null,"topics":["allpairs","combinatorial-testing","java","pairwise","pairwise-testing","test-automation","testing","testing-tools"],"latest_commit_sha":null,"homepage":"","language":"Java","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/pavelicii.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}},"created_at":"2022-02-23T22:22:56.000Z","updated_at":"2023-11-06T12:28:17.000Z","dependencies_parsed_at":"2023-12-16T15:46:56.563Z","dependency_job_id":"7234c5ef-c38f-4254-a96f-9f5c13b64938","html_url":"https://github.com/pavelicii/allpairs4j","commit_stats":null,"previous_names":[],"tags_count":2,"template":null,"template_full_name":null,"purl":"pkg:github/pavelicii/allpairs4j","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavelicii%2Fallpairs4j","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavelicii%2Fallpairs4j/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavelicii%2Fallpairs4j/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavelicii%2Fallpairs4j/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pavelicii","download_url":"https://codeload.github.com/pavelicii/allpairs4j/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavelicii%2Fallpairs4j/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28314260,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-11T14:58:17.114Z","status":"ssl_error","status_checked_at":"2026-01-11T14:55:53.580Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["allpairs","combinatorial-testing","java","pairwise","pairwise-testing","test-automation","testing","testing-tools"],"created_at":"2026-01-11T17:02:07.466Z","updated_at":"2026-01-11T17:02:07.523Z","avatar_url":"https://github.com/pavelicii.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AllPairs4J\n\n[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/pavelicii/allpairs4j/build-checkstyle.yaml?branch=master\u0026logo=GitHub)](https://github.com/pavelicii/allpairs4j/actions/workflows/build-checkstyle.yaml)\n[![Maven Central](https://img.shields.io/maven-central/v/io.github.pavelicii/allpairs4j)](https://search.maven.org/artifact/io.github.pavelicii/allpairs4j)\n\nAllPairs4J is an open source Java library for generation of minimal set of test combinations.\n\n## Pairwise Testing • [pairwise.org](https://www.pairwise.org/)\n\nAssuming you want to create test cases for web browser testing, the domain can be described with parameters:\n\n```text\nBrowser:    Chrome, Firefox, Safari, Edge\nOS:         Windows, Linux, macOS\nRAM:        1024, 2048, 4096, 8192, 16384\nDrive:      HDD, SSD\nScreen:     1024x768, 1366x768, 1680x1050, 1920x1080, 2560x1440, 3840x2160\n```\n\nThere are hundreds of possible combinations of these values. However, usually most faults are caused by interactions \nof at most two factors, therefore testing all pairs is an effective alternative to exhaustive testing. \nFor example, `{Chrome, Windows}` is one pair, `{4096, SSD}` is another; together they can represent a test case \nthat also covers many other pairs: `{Chrome, Windows, 4096, SSD, 2560x1440}`. In the end, you have good \ncoverage while the number of test cases remains manageable.\n\nWith AllPairs4J, you can add **constraints** - limitations on the domain to restrict generation of certain pairs. \nFor example, specify that `Safari` can only be paired with `macOS`, and `Edge` with `Windows`. \nOr even go beyond pairs.\n\n## Features\n\n* Specify **constraints** to add limitations on the test combinations generation.\n* Generate **pair**wise, **triple**wise, **n**-wise test combinations.\n* Integrate with **any Java project**. There are pairwise tools that can sometimes be faster or generate smaller set\n  covering all the test combinations ([pict](https://github.com/microsoft/pict) is probably your best choice). \n  However, they are missing features mentioned above and/or do not integrate with Java.\n\n## Installation\n\n### Requirements\n\nJava 8 or higher.\n\n### Gradle\n\n```groovy\ndependencies {\n    implementation(\"io.github.pavelicii:allpairs4j:1.0.1\")\n}\n```\n\n### Maven\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.github.pavelicii\u003c/groupId\u003e\n    \u003cartifactId\u003eallpairs4j\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## Usage\n\n### Generate Pairwise Combinations\n\nYou can configure AllPairs generation using `AllPairsBuilder`. After it is built, the test cases are generated.\\\nAs a minimal setup, you need to describe Parameters to generate test combinations from.\n\n#### Sample code:\n\n```java\nAllPairs allPairs = new AllPairs.AllPairsBuilder()\n        .withParameters(Arrays.asList(\n                new Parameter(\"Browser\", \"Chrome\", \"Safari\", \"Edge\"),\n                new Parameter(\"OS\", \"Windows\", \"Linux\", \"macOS\"),\n                new Parameter(\"RAM\", 2048, 4096, 8192, 16384),\n                new Parameter(\"Drive\", \"HDD\", \"SSD\")))\n        .build();\n\nSystem.out.println(allPairs);\n```\n\n#### Output:\n\n\u003cdetails\u003e\u003csummary\u003eShow\u003c/summary\u003e\n\n```text\n  1: {Browser=Chrome, OS=Windows, RAM=2048, Drive=HDD}\n  2: {Browser=Safari, OS=Linux, RAM=4096, Drive=HDD}\n  3: {Browser=Edge, OS=macOS, RAM=8192, Drive=HDD}\n  4: {Browser=Edge, OS=Linux, RAM=16384, Drive=SSD}\n  5: {Browser=Safari, OS=Windows, RAM=16384, Drive=SSD}\n  6: {Browser=Chrome, OS=macOS, RAM=4096, Drive=SSD}\n  7: {Browser=Chrome, OS=Linux, RAM=8192, Drive=SSD}\n  8: {Browser=Safari, OS=macOS, RAM=2048, Drive=SSD}\n  9: {Browser=Edge, OS=Windows, RAM=4096, Drive=HDD}\n 10: {Browser=Edge, OS=Windows, RAM=2048, Drive=HDD}\n 11: {Browser=Safari, OS=macOS, RAM=16384, Drive=HDD}\n 12: {Browser=Chrome, OS=Linux, RAM=16384, Drive=SSD}\n 13: {Browser=Safari, OS=Linux, RAM=8192, Drive=SSD}\n 14: {Browser=Chrome, OS=Windows, RAM=8192, Drive=HDD}\n 15: {Browser=Edge, OS=Linux, RAM=2048, Drive=HDD}\n```\n\n\u003c/details\u003e\n\n### Constraints: Generate Filtered Pairwise Combinations\n\nTo filter out unwanted combinations, you need to describe Constraints. Each potential test Case is tested against them. \nIf any test evaluates to `true`, the Case under test won't be present in the result and the algorithm will search \nfor another Case, so that in the end all possible pairs are covered (considering all the Constraints).\n\nFor example, let's create limitations so that: \n* `Browser=Safari` can only be paired with `OS=macOS`\n* `Browser=Edge` can only be paired with `OS=Windows`\n* `RAM` can't be less than `4000`\n\n#### Sample code:\n\n```java\nAllPairs allPairs = new AllPairs.AllPairsBuilder()\n        .withParameter(new Parameter(\"Browser\", \"Chrome\", \"Safari\", \"Edge\"))\n        .withParameter(new Parameter(\"OS\", \"Windows\", \"Linux\", \"macOS\"))\n        .withParameter(new Parameter(\"RAM\", 2048, 4096, 8192, 16384))\n        .withParameter(new Parameter(\"Drive\", \"HDD\", \"SSD\"))\n        .withConstraint(c -\u003e c.get(\"Browser\").equals(\"Safari\") \u0026\u0026 !c.get(\"OS\").equals(\"macOS\"))\n        .withConstraint(c -\u003e c.get(\"Browser\").equals(\"Edge\") \u0026\u0026 !c.get(\"OS\").equals(\"Windows\"))\n        .withConstraint(c -\u003e (int) c.get(\"RAM\") \u003c 4000)\n        .build();\n\nSystem.out.println(allPairs);\n```\n\n#### Output:\n\n\u003cdetails\u003e\u003csummary\u003eShow\u003c/summary\u003e\n\n```text\n  1: {Browser=Chrome, OS=Windows, RAM=4096, Drive=HDD}\n  2: {Browser=Safari, OS=macOS, RAM=8192, Drive=HDD}\n  3: {Browser=Edge, OS=Windows, RAM=16384, Drive=SSD}\n  4: {Browser=Edge, OS=Windows, RAM=8192, Drive=SSD}\n  5: {Browser=Safari, OS=macOS, RAM=4096, Drive=SSD}\n  6: {Browser=Chrome, OS=Linux, RAM=16384, Drive=HDD}\n  7: {Browser=Edge, OS=Windows, RAM=4096, Drive=HDD}\n  8: {Browser=Chrome, OS=macOS, RAM=16384, Drive=SSD}\n  9: {Browser=Safari, OS=macOS, RAM=16384, Drive=HDD}\n 10: {Browser=Chrome, OS=Linux, RAM=8192, Drive=SSD}\n 11: {Browser=Chrome, OS=Linux, RAM=4096, Drive=SSD}\n```\n\n\u003c/details\u003e\n\n#### Constraints tips:\n\nTry to simplify constraints as much as possible. Too complicated constraints might cause longer algorithm processing \ntime, especially on a large input of Parameters. \n\nFor example, for the following input:\n\n```\nBrowser:    Chrome\nOS:         Linux, macOS\nDrive:      HDD, SSD\n```\n\nConsider two different constraints:\n\n```java\n// filter out 'Chrome-Linux-HDD' combination:\ncomplicatedConstraint = c -\u003e c.get(\"Browser\").equals(\"Chrome\") \u0026\u0026 c.get(\"OS\").equals(\"Linux\") \u0026\u0026 c.get(\"Drive\").equals(\"HDD\")\n// filter out 'Linux-HDD' pair:\nsimplifiedConstraint = c -\u003e c.get(\"OS\").equals(\"Linux\") \u0026\u0026 c.get(\"Drive\").equals(\"HDD\")\n```\n\nIt is better to use `simplifiedConstraint`, because the usage of `complicatedConstraint` implies there might be pairs \nincluding non-`Chrome` browsers, while in fact there is only one possible browser.\n\n### Generate Triplewise Combinations\n\nYou can specify test combination size to go beyond pairs.\n\n#### Sample code:\n\n```java\nAllPairs allPairs = new AllPairs.AllPairsBuilder()\n        .withTestCombinationSize(3)\n        .withParameters(Arrays.asList(\n                new Parameter(\"Browser\", \"Chrome\", \"Safari\", \"Edge\"),\n                new Parameter(\"OS\", \"Windows\", \"Linux\", \"macOS\"),\n                new Parameter(\"RAM\", 2048, 4096, 8192, 16384),\n                new Parameter(\"Drive\", \"HDD\", \"SSD\")))\n        .build();\n\nSystem.out.println(allPairs);\n```\n\n#### Output:\n\n\u003cdetails\u003e\u003csummary\u003eShow\u003c/summary\u003e\n\n```text\n  1: {Browser=Chrome, OS=Windows, RAM=2048, Drive=HDD}\n  2: {Browser=Safari, OS=Linux, RAM=4096, Drive=HDD}\n  3: {Browser=Edge, OS=macOS, RAM=8192, Drive=HDD}\n  4: {Browser=Edge, OS=macOS, RAM=16384, Drive=SSD}\n  5: {Browser=Safari, OS=Linux, RAM=16384, Drive=SSD}\n  6: {Browser=Chrome, OS=Windows, RAM=8192, Drive=SSD}\n  7: {Browser=Chrome, OS=Windows, RAM=4096, Drive=HDD}\n  8: {Browser=Safari, OS=Linux, RAM=2048, Drive=HDD}\n  9: {Browser=Edge, OS=macOS, RAM=2048, Drive=HDD}\n 10: {Browser=Edge, OS=macOS, RAM=4096, Drive=HDD}\n 11: {Browser=Safari, OS=Linux, RAM=8192, Drive=SSD}\n 12: {Browser=Chrome, OS=Windows, RAM=16384, Drive=SSD}\n 13: {Browser=Chrome, OS=Windows, RAM=16384, Drive=HDD}\n 14: {Browser=Safari, OS=Linux, RAM=4096, Drive=SSD}\n 15: {Browser=Edge, OS=macOS, RAM=2048, Drive=SSD}\n 16: {Browser=Edge, OS=macOS, RAM=8192, Drive=SSD}\n 17: {Browser=Safari, OS=Linux, RAM=8192, Drive=HDD}\n 18: {Browser=Chrome, OS=Windows, RAM=2048, Drive=SSD}\n 19: {Browser=Chrome, OS=Windows, RAM=4096, Drive=SSD}\n 20: {Browser=Safari, OS=Linux, RAM=16384, Drive=HDD}\n 21: {Browser=Edge, OS=macOS, RAM=16384, Drive=HDD}\n 22: {Browser=Edge, OS=macOS, RAM=4096, Drive=SSD}\n 23: {Browser=Safari, OS=Linux, RAM=2048, Drive=SSD}\n 24: {Browser=Chrome, OS=Windows, RAM=8192, Drive=HDD}\n 25: {Browser=Chrome, OS=Linux, RAM=8192, Drive=HDD}\n 26: {Browser=Safari, OS=macOS, RAM=2048, Drive=SSD}\n 27: {Browser=Edge, OS=Windows, RAM=4096, Drive=SSD}\n 28: {Browser=Edge, OS=Windows, RAM=16384, Drive=HDD}\n 29: {Browser=Safari, OS=macOS, RAM=16384, Drive=HDD}\n 30: {Browser=Chrome, OS=Linux, RAM=4096, Drive=SSD}\n 31: {Browser=Chrome, OS=Linux, RAM=2048, Drive=SSD}\n 32: {Browser=Safari, OS=macOS, RAM=8192, Drive=HDD}\n 33: {Browser=Edge, OS=Windows, RAM=8192, Drive=HDD}\n 34: {Browser=Safari, OS=macOS, RAM=4096, Drive=SSD}\n 35: {Browser=Edge, OS=Windows, RAM=2048, Drive=SSD}\n 36: {Browser=Chrome, OS=Linux, RAM=16384, Drive=HDD}\n 37: {Browser=Chrome, OS=macOS, RAM=16384, Drive=HDD}\n 38: {Browser=Edge, OS=Linux, RAM=2048, Drive=SSD}\n 39: {Browser=Safari, OS=Windows, RAM=4096, Drive=SSD}\n 40: {Browser=Safari, OS=Windows, RAM=8192, Drive=HDD}\n 41: {Browser=Edge, OS=Linux, RAM=8192, Drive=HDD}\n 42: {Browser=Chrome, OS=macOS, RAM=4096, Drive=SSD}\n 43: {Browser=Chrome, OS=macOS, RAM=2048, Drive=SSD}\n 44: {Browser=Edge, OS=Linux, RAM=16384, Drive=HDD}\n 45: {Browser=Safari, OS=Windows, RAM=16384, Drive=HDD}\n 46: {Browser=Safari, OS=Windows, RAM=2048, Drive=SSD}\n 47: {Browser=Edge, OS=Linux, RAM=4096, Drive=SSD}\n 48: {Browser=Chrome, OS=macOS, RAM=8192, Drive=HDD}\n```\n\n\u003c/details\u003e\n\n### Configuration Summary\n\n#### Builder:\n\n```java\nAllPairs allPairs = new AllPairs.AllPairsBuilder()\n        .withParameter( Parameter )                            // specifies 1 Parameter\n        .withParameters( List\u003cParameter\u003e )                     // alternative way to specify multiple Parameters as List\n        .withConstraint( Predicate\u003cConstrainableCase\u003e )        // specifies 1 Constraint, default is no Constraints\n        .withConstraints( List\u003cPredicate\u003cConstrainableCase\u003e\u003e ) // alternative way to specify multiple Constraints as List\n        .withTestCombinationSize( int )                        // specifies test combination size, default is 2 (pair)\n        .printEachCaseDuringGeneration()                       // prints Cases during generation, useful for debug\n        .build();\n\nList\u003cCase\u003e generatedCases = allPairs.getGeneratedCases();      // work with resulting List of Cases\nfor (Case c : allPairs) { ... }                                // or use Iterator\n```\n\n#### Data types:\n\n* **Parameter**: named `List\u003cObject\u003e` storing all input values\n* **Case**: `Map\u003cString, Object\u003e` storing one generated test case,\n  where `key` is mapped to the `Parameter` name, `value` is mapped to one of the `Parameter` values\n* **Predicate\\\u003cConstrainableCase\\\u003e**: constraint\n\n## Contributing\n\nPull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.\n\nPlease make sure to update tests as appropriate.\n\n[SemVer](https://semver.org/) is used for versioning. For the versions available, \nsee the [releases](https://github.com/pavelicii/allpairs4j/releases) on this repository.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpavelicii%2Fallpairs4j","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpavelicii%2Fallpairs4j","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpavelicii%2Fallpairs4j/lists"}