Skip to content

Latest commit

 

History

History
255 lines (234 loc) · 6.92 KB

HOWTO.md

File metadata and controls

255 lines (234 loc) · 6.92 KB

Basic Example

Let's write a simple "parser", it should:

  1. Take a string containing words that are separated by commas
  2. Should return a list of those words.
  3. Enforce atleast two entries in the list (two words, one comma)

  1. Initialize parser module
$ mkdir parser
$ cd parser
$ touch __init__.py
  1. Initialize serializer
# parser/serializer.py
def serialize(string):
    serialized = string.split(',')
    if len(serialized) < 2:
        raise Exception('Need atleast two entries')
    return serialized
  1. Install dependencies (ParserKiosk and Pytest)
pip install parserkiosk pytest
  1. Write a simple config.yaml
# parser/config.yaml
---
import_string: "from parser import serializer"
serialize_function: "serializer.serialize"
assert_functions:
  - assert_list_entries
  1. 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\"]"
  1. 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"])
  1. 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
  1. Add an __init__.py in tests/
$ touch tests/__init__.py
  1. 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 ================================================================================================

Recap:

  1. We wrote a simple data serialization format
  2. We defined a function in config.yaml that we use to assert entries in our lists.
  3. We defined a test for the serializer in a test_serialize.yaml
  4. We generated tests using parserkiosk
  5. Ran the test-suite, which worked as expected

Let's go further to see more ParserKiosk functionality.

  1. 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 function fail
# 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"
  1. 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
  1. 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.

Let's add deserialization functionality to our serializer

  1. 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)
  1. 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\""
  1. 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
  1. 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
  1. Generate tests
# in dir parser
$ parserkiosk . --builtin python
$ ls tests/
commons.py  __init__.py  __pycache__  test_de_serialize.py  test_serialize.py
  1. 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 ===============================================