Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/thombashi/allpairspy
A python library for test combinations generator. 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.
https://github.com/thombashi/allpairspy
allpairs pairwise python-library testing
Last synced: 7 days ago
JSON representation
A python library for test combinations generator. 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.
- Host: GitHub
- URL: https://github.com/thombashi/allpairspy
- Owner: thombashi
- License: mit
- Created: 2017-01-20T23:35:40.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2023-11-01T08:19:45.000Z (about 1 year ago)
- Last Synced: 2024-10-30T00:30:04.208Z (about 2 months ago)
- Topics: allpairs, pairwise, python-library, testing
- Language: Python
- Homepage:
- Size: 138 KB
- Stars: 264
- Watchers: 17
- Forks: 42
- Open Issues: 4
-
Metadata Files:
- Readme: README.rst
- Changelog: CHANGES.txt
- Funding: .github/FUNDING.yml
- License: LICENSE.txt
Awesome Lists containing this project
README
.. contents:: **allpairspy** forked from `bayandin/allpairs `__
:backlinks: top
:depth: 2.. image:: https://badge.fury.io/py/allpairspy.svg
:target: https://badge.fury.io/py/allpairspy
:alt: PyPI package version.. image:: https://img.shields.io/pypi/pyversions/allpairspy.svg
:target: https://pypi.org/project/allpairspy
:alt: Supported Python versions.. image:: https://github.com/thombashi/allpairspy/workflows/Tests/badge.svg
:target: https://github.com/thombashi/allpairspy/actions?query=workflow%3ATests
:alt: Linux/macOS/Windows CI status.. image:: https://coveralls.io/repos/github/thombashi/allpairspy/badge.svg?branch=master
:target: https://coveralls.io/github/thombashi/allpairspy?branch=master
:alt: Test coverageAllPairs test combinations generator
------------------------------------------------
AllPairs 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 see http://www.pairwise.org.
Features
--------
* Produces 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 Started
---------------Basic Usage
==================
:Sample Code:
.. code:: pythonfrom allpairspy import AllPairs
parameters = [
["Brand X", "Brand Y"],
["98", "NT", "2000", "XP"],
["Internal", "Modem"],
["Salaried", "Hourly", "Part-Time", "Contr."],
[6, 10, 15, 30, 60],
]print("PAIRWISE:")
for i, pairs in enumerate(AllPairs(parameters)):
print("{:2d}: {}".format(i, pairs)):Output:
.. code::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]Filtering
==================
You can restrict pairs by setting a filtering function to ``filter_func`` at
``AllPairs`` constructor.:Sample Code:
.. code:: pythonfrom allpairspy import AllPairs
def is_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)
if n > 1:
# Brand Y does not support Windows 98
if "98" == row[1] and "Brand Y" == row[0]:
return False# Brand X does not work with XP
if "XP" == row[1] and "Brand X" == row[0]:
return Falseif n > 4:
# Contractors are billed in 30 min increments
if "Contr." == row[3] and row[4] < 30:
return Falsereturn True
parameters = [
["Brand X", "Brand Y"],
["98", "NT", "2000", "XP"],
["Internal", "Modem"],
["Salaried", "Hourly", "Part-Time", "Contr."],
[6, 10, 15, 30, 60]
]print("PAIRWISE:")
for i, pairs in enumerate(AllPairs(parameters, filter_func=is_valid_combination)):
print("{:2d}: {}".format(i, pairs)):Output:
.. code::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: OrderedDict
====================================
You can use ``collections.OrderedDict`` instance as an argument for ``AllPairs`` constructor.
Pairs will be returned as ``collections.namedtuple`` instances.:Sample Code:
.. code:: pythonfrom collections import OrderedDict
from allpairspy import AllPairsparameters = OrderedDict({
"brand": ["Brand X", "Brand Y"],
"os": ["98", "NT", "2000", "XP"],
"minute": [15, 30, 60],
})print("PAIRWISE:")
for i, pairs in enumerate(AllPairs(parameters)):
print("{:2d}: {}".format(i, pairs)):Sample Code:
.. 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 pytest
====================================================================Parameterized testing: value matrix
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:Sample Code:
.. code:: pythonimport pytest
from allpairspy import AllPairsdef function_to_be_tested(brand, operating_system, minute) -> bool:
# do something
return Trueclass TestParameterized(object):
@pytest.mark.parametrize(["brand", "operating_system", "minute"], [
values for values in AllPairs([
["Brand X", "Brand Y"],
["98", "NT", "2000", "XP"],
[10, 15, 30, 60]
])
])
def test(self, brand, operating_system, minute):
assert function_to_be_tested(brand, operating_system, minute):Output:
.. code::$ py.test test_parameterize.py -v
============================= test session starts ==============================
...
collected 16 itemstest_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: OrderedDict
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:Sample Code:
.. code:: pythonimport pytest
from allpairspy import AllPairsdef function_to_be_tested(brand, operating_system, minute) -> bool:
# do something
return Trueclass TestParameterized(object):
@pytest.mark.parametrize(
["pair"],
[
[pair]
for pair in AllPairs(
OrderedDict(
{
"brand": ["Brand X", "Brand Y"],
"operating_system": ["98", "NT", "2000", "XP"],
"minute": [10, 15, 30, 60],
}
)
)
],
)
def test(self, pair):
assert function_to_be_tested(pair.brand, pair.operating_system, pair.minute)Other Examples
=================
Other examples could be found in `examples `__ directory.Installation
------------Installation: pip
==================================
::pip install allpairspy
Installation: apt
==================================
You can install the package by ``apt`` via a Personal Package Archive (`PPA `__):::
sudo add-apt-repository ppa:thombashi/ppa
sudo apt update
sudo apt install python3-allpairspyKnown issues
------------
* Not 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).
Dependencies
------------
Python 3.7+
no external dependencies.Sponsors
------------
.. image:: https://avatars.githubusercontent.com/u/3658062?s=48&v=4
:target: https://github.com/b4tman
:alt: Dmitry Belyaev (b4tman)
.. image:: https://avatars.githubusercontent.com/u/44389260?s=48&u=6da7176e51ae2654bcfd22564772ef8a3bb22318&v=4
:target: https://github.com/chasbecker
:alt: Charles Becker (chasbecker)
.. image:: https://avatars.githubusercontent.com/u/46711571?s=48&u=57687c0e02d5d6e8eeaf9177f7b7af4c9f275eb5&v=4
:target: https://github.com/Arturi0
:alt: Arturi0`Become a sponsor `__