Skip to content
Snippets Groups Projects
Commit afe9a709 authored by Filip Kučerák's avatar Filip Kučerák
Browse files

README.md merge

parents 98429e78 04f74a64
No related branches found
No related tags found
No related merge requests found
KDTesting
# KDTesting
Python library for testing applications using IO.
# Basics
The library works using ValueGenerators (not python generators) and Arbitrary classes.
# Test
Test is container that holds name, arbitrary and value provided by said arbitrary. The test also contains functions `shrink` and `to_str` (using `to_str` from arbitrary on value).
# Tester
Tester is abstract class, the most important function `run_test(test: Test[G])` is not defined.
# RefImlTester
Tester that runs tests on your implementation and the reference implementation, then runs your process output tests on the outputs.
## ProcessOutputTest
Type is `Callable[[ProcessOutput, ProcessOutput], bool]`, it takes the outputs (in format provided by the `subprocess.run`) and returns bool.
There are some presets:
- `stdout_equality()`: returns test, that only compares the raw stdout
- `stdout_processed_equality(test_preprocessor, exp_preprocessor)`: returns test that compares processed stdouts. `test_preprocessor` and `exp_preprocessor` are `Callable[[str], str]` that "process" the stdout (you have to define these, there is `str_id` that returns the input unchaged `x -*> x`)
## Example use
```python
def ignore_numbers(x: str):
return re.sub(r'\d+', '', x)
# `program_tst` and `program_exp` are absolute paths pointing to the executables
# 3 - verbosity (default is 5, too much)
tester = RefImplTester(program_tst, program_exp, 3)
tester.add_output_test(stdout_processed_eqality(ignore_numbers, ignore_numbers))
for i in range(5):
# `command_sequence` is a custom arbitrary that returns sequence of
# `\n` delimitered commands
tester.add_test(Test(f"all_{i}", command_sequence))
# runs the test, returns (reduced test, number of shrinks) tuple
reduced_tests = tester.run()
# prints the failed tests, first the name, the number of shrinks, the test,
# then saves it as .tst file
for test, shrinks in reduced_tests:
print(test.name, shrinks)
print(test.to_str())
tester.save_shrunk(reduced_tests)
# also saves the original tests
tester.save_tests()
```
# Arbitraries
`Arbitrary[T]`
### Get
`get() -> T`
returns arbitrary value generated by the Arbitrary
### Shrink
`shrink(value: T) -> List[T]`
shrinks any value created by the Arbitrary to simpler value
### To string
`to_str(value: T) -> str`
converts the value to string
## The arbitraries currently present are:
### NumberA(min_value, max_value)
get returns: number in [min_value, max_value)
shrinks value to: val // 2, val moved towards 0
### ConstantA(constant)
get returns: constant
shrinks value to: nothing
### TupleA(arbs)
get returns: tuple where i-th value uses i-th arbitrary from arbs
shrinks value to: list of different tuples with shrunk values
### ListA(arb, min_size, max_size)
get returns: list with length [min_size, max_size)
shrinks value to: shorter lists
### ChoiceA(choices)
get returns: tuple (index of chosen arb, value generated by that arb), choice is random
shrinks value to: tuples with shrunk values (index of the chosen arb, value shrunk using said arb)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment