Package: pyproptest
Pyproptest - property based testing made simple (maybe)Overview:This package was created to allow Python users to utilise property based testing in a similar manner to Haskell'sQuickCheckpackage.Property based testing allows for a more complete 'proving' of a program's correctness by ensuring the overall behaviour of functions is correct. This is in contrast to testing individual test cases - a unit testing approach. Property based testing is, however, not particularly well suited to testing very stateful programs.ThinkingCorrectly:E.g. Testing that a sorting function works as intended.In this case, to ensure that the functionmysortis behaving correctly, we may want to test that is has the following properties:the items in the resulting list are in sorted order (kind of obvious - we want the sorting algorithm to sort things)every unique value from the input list appears in the output list the same number of times (no values are disappearing/being duplicated)the resulting list has the same number of items as the original list (ensure that new items aren't introduced)If thesepropertieshold, it can be concluded that the sorting algorithm is performing correctly.Usage:The general structure of a test within a class is as follows:@staticmethod
def prop_equalLength():
    def test(i):
        return len(i) == len(sorted(i))
    return ([bg.intListArb(10,-100,100)], test)prop_equalLengthis the function for producing the test with generatorstestis the test to be run[bg.intListArb(10,-100,100)]is the list of generators used to produce the test function's inputs (i)or, using the decorator pattern:@staticmethod
@bg.test([bg.intListArb(10,-100,100)])
def prop_equalLength(i):
     return len(i) == len(sorted(i))prop_equalLengthis the test functionbg.testdecorator specifies generators (bgrefers topyproptest.basicGenerators)[bg.intListArb(10,-100,100)]is the list of generators used to produce the test function's inputs (i)The following is an implementation of some tests for ensuring that the sorting functionsortedworks correctly. The methodology follows that described in the previous section:import pyproptest.basicGenerators as bg
import pyproptest.testing as pytest

class sortingTests:
    @staticmethod
    @bg.test([bg.intListArb(10,-100,100)])
    def prop_equalLength(i):
        return len(i) == len(sorted(i))

    @staticmethod
    @bg.test([bg.intListArb(10,-100,100)])
    def prop_sortedResult(i):
        res = sorted(i)
        return all([res[i] <= res[i + 1] for i in range(len(res) - 1)])
    
    @staticmethod
    @bg.test([bg.intListArb(10,-100,100)])
    def prop_containsSameElements(i):
        res = sorted(i)
        ifreq = {x:i.count(x) for x in i}
        return ifreq == {x:res.count(x) for x in res}


testerObj = pytest.tester(classes = [sortingTests])
testerObj.runTests()This produces output:testing sortingTests:
testing prop_containsSameElements:		ran 100 test(s), with 0 failure(s)
testing prop_equalLength:		ran 100 test(s), with 0 failure(s)
testing prop_sortedResult:		ran 100 test(s), with 0 failure(s)
==================================================
0 test(s) failed (100.0%):
==================================================Signifying that all of the tests passed, and thesorted()function has all of the properties which we want it to have.Defining new generators:Generators for producing the arbitrary input to property testing functions take the form of a wrapper function which returns a generator. For generating arbitrary integers, the following generator - available in basicGenerators, can be used:def intArb(minBound = -sys.maxsize, maxBound = sys.maxsize):
    def gen():
        while True:
            yield random.randint(minBound, maxBound)
    return gen