Package: allpairspy
allpairspyforked frombayandin/allpairsAllPairs test combinations generatorFeaturesGet StartedBasic UsageFilteringData Source: OrderedDictParameterized testing pairwise by using pytestOther ExamplesInstallationInstallation: pipInstallation: aptKnown issuesDependenciesSponsorsAllPairs test combinations generatorAllPairs is an open source test combinations generator written in
Python, developed and maintained by MetaCommunications Engineering.
The generator allows one to create a set of tests using “pairwise
combinations” method, reducing a number of combinations of variables
into a lesser set that covers most situations.For more info on pairwise testing seehttp://www.pairwise.org.FeaturesProduces good enough dataset.Pythonic, iterator-style enumeration interface.Allows to filter out “invalid” combinations during search for the next combination.Goes beyond pairs! If/when required can generate n-wise combinations.Get StartedBasic UsageSample Code:fromallpairspyimportAllPairsparameters=[["Brand X","Brand Y"],["98","NT","2000","XP"],["Internal","Modem"],["Salaried","Hourly","Part-Time","Contr."],[6,10,15,30,60],]print("PAIRWISE:")fori,pairsinenumerate(AllPairs(parameters)):print("{:2d}:{}".format(i,pairs))Output:PAIRWISE:
 0: ['Brand X', '98', 'Internal', 'Salaried', 6]
 1: ['Brand Y', 'NT', 'Modem', 'Hourly', 6]
 2: ['Brand Y', '2000', 'Internal', 'Part-Time', 10]
 3: ['Brand X', 'XP', 'Modem', 'Contr.', 10]
 4: ['Brand X', '2000', 'Modem', 'Part-Time', 15]
 5: ['Brand Y', 'XP', 'Internal', 'Hourly', 15]
 6: ['Brand Y', '98', 'Modem', 'Salaried', 30]
 7: ['Brand X', 'NT', 'Internal', 'Contr.', 30]
 8: ['Brand X', '98', 'Internal', 'Hourly', 60]
 9: ['Brand Y', '2000', 'Modem', 'Contr.', 60]
10: ['Brand Y', 'NT', 'Modem', 'Salaried', 60]
11: ['Brand Y', 'XP', 'Modem', 'Part-Time', 60]
12: ['Brand Y', '2000', 'Modem', 'Hourly', 30]
13: ['Brand Y', '98', 'Modem', 'Contr.', 15]
14: ['Brand Y', 'XP', 'Modem', 'Salaried', 15]
15: ['Brand Y', 'NT', 'Modem', 'Part-Time', 15]
16: ['Brand Y', 'XP', 'Modem', 'Part-Time', 30]
17: ['Brand Y', '98', 'Modem', 'Part-Time', 6]
18: ['Brand Y', '2000', 'Modem', 'Salaried', 6]
19: ['Brand Y', '98', 'Modem', 'Salaried', 10]
20: ['Brand Y', 'XP', 'Modem', 'Contr.', 6]
21: ['Brand Y', 'NT', 'Modem', 'Hourly', 10]FilteringYou can restrict pairs by setting a filtering function tofilter_funcatAllPairsconstructor.Sample Code:fromallpairspyimportAllPairsdefis_valid_combination(row):"""
    This is a filtering function. Filtering functions should return True
    if combination is valid and False otherwise.

    Test row that is passed here can be incomplete.
    To prevent search for unnecessary items filtering function
    is executed with found subset of data to validate it.
    """n=len(row)ifn>1:# Brand Y does not support Windows 98if"98"==row[1]and"Brand Y"==row[0]:returnFalse# Brand X does not work with XPif"XP"==row[1]and"Brand X"==row[0]:returnFalseifn>4:# Contractors are billed in 30 min incrementsif"Contr."==row[3]androw[4]<30:returnFalsereturnTrueparameters=[["Brand X","Brand Y"],["98","NT","2000","XP"],["Internal","Modem"],["Salaried","Hourly","Part-Time","Contr."],[6,10,15,30,60]]print("PAIRWISE:")fori,pairsinenumerate(AllPairs(parameters,filter_func=is_valid_combination)):print("{:2d}:{}".format(i,pairs))Output:PAIRWISE:
 0: ['Brand X', '98', 'Internal', 'Salaried', 6]
 1: ['Brand Y', 'NT', 'Modem', 'Hourly', 6]
 2: ['Brand Y', '2000', 'Internal', 'Part-Time', 10]
 3: ['Brand X', '2000', 'Modem', 'Contr.', 30]
 4: ['Brand X', 'NT', 'Internal', 'Contr.', 60]
 5: ['Brand Y', 'XP', 'Modem', 'Salaried', 60]
 6: ['Brand X', '98', 'Modem', 'Part-Time', 15]
 7: ['Brand Y', 'XP', 'Internal', 'Hourly', 15]
 8: ['Brand Y', 'NT', 'Internal', 'Part-Time', 30]
 9: ['Brand X', '2000', 'Modem', 'Hourly', 10]
