Basic specification structure:
spec: [Any operation here applies to all test cases below] domain <arguments>: [Operations declared here apply to this particular test case] results <expected result>
Let’s see what all of this means:
- spec - indicates start of specification.
- domain - indicates single test case. Domain statement is followed by arguments passed to the tested function.
- results - specifies the expected result of test case.
Tests shall be simple. As simple as saying “if I provide you with arguments X I expect the result Y”. So let’s try to implement function that provided with negative value returns 0. Otherwise the function returns its input.
def flatten_positive(x): """ spec: domain 32: results 32 domain 0: results 0 domain interval (-Infinity, 0): results 0 # Floats are also allowed domain 67.6: results 67.6 domain interval (-Infinity, 0): results 0.0 """ if x < 0: return 0 return x
Test cases can include plain values or sets of values as arguments. That is why the keyword is called domain rather than arguments. interval is used to specify input ranges in which function has constant output. Additionally Infinity is a special value that indicates no upper boundary of range (-Infinity means no lower boundary).
Interval is mechanism of specyfing tests declaratively. Under the hood argument contained within specified range is randomly generated. The language does not prove the statement is true for all possible combinations of arguments by any means.
To run tests use command:
Additionaly if you want more detailed output you can use:
takathon -v info <path-to-file-or-directory>
For unordered test data you can use any_of to indicate that the result is constant for specified objects.
from enum import Enum Color = Enum("Color", ("BLUE", "CYAN", "GREEN", "YELLOW", "RED")) def is_red(color): """ spec: domain any_of(Color.BLUE, Color.CYAN, Color.GREEN, Color.YELLOW): results False domain Color.RED: results True """ return color == Color.RED
Plain Python imports works out of the box so you can bring anything to test scope. No need to bloat the module itself. Python style comments are also supported.