allpairspy


Nameallpairspy JSON
Version 2.5.1 PyPI version JSON
download
home_pagehttps://github.com/thombashi/allpairspy
SummaryPairwise test combinations generator
upload_time2023-07-08 09:08:54
maintainerTsuyoshi Hombashi
docs_urlNone
authorMetaCommunications Engineering
requires_python>=3.7
licenseMIT License
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            .. contents:: **allpairspy** forked from `bayandin/allpairs <https://github.com/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 coverage


AllPairs 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:: python

        from 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:: python

        from 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 False

            if n > 4:
                # Contractors are billed in 30 min increments
                if "Contr." == row[3] and row[4] < 30:
                    return False

            return 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:: python

        from collections import OrderedDict
        from allpairspy import AllPairs

        parameters = 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:: python

        import pytest
        from allpairspy import AllPairs

        def function_to_be_tested(brand, operating_system, minute) -> bool:
            # do something
            return True

        class 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 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: OrderedDict
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:Sample Code:
    .. code:: python

        import pytest
        from allpairspy import AllPairs

        def function_to_be_tested(brand, operating_system, minute) -> bool:
            # do something
            return True

        class 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 <https://github.com/thombashi/allpairspy/tree/master/examples>`__ directory.


Installation
------------

Installation: pip
==================================
::

    pip install allpairspy

Installation: apt
==================================
You can install the package by ``apt`` via a Personal Package Archive (`PPA <https://launchpad.net/~thombashi/+archive/ubuntu/ppa>`__):

::

    sudo add-apt-repository ppa:thombashi/ppa
    sudo apt update
    sudo apt install python3-allpairspy


Known 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 <https://github.com/sponsors/thombashi>`__

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/thombashi/allpairspy",
    "name": "allpairspy",
    "maintainer": "Tsuyoshi Hombashi",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "tsuyoshi.hombashi@gmail.com",
    "keywords": "",
    "author": "MetaCommunications Engineering",
    "author_email": "metacomm@users.sourceforge.net",
    "download_url": "https://files.pythonhosted.org/packages/ea/9e/a5a536c22f56cdbbb0236889cff33915e20fb93a0526887367b38e91122e/allpairspy-2.5.1.tar.gz",
    "platform": null,
    "description": ".. contents:: **allpairspy** forked from `bayandin/allpairs <https://github.com/bayandin/allpairs>`__\n   :backlinks: top\n   :depth: 2\n\n.. image:: https://badge.fury.io/py/allpairspy.svg\n    :target: https://badge.fury.io/py/allpairspy\n    :alt: PyPI package version\n\n.. image:: https://img.shields.io/pypi/pyversions/allpairspy.svg\n    :target: https://pypi.org/project/allpairspy\n    :alt: Supported Python versions\n\n.. image:: https://github.com/thombashi/allpairspy/workflows/Tests/badge.svg\n    :target: https://github.com/thombashi/allpairspy/actions?query=workflow%3ATests\n    :alt: Linux/macOS/Windows CI status\n\n.. image:: https://coveralls.io/repos/github/thombashi/allpairspy/badge.svg?branch=master\n    :target: https://coveralls.io/github/thombashi/allpairspy?branch=master\n    :alt: Test coverage\n\n\nAllPairs test combinations generator\n------------------------------------------------\nAllPairs is an open source test combinations generator written in\nPython, developed and maintained by MetaCommunications Engineering.\nThe generator allows one to create a set of tests using \"pairwise\ncombinations\" method, reducing a number of combinations of variables\ninto a lesser set that covers most situations.\n\nFor more info on pairwise testing see http://www.pairwise.org.\n\n\nFeatures\n--------\n* Produces good enough dataset.\n* Pythonic, iterator-style enumeration interface.\n* Allows to filter out \"invalid\" combinations during search for the next combination.\n* Goes beyond pairs! If/when required can generate n-wise combinations.\n\n\nGet Started\n---------------\n\nBasic Usage\n==================\n:Sample Code:\n    .. code:: python\n\n        from allpairspy import AllPairs\n\n        parameters = [\n            [\"Brand X\", \"Brand Y\"],\n            [\"98\", \"NT\", \"2000\", \"XP\"],\n            [\"Internal\", \"Modem\"],\n            [\"Salaried\", \"Hourly\", \"Part-Time\", \"Contr.\"],\n            [6, 10, 15, 30, 60],\n        ]\n\n        print(\"PAIRWISE:\")\n        for i, pairs in enumerate(AllPairs(parameters)):\n            print(\"{:2d}: {}\".format(i, pairs))\n\n:Output:\n    .. code::\n\n        PAIRWISE:\n         0: ['Brand X', '98', 'Internal', 'Salaried', 6]\n         1: ['Brand Y', 'NT', 'Modem', 'Hourly', 6]\n         2: ['Brand Y', '2000', 'Internal', 'Part-Time', 10]\n         3: ['Brand X', 'XP', 'Modem', 'Contr.', 10]\n         4: ['Brand X', '2000', 'Modem', 'Part-Time', 15]\n         5: ['Brand Y', 'XP', 'Internal', 'Hourly', 15]\n         6: ['Brand Y', '98', 'Modem', 'Salaried', 30]\n         7: ['Brand X', 'NT', 'Internal', 'Contr.', 30]\n         8: ['Brand X', '98', 'Internal', 'Hourly', 60]\n         9: ['Brand Y', '2000', 'Modem', 'Contr.', 60]\n        10: ['Brand Y', 'NT', 'Modem', 'Salaried', 60]\n        11: ['Brand Y', 'XP', 'Modem', 'Part-Time', 60]\n        12: ['Brand Y', '2000', 'Modem', 'Hourly', 30]\n        13: ['Brand Y', '98', 'Modem', 'Contr.', 15]\n        14: ['Brand Y', 'XP', 'Modem', 'Salaried', 15]\n        15: ['Brand Y', 'NT', 'Modem', 'Part-Time', 15]\n        16: ['Brand Y', 'XP', 'Modem', 'Part-Time', 30]\n        17: ['Brand Y', '98', 'Modem', 'Part-Time', 6]\n        18: ['Brand Y', '2000', 'Modem', 'Salaried', 6]\n        19: ['Brand Y', '98', 'Modem', 'Salaried', 10]\n        20: ['Brand Y', 'XP', 'Modem', 'Contr.', 6]\n        21: ['Brand Y', 'NT', 'Modem', 'Hourly', 10]\n\n\nFiltering\n==================\nYou can restrict pairs by setting a filtering function to ``filter_func`` at\n``AllPairs`` constructor.\n\n:Sample Code:\n    .. code:: python\n\n        from allpairspy import AllPairs\n\n        def is_valid_combination(row):\n            \"\"\"\n            This is a filtering function. Filtering functions should return True\n            if combination is valid and False otherwise.\n\n            Test row that is passed here can be incomplete.\n            To prevent search for unnecessary items filtering function\n            is executed with found subset of data to validate it.\n            \"\"\"\n\n            n = len(row)\n\n            if n > 1:\n                # Brand Y does not support Windows 98\n                if \"98\" == row[1] and \"Brand Y\" == row[0]:\n                    return False\n\n                # Brand X does not work with XP\n                if \"XP\" == row[1] and \"Brand X\" == row[0]:\n                    return False\n\n            if n > 4:\n                # Contractors are billed in 30 min increments\n                if \"Contr.\" == row[3] and row[4] < 30:\n                    return False\n\n            return True\n\n        parameters = [\n            [\"Brand X\", \"Brand Y\"],\n            [\"98\", \"NT\", \"2000\", \"XP\"],\n            [\"Internal\", \"Modem\"],\n            [\"Salaried\", \"Hourly\", \"Part-Time\", \"Contr.\"],\n            [6, 10, 15, 30, 60]\n        ]\n\n        print(\"PAIRWISE:\")\n        for i, pairs in enumerate(AllPairs(parameters, filter_func=is_valid_combination)):\n            print(\"{:2d}: {}\".format(i, pairs))\n\n:Output:\n    .. code::\n\n        PAIRWISE:\n         0: ['Brand X', '98', 'Internal', 'Salaried', 6]\n         1: ['Brand Y', 'NT', 'Modem', 'Hourly', 6]\n         2: ['Brand Y', '2000', 'Internal', 'Part-Time', 10]\n         3: ['Brand X', '2000', 'Modem', 'Contr.', 30]\n         4: ['Brand X', 'NT', 'Internal', 'Contr.', 60]\n         5: ['Brand Y', 'XP', 'Modem', 'Salaried', 60]\n         6: ['Brand X', '98', 'Modem', 'Part-Time', 15]\n         7: ['Brand Y', 'XP', 'Internal', 'Hourly', 15]\n         8: ['Brand Y', 'NT', 'Internal', 'Part-Time', 30]\n         9: ['Brand X', '2000', 'Modem', 'Hourly', 10]\n        10: ['Brand Y', 'XP', 'Modem', 'Contr.', 30]\n        11: ['Brand Y', '2000', 'Modem', 'Salaried', 15]\n        12: ['Brand Y', 'NT', 'Modem', 'Salaried', 10]\n        13: ['Brand Y', 'XP', 'Modem', 'Part-Time', 6]\n        14: ['Brand Y', '2000', 'Modem', 'Contr.', 60]\n\n\nData Source: OrderedDict\n====================================\nYou can use ``collections.OrderedDict`` instance as an argument for ``AllPairs`` constructor.\nPairs will be returned as ``collections.namedtuple`` instances.\n\n:Sample Code:\n    .. code:: python\n\n        from collections import OrderedDict\n        from allpairspy import AllPairs\n\n        parameters = OrderedDict({\n            \"brand\": [\"Brand X\", \"Brand Y\"],\n            \"os\": [\"98\", \"NT\", \"2000\", \"XP\"],\n            \"minute\": [15, 30, 60],\n        })\n\n        print(\"PAIRWISE:\")\n        for i, pairs in enumerate(AllPairs(parameters)):\n            print(\"{:2d}: {}\".format(i, pairs))\n\n:Sample Code:\n    .. code::\n\n        PAIRWISE:\n         0: Pairs(brand='Brand X', os='98', minute=15)\n         1: Pairs(brand='Brand Y', os='NT', minute=15)\n         2: Pairs(brand='Brand Y', os='2000', minute=30)\n         3: Pairs(brand='Brand X', os='XP', minute=30)\n         4: Pairs(brand='Brand X', os='2000', minute=60)\n         5: Pairs(brand='Brand Y', os='XP', minute=60)\n         6: Pairs(brand='Brand Y', os='98', minute=60)\n         7: Pairs(brand='Brand X', os='NT', minute=60)\n         8: Pairs(brand='Brand X', os='NT', minute=30)\n         9: Pairs(brand='Brand X', os='98', minute=30)\n        10: Pairs(brand='Brand X', os='XP', minute=15)\n        11: Pairs(brand='Brand X', os='2000', minute=15)\n\n\nParameterized testing pairwise by using pytest\n====================================================================\n\nParameterized testing: value matrix\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n:Sample Code:\n    .. code:: python\n\n        import pytest\n        from allpairspy import AllPairs\n\n        def function_to_be_tested(brand, operating_system, minute) -> bool:\n            # do something\n            return True\n\n        class TestParameterized(object):\n            @pytest.mark.parametrize([\"brand\", \"operating_system\", \"minute\"], [\n                values for values in AllPairs([\n                    [\"Brand X\", \"Brand Y\"],\n                    [\"98\", \"NT\", \"2000\", \"XP\"],\n                    [10, 15, 30, 60]\n                ])\n            ])\n            def test(self, brand, operating_system, minute):\n                assert function_to_be_tested(brand, operating_system, minute)\n\n:Output:\n    .. code::\n\n        $ py.test test_parameterize.py -v\n        ============================= test session starts ==============================\n        ...\n        collected 16 items\n\n        test_parameterize.py::TestParameterized::test[Brand X-98-10] PASSED      [  6%]\n        test_parameterize.py::TestParameterized::test[Brand Y-NT-10] PASSED      [ 12%]\n        test_parameterize.py::TestParameterized::test[Brand Y-2000-15] PASSED    [ 18%]\n        test_parameterize.py::TestParameterized::test[Brand X-XP-15] PASSED      [ 25%]\n        test_parameterize.py::TestParameterized::test[Brand X-2000-30] PASSED    [ 31%]\n        test_parameterize.py::TestParameterized::test[Brand Y-XP-30] PASSED      [ 37%]\n        test_parameterize.py::TestParameterized::test[Brand Y-98-60] PASSED      [ 43%]\n        test_parameterize.py::TestParameterized::test[Brand X-NT-60] PASSED      [ 50%]\n        test_parameterize.py::TestParameterized::test[Brand X-NT-30] PASSED      [ 56%]\n        test_parameterize.py::TestParameterized::test[Brand X-98-30] PASSED      [ 62%]\n        test_parameterize.py::TestParameterized::test[Brand X-XP-60] PASSED      [ 68%]\n        test_parameterize.py::TestParameterized::test[Brand X-2000-60] PASSED    [ 75%]\n        test_parameterize.py::TestParameterized::test[Brand X-2000-10] PASSED    [ 81%]\n        test_parameterize.py::TestParameterized::test[Brand X-XP-10] PASSED      [ 87%]\n        test_parameterize.py::TestParameterized::test[Brand X-98-15] PASSED      [ 93%]\n        test_parameterize.py::TestParameterized::test[Brand X-NT-15] PASSED      [100%]\n\nParameterized testing: OrderedDict\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n:Sample Code:\n    .. code:: python\n\n        import pytest\n        from allpairspy import AllPairs\n\n        def function_to_be_tested(brand, operating_system, minute) -> bool:\n            # do something\n            return True\n\n        class TestParameterized(object):\n            @pytest.mark.parametrize(\n                [\"pair\"],\n                [\n                    [pair]\n                    for pair in AllPairs(\n                        OrderedDict(\n                            {\n                                \"brand\": [\"Brand X\", \"Brand Y\"],\n                                \"operating_system\": [\"98\", \"NT\", \"2000\", \"XP\"],\n                                \"minute\": [10, 15, 30, 60],\n                            }\n                        )\n                    )\n                ],\n            )\n            def test(self, pair):\n                assert function_to_be_tested(pair.brand, pair.operating_system, pair.minute)\n\n\nOther Examples\n=================\nOther examples could be found in `examples <https://github.com/thombashi/allpairspy/tree/master/examples>`__ directory.\n\n\nInstallation\n------------\n\nInstallation: pip\n==================================\n::\n\n    pip install allpairspy\n\nInstallation: apt\n==================================\nYou can install the package by ``apt`` via a Personal Package Archive (`PPA <https://launchpad.net/~thombashi/+archive/ubuntu/ppa>`__):\n\n::\n\n    sudo add-apt-repository ppa:thombashi/ppa\n    sudo apt update\n    sudo apt install python3-allpairspy\n\n\nKnown issues\n------------\n* Not optimal - there are tools that can create smaller set covering\n  all the pairs. However, they are missing some other important\n  features and/or do not integrate well with Python.\n\n* Lousy written filtering function may lead to full permutation of parameters.\n\n* Version 2.0 has become slower (a side-effect of introducing ability to produce n-wise combinations).\n\n\nDependencies\n------------\nPython 3.7+\nno external dependencies.\n\n\nSponsors\n------------\n.. image:: https://avatars.githubusercontent.com/u/3658062?s=48&v=4\n   :target: https://github.com/b4tman\n   :alt: Dmitry Belyaev (b4tman)\n.. image:: https://avatars.githubusercontent.com/u/44389260?s=48&u=6da7176e51ae2654bcfd22564772ef8a3bb22318&v=4\n   :target: https://github.com/chasbecker\n   :alt: Charles Becker (chasbecker)\n.. image:: https://avatars.githubusercontent.com/u/46711571?s=48&u=57687c0e02d5d6e8eeaf9177f7b7af4c9f275eb5&v=4\n   :target: https://github.com/Arturi0\n   :alt: Arturi0\n\n`Become a sponsor <https://github.com/sponsors/thombashi>`__\n",
    "bugtrack_url": null,
    "license": "MIT License",
    "summary": "Pairwise test combinations generator",
    "version": "2.5.1",
    "project_urls": {
        "Homepage": "https://github.com/thombashi/allpairspy",
        "Source": "https://github.com/thombashi/allpairspy",
        "Tracker": "https://github.com/thombashi/allpairspy/issues"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5a1afedf0f2ff77ec65e599112b2d5402fee5c166d9378b51760b696bd8cde1d",
                "md5": "3542bc84d238031b932e4eff85701cfa",
                "sha256": "3f97cbac2bbee86f4bfceffd0fd91dca740a120c78e9368af2bad81a2b3426e2"
            },
            "downloads": -1,
            "filename": "allpairspy-2.5.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "3542bc84d238031b932e4eff85701cfa",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 8965,
            "upload_time": "2023-07-08T09:08:51",
            "upload_time_iso_8601": "2023-07-08T09:08:51.994055Z",
            "url": "https://files.pythonhosted.org/packages/5a/1a/fedf0f2ff77ec65e599112b2d5402fee5c166d9378b51760b696bd8cde1d/allpairspy-2.5.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ea9ea5a536c22f56cdbbb0236889cff33915e20fb93a0526887367b38e91122e",
                "md5": "3a57a1abc7c031d57339f1f2a0b66350",
                "sha256": "f69d31a3b56eee119d1ec6063e9c732dd44fbba352ef738cb22d9699fc4009fe"
            },
            "downloads": -1,
            "filename": "allpairspy-2.5.1.tar.gz",
            "has_sig": false,
            "md5_digest": "3a57a1abc7c031d57339f1f2a0b66350",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 14281,
            "upload_time": "2023-07-08T09:08:54",
            "upload_time_iso_8601": "2023-07-08T09:08:54.049132Z",
            "url": "https://files.pythonhosted.org/packages/ea/9e/a5a536c22f56cdbbb0236889cff33915e20fb93a0526887367b38e91122e/allpairspy-2.5.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-07-08 09:08:54",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "thombashi",
    "github_project": "allpairspy",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "allpairspy"
}
        
Elapsed time: 0.42942s