Let's write a simple "parser", it should:
- Take a string containing words that are separated by commas
- Should return a list of those words.
- Enforce atleast two entries in the list (two words, one comma)
- Initialize parser module
$ mkdir parser
$ cd parser
$ touch __init__.py
- Initialize serializer
# parser/serializer.py
def serialize(string):
serialized = string.split(',')
if len(serialized) < 2:
raise Exception('Need atleast two entries')
return serialized
- Install dependencies (ParserKiosk and Pytest)
pip install parserkiosk pytest
- Write a simple
config.yaml
# parser/config.yaml
---
import_string: "from parser import serializer"
serialize_function: "serializer.serialize"
assert_functions:
- assert_list_entries
- Write a simple test case in
test_serialize.yaml
# parser/test_serialize.yaml
---
type: "SERIALIZE"
tests:
test_something:
info: "Example Test"
input:
type: "str"
arg: "hello, world"
assert:
func: "assert_list_entries"
arg: "[\"hello\", \" world\"]"
- Run Parserkiosk
$ parserkiosk . --builtin python
Done
$ ls tests/
test_serialize.py
$ cat tests/test_serialize.py
# parser/tests/test_serialize.py
import pytest
from parser import serializer
from .commons import (
assert_list_entries,
)
def test_something():
'''
Example Test
'''
data = "hello, world"
serialized_data = serializer.serialize(data)
assert assert_list_entries(serialized_data, ["hello", " world"])
- Let's write the
assert_list_entries
function
# parser/tests/commons.py
def assert_list_entries(a, b):
for index, item in enumerate(a):
if item != b[index]:
return False
return True
- Add an
__init__.py
intests/
$ touch tests/__init__.py
- We should be able to run the suite!
# in directory parser
$ pytest .
platform linux -- Python 3.10.2, pytest-7.0.1, pluggy-1.0.0
rootdir: /x/y/z/parser
collected 1 item
tests/test_serialize.py . [100%]
================================================================================================ 1 passed in 0.01s ================================================================================================
- We wrote a simple data serialization format
- We defined a function in
config.yaml
that we use to assert entries in our lists. - We defined a test for the serializer in a
test_serialize.yaml
- We generated tests using parserkiosk
- Ran the test-suite, which worked as expected
Let's go further to see more ParserKiosk functionality.
- Let's write a test that is expected to fail, as we will supply less than two entries to our
serialize
function. We can use the builtin assert functionfail
# parser/test_serialize.yaml
---
type: "SERIALIZE"
tests:
test_something:
info: "Example Test"
input:
type: "str"
arg: "hello, world"
assert:
func: "assert_list_entries"
arg: "[\"hello\", \" world\"]"
# Add this test
test_error_less_than_two_comma_entries:
info: "Should raise an error when given a string without any comma separated values"
input:
type: "str"
arg: "helloworld"
assert:
func: "fail"
- Generate tests
$ parserkiosk . --builtin python
$ cat tests/test_serialize.py
import pytest
from parser import serializer
from .commons import (
assert_list_entries,
)
def test_something():
'''
Example Test
'''
data = "hello, world"
serialized_data = serializer.serialize(data)
assert assert_list_entries(serialized_data, ["hello", " world"])
def test_error_less_than_two_comma_entries():
'''
Should raise an error when given a string without any comma separated values
'''
data = "helloworld"
try:
serialized_data = serializer.serialize(data)
pytest.fail()
except Exception as e:
pass
- Run tests!
# in dir parser/
$ pytest -s .
============================================= test session starts ==============================================
platform linux -- Python 3.10.2, pytest-7.0.1, pluggy-1.0.0
rootdir: /x/y/z/parser
collected 2 items
tests/test_serialize.py ..
============================================== 2 passed in 0.01s ===============================================
We successfully generated a test where we can assert that an error was raised.
- Add a
de_serialize
function to convert data back into a string.
# parser/serializer.py
from functools import reduce # add this
def serialize(string):
serialized = string.split(',')
if len(serialized) < 2:
raise Exception('Need atleast two entries')
return serialized
# add this function
def de_serialize(array):
return reduce(lambda a, b: f'{a},{b}', array)
- Define tests for this function
# WARNING: This is a new ymal file! test_de_serialize not test_serialize
# parser/test_de_serialize.yaml
---
type: "DE_SERIALIZE"
tests:
test_de_serialize:
info: "Should return a string of words separated by commas"
input:
type: "raw"
arg: "[\"hello\", \" world\"]"
assert:
func: "assert_string"
arg: "\"hello, world\""
- Add new assert function, and de_serializer function in our config
# parser/config.yaml
---
import_string: "from parser import serializer"
serialize_function: "serializer.serialize"
de_serialize_function: "serializer.de_serialize" # this
assert_functions:
- assert_list_entries
- assert_string # this
- Define the function in the commons file
# parser/tests/commons.py
def assert_list_entries(a, b):
for index, item in enumerate(a):
if item != b[index]:
return False
return True
# this function
def assert_string(a, b):
return a == b
- Generate tests
# in dir parser
$ parserkiosk . --builtin python
$ ls tests/
commons.py __init__.py __pycache__ test_de_serialize.py test_serialize.py
- Run tests!
============================================= test session starts ==============================================
platform linux -- Python 3.10.2, pytest-7.0.1, pluggy-1.0.0
rootdir: /x/y/z/parser
collected 3 items
tests/test_de_serialize.py .
tests/test_serialize.py ..
============================================== 3 passed in 0.01s ===============================================