10: ['Brand Y', 'XP', 'Modem', 'Contr.', 30]
11: ['Brand Y', '2000', 'Modem', 'Salaried', 15]
12: ['Brand Y', 'NT', 'Modem', 'Salaried', 10]
13: ['Brand Y', 'XP', 'Modem', 'Part-Time', 6]
14: ['Brand Y', '2000', 'Modem', 'Contr.', 60]Data Source: OrderedDictYou can usecollections.OrderedDictinstance as an argument forAllPairsconstructor.
Pairs will be returned ascollections.namedtupleinstances.Sample Code:fromcollectionsimportOrderedDictfromallpairspyimportAllPairsparameters=OrderedDict({"brand":["Brand X","Brand Y"],"os":["98","NT","2000","XP"],"minute":[15,30,60],})print("PAIRWISE:")fori,pairsinenumerate(AllPairs(parameters)):print("{:2d}:{}".format(i,pairs))Sample Code:PAIRWISE:
 0: Pairs(brand='Brand X', os='98', minute=15)
 1: Pairs(brand='Brand Y', os='NT', minute=15)
 2: Pairs(brand='Brand Y', os='2000', minute=30)
 3: Pairs(brand='Brand X', os='XP', minute=30)
 4: Pairs(brand='Brand X', os='2000', minute=60)
 5: Pairs(brand='Brand Y', os='XP', minute=60)
 6: Pairs(brand='Brand Y', os='98', minute=60)
 7: Pairs(brand='Brand X', os='NT', minute=60)
 8: Pairs(brand='Brand X', os='NT', minute=30)
 9: Pairs(brand='Brand X', os='98', minute=30)
10: Pairs(brand='Brand X', os='XP', minute=15)
11: Pairs(brand='Brand X', os='2000', minute=15)Parameterized testing pairwise by using pytestParameterized testing: value matrixSample Code:importpytestfromallpairspyimportAllPairsdeffunction_to_be_tested(brand,operating_system,minute)->bool:# do somethingreturnTrueclassTestParameterized(object):@pytest.mark.parametrize(["brand","operating_system","minute"],[valuesforvaluesinAllPairs([["Brand X","Brand Y"],["98","NT","2000","XP"],[10,15,30,60]])])deftest(self,brand,operating_system,minute):assertfunction_to_be_tested(brand,operating_system,minute)Output:$ py.test test_parameterize.py -v
============================= test session starts ==============================
...
collected 16 items

test_parameterize.py::TestParameterized::test[Brand X-98-10] PASSED      [  6%]
test_parameterize.py::TestParameterized::test[Brand Y-NT-10] PASSED      [ 12%]
test_parameterize.py::TestParameterized::test[Brand Y-2000-15] PASSED    [ 18%]
test_parameterize.py::TestParameterized::test[Brand X-XP-15] PASSED      [ 25%]
test_parameterize.py::TestParameterized::test[Brand X-2000-30] PASSED    [ 31%]
test_parameterize.py::TestParameterized::test[Brand Y-XP-30] PASSED      [ 37%]
test_parameterize.py::TestParameterized::test[Brand Y-98-60] PASSED      [ 43%]
test_parameterize.py::TestParameterized::test[Brand X-NT-60] PASSED      [ 50%]
test_parameterize.py::TestParameterized::test[Brand X-NT-30] PASSED      [ 56%]
test_parameterize.py::TestParameterized::test[Brand X-98-30] PASSED      [ 62%]
test_parameterize.py::TestParameterized::test[Brand X-XP-60] PASSED      [ 68%]
test_parameterize.py::TestParameterized::test[Brand X-2000-60] PASSED    [ 75%]
test_parameterize.py::TestParameterized::test[Brand X-2000-10] PASSED    [ 81%]
test_parameterize.py::TestParameterized::test[Brand X-XP-10] PASSED      [ 87%]
test_parameterize.py::TestParameterized::test[Brand X-98-15] PASSED      [ 93%]
test_parameterize.py::TestParameterized::test[Brand X-NT-15] PASSED      [100%]Parameterized testing: OrderedDictSample Code:importpytestfromallpairspyimportAllPairsdeffunction_to_be_tested(brand,operating_system,minute)->bool:# do somethingreturnTrueclassTestParameterized(object):@pytest.mark.parametrize(["pair"],[[pair]forpairinAllPairs(OrderedDict({"brand":["Brand X","Brand Y"],"operating_system":["98","NT","2000","XP"],"minute":[10,15,30,60],}))],)deftest(self,pair):assertfunction_to_be_tested(pair.brand,pair.operating_system,pair.minute)Other ExamplesOther examples could be found inexamplesdirectory.InstallationInstallation: pippip install allpairspyInstallation: aptYou can install the package byaptvia a Personal Package Archive (PPA):sudo add-apt-repository ppa:thombashi/ppa
sudo apt update
sudo apt install python3-allpairspyKnown issuesNot optimal - there are tools that can create smaller set covering
all the pairs. However, they are missing some other important
features and/or do not integrate well with Python.Lousy written filtering function may lead to full permutation of parameters.Version 2.0 has become slower (a side-effect of introducing ability to produce n-wise combinations).DependenciesPython 3.7+
no external dependencies.SponsorsBecome a sponsor