{"id":21198097,"url":"https://github.com/retailmenot/pairwise","last_synced_at":"2025-06-25T21:35:11.199Z","repository":{"id":16954660,"uuid":"19716896","full_name":"RetailMeNot/pairwise","owner":"RetailMeNot","description":"Java implementation of Combinatorial Test Case Generation","archived":false,"fork":false,"pushed_at":"2023-08-06T20:05:46.000Z","size":212,"stargazers_count":45,"open_issues_count":2,"forks_count":20,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-05T11:06:41.881Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","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/RetailMeNot.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"License.txt","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,"zenodo":null}},"created_at":"2014-05-12T21:58:01.000Z","updated_at":"2024-08-02T12:33:39.000Z","dependencies_parsed_at":"2025-06-25T21:33:36.086Z","dependency_job_id":null,"html_url":"https://github.com/RetailMeNot/pairwise","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/RetailMeNot/pairwise","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RetailMeNot%2Fpairwise","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RetailMeNot%2Fpairwise/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RetailMeNot%2Fpairwise/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RetailMeNot%2Fpairwise/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RetailMeNot","download_url":"https://codeload.github.com/RetailMeNot/pairwise/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RetailMeNot%2Fpairwise/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261957660,"owners_count":23236322,"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":[],"created_at":"2024-11-20T19:47:58.837Z","updated_at":"2025-06-25T21:35:11.152Z","avatar_url":"https://github.com/RetailMeNot.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"pairwise\n========\n\n## Project\nPairwise is an open-source library for the generation of data sets, most commonly used for\ntesting. A complete discussion of the ideas and algorithms is available from http://www.pairwise.org/\n\n## Installation\n\nThis is a Maven project, so you can either deploy a SNAPSHOT jar to your local Maven repo, or you can just point to the latest version in Maven Central\n\n### Building From Source\nDownload the source, then from the command-line, run the `mvn install` command. This will deploy a SNAPSHOT jar file to your local Men repo\n\nOnce the jar has been deployed, you should be able to include a small snippet in your pom file:\n\n```\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.retailmenot\u003c/groupId\u003e\n        \u003cartifactId\u003epairwise\u003c/artifactId\u003e\n        \u003cversion\u003e0.9-SNAPSHOT\u003c/version\u003e\n    \u003c/dependency\u003e\n```\n\nIf you're currently using Maven, and your repos, paths, and IDE are all set up correctly, you should be able to address the classes in this project immediately.\n\nIf you prefer to build a jar file and include it into your classpath, run `mvn package`, and the jar file should appear in the target folder under the main folder.\n\n### Maven Central\nTo point to the jar file in Maven Central, include this xml snippet in your pom.xml file:\n\n```\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.retailmenot\u003c/groupId\u003e\n        \u003cartifactId\u003epairwise\u003c/artifactId\u003e\n        \u003cversion\u003e0.9\u003c/version\u003e\n    \u003c/dependency\u003e\n```\n\n## Concept\nSimply put, this library takes an **input space**, then combines and reduces the data set down\nfrom **all possible permutations** to a set that will guarantee **pairwise permutations**.\n\nPut another way, this algorithm will guarantee not that every possible input was tested with\nall possible other inputs, but that **every possible input was tested with all other *single*\ninputs**. The initial input space is analyzed and broken down into a series of all possible **pairs** of inputs, and these pairs are then combined to produce the **smallest number of data sets** that can be iterated over in order to guarantee this \"pairwise\" coverage.\n\n## Links\nPlease see http://pairwise.org/ for more information\n\n\n## Example\nThis snippet takes several variables, and generates a combined set of test cases that will guarantee this \"pairwise\" coverage.\n\nImagine a shopping web site, where you want to verify that the various methods of adding an item to a shopping cart will\nresult in the proper check-out procedure. You want to make sure all supported browsers work, and that you have a representative\nset of products\n\n```\nprivate static final String NAV_SCENARIO =\n        \"Browser: Chrome, Firefox, InternetExplorer, Safari\"\n     + \"\\nPage: Home, Category, Search, New Products\"\n     + \"\\nProduct: Phone, Movie, Computer, Blender, Microwave, Book, Sweater\"\n     + \"\\nClick: Link, Image, Description\"\n        ;\n\npublic static void buildTestSets() {\n    //First, generate the list of vectors we *want*\n    IInventory inventory = PairwiseInventoryFactory.generateParameterInventory(NAV_SCENARIO);\n    List\u003cMap\u003cString, String\u003e\u003e rawDataSet = inventory.getTestDataSet().getTestSets();\n\n    //Now, go through the vectors in the database to figure out what we already *have*\n    // If we don't have it already, create it\n    for (Map\u003cString, String\u003e rawTestCase: rawDataSet) {\n        log.debug(String.format(\"Looking for Vector: [%s] [%s] [%s] [%s]\", \n            rawTestCase.get(\"Browser\"), rawTestCase.get(\"Page\"), \n            rawTestCase.get(\"Product\"), rawTestCase(\"Click\"));\n        //Now do something with it...\n    }\n}\n```\n\nInternally, it first generates the list of all possible pairs:\n\n```\nBrowser: Chrome, Page: Home\nChrome, Category\nChrome, Search\nChrome, New Products\nBrowser: Chrome, Product: Phone\nChrome, Movie\n\n\u003csnip\u003e\n\nPage: Home, Click: Link\nHome, Image\n\n//etc.\n```\n\nNext, it generates a set of test cases that will combine and reduce the pairs in such a way as to examine the highest number of pairs\nin the lowest number of iterations:\n\n* Test Case 000: [Chrome] [Home] [Phone] [Link]\n* Test Case 001: [Firefox] [Category] [Phone] [Image]\n* Test Case 002: [InternetExplorer] [Search] [Phone] [Description]\n* Test Case 003: [Safari] [New Products] [Phone] [Link]\n* Test Case 004: [Chrome] [Search] [Movie] [Image]\n\n\u0026lt;snip\u0026gt;\n\n* Test Case 025: [Firefox] [Home] [Sweater] [Link]\n* Test Case 026: [InternetExplorer] [New Products] [Microwave] [Link]\n* Test Case 027: [Safari] [Search] [Blender] [Link]\n\nTest Case 000 covers these pairs:  \n\n* [Chrome, Home]\n* [Home, Phone]\n* [Phone, Link]\n* [Chrome, Phone]\n* [Chrome, Link]\n* [Home, Link]\n\nTest Case 001 tests 6 new pairs, 002 covers 6 more, etc. There are 116 pairs we want to test, and we're able to guarantee the coverage of all of them in 28 test cases.\n\nYou would think that the number of test cases would always be ~19 (116 / 6 (total pairs / #\ncoverable by one test case)), but it's more complicated than that: when you have a high number\nof values in one parameter set (in this case, **Product**), you will end up having to execute more and more iterations in order to guarantee that the products are adequately tested with all other values. Therefore, you will see a lot of repetitions of other pairs as you iterate through the test cases.\n\n### Project Maturity\nThis project has been in general use within our offices for over a year, having been developed initially to generate simple pairwise data sets for a very small number of scenarios. The algorithm is stable, and does what it purports to do, but that said, there are a lot of features we'd like to add:\n\n* Randomizing test set generation, so that it's not the same set every time\n* Along those lines, we would like to provide a \"token\", which would allow you to generate the same data set over and over, should you have the desire\n* Model constraints, which would allow you to make rules such as \"these values can never be used together\"\n* Parameter sub-sets: if there is more than one kind of blender and you need to test with them all, the parameter needs to offer another \"dimension\" besides just \"blender\"\n* Order-N combinations: currently it only generates pairs of data, but we'd like to allow 3, 4, 5, or N number of combinations\n* Non-String data: currently all operations are String-based, but it would be nice to allow any kind of object to be used\n* Ability to generate **full** data set: If there are only 300 different test sets possible, and you are ok with testing all 300 of them, you should be able to do that by specifying an Order-1 data set\n\nIn conclusion, though this project is stable as-is, it needs a lot of work in order to become truly useful in many scenarios.\n\nUnit testing is roughly 80%, though there is no practical reason it couldn't be 100%.\n\n## Contributing\nAll pull requests are greatly appreciated! This project is intended for anyone who wants to add pairwise coverage to their projects easily. If you need new features, open an issue on github, or better yet, contribute your own features! We've made every attempt to keep the code simple and clean, so you should be able to follow our examples.\n\n## Versioning\nWe intend to use Semantic Versioning for this project. As such we are starting with v0.9, and might conceivably not be backward compatible when releasing v1.x in the future. See http://semver.org/ for more details.\n\n## License\nThis project has been released under the MIT license. Please see the license.txt file for more details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fretailmenot%2Fpairwise","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fretailmenot%2Fpairwise","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fretailmenot%2Fpairwise/lists"}