working on manual tests for the Python Ternary Search Tree

Hello peoples!
This one will be about how I prepare to write a unittest/pytest.
I know there's the whole 'test first' approach, but this works best for me so far.
If it's not your thing, groovy.

TODO:
1) make unittest  (started: see below)
2) compare pytest (started: see below)
So far it looks like there is no advantage, other than some extra typing practice, to doing Unittest over pytest

Update: adding the started unittest and pytest

The Ternary search tree for this exercise in the LMPTHW book may be protected by Zed's copyright, so I shall instead share some testing techniques I am working on.

I want to do a unittest for this exercise, because well....  Most testing libraries are built on top of the already built in unittest that python has.

Instead of fumbling to write out the tests for pytest / unittest;
I first write out the different print calls I'd like to see;
Then I'll write the unittest or pytest around what I would like to see tested from those results.

The better I understand the engine, the better I understand how the vehicle runs.

As a master copy exercise, the tree itself is in majority Zed's code, but the testing will be my own.

Where you see:
              tree = TSTree()
Will be where I put the tree into the methods, and then test the different parts I made for it.

Some of this, like pretty_highlights, was just to give myself a bit of fun while I did it, and I really like being able to visualize what is going on in the code.
* Unittest, and pytest below manual test:::
***********  manual_tests.py************

#!usr/bin/python3
#! -*- coding: ascii -*-
from ex23 import TSTreeNode, TSTree
import random

def random_letters(number):
    # https://stackoverflow.com/questions/51180859/how-to-generate-random-letters-in-python
    # produce a random string of letters by size range number.

    if type(number) != int:
        message = "\n argument --> \n method -- random_letters(number) --->
                           \n number is int type only"
        x = type(number)
        message = message + "\n Got type: "  + str(x) + "  instead"
        raise TypeError(message)

    else:
        chars = 'ACTg'
        return ''.join(random.choice(chars) for x in range(number))
 
def make_list_set_TSTree(size, tree=TSTree(), alist=[]): 
   """
    fill the default tree, and an accomaning list with  a random letter
    string of size : size  , and return tree and list for testing 
    """
    if type(size) != int:
        message = ("\n arguement --->> size, \n for make_list_set_TSTree() \n can only be of 'int'         
                          type.\n")
        x = type(size)
        message = message + "Got type: " + str(x) + "    instead"
        raise TypeError(message)

    for i in range(0, size):
        Dna = random_letters(8)
        tree.set(Dna, Dna)
        alist.append(Dna)
        i+=1 
    return tree, alist

def print_shortest(alist, tree):
    """
    With alist, and tree as arguements, use the list of strings, to search through given
    tree for the shortest matching string in the tree
    """
    print("***   shortest  ***")
    for item in alist:
        #first two letters
        astring = item[:-6]
        result = tree.find_shortest(astring)
        print(result)

def print_all(alist, tree):   
    """
    with given list of strings, search given tree for all items in tree
    that contain the search strings.
    """           
    print("***  all ***")
    for item in alist:
         #first two letters
         astring = item[:-6]
         result = tree.find_all(astring)
         print(astring)
         print(result)


def pretty_highlights(astring, lth, color=True):
    """
    lth = letters to be highlighted
    take a string, and place ascii escape characters in place 
    to color the desired lth,
    Pytest would probably hate all the escape colors.
    This is intended for printing to command prompt highlighted letters in a string
    it has no other purpose at the moment
    """
    # Need to add -- raise errors for wrong types in arguements
    red = "\u001b[31m"
    highlight_blue = "\u001b[46m"
    reset = "\u001b[0m"

    split_string = astring.split()
    newstring = ''
    print("----seeking :", lth)

    for item in split_string:
        for letters in item:
         
            if letters in lth:
                if color:
                    letters = highlight_blue + letters + reset
                else:
                    pass
     
            newstring = newstring + letters
        newstring = newstring + " "
    return newstring
 

def print_contains(somelist, tree, test=False):
   # use tree's find_all to fill a list with matching finds
 
    print("***  contains  ***")
    r_string_list = []
    result = []
 
    # use tree's find_all to fill a list with matching finds
    for item in somelist:
        r_string = item[:-6]
        r_string_list.append(r_string)
        x = tree.find_all(r_string)
        result.append(x)

    if test == True:
        print("****** testing results, no ascii escape characters *****")
    else:
        print("***** Pretty HIGHLIGHTS (for command prompt manual test results) *****")
    test_number = 0
    i = 0
    for item in result: # for the lists in the result list:
     
        test_number += 1
        if len(item) == 0: # pass if list is empty
            pass
        else:
            for searchstring in item: # for item in the list
             
                letters = r_string_list[i] # for automated testing of method
                # this could become a argument in the method definition
                if not test:
                    print(item)
                    newstring = pretty_highlights(searchstring, letters)
                    message = "--->>   " + str(test_number) + " --->>  " + letters
                    print(message)
                    print(newstring)
                else:
                    message = " ---->>  " + str(test_number) + " ----->>    " + letters
                    print(message)
                    print("string =", searchstring)
                    print("letters searched =", letters)
        i += 1         

####  Running the test items in command prompt / terminal / shell             
#tree, Dna_list = make_list_set_TSTree(True) 
tree, Dna_list = make_list_set_TSTree(5)
#failtest = random_letters(7.8)
#print_contains(Dna_list, tree)
#print_shortest(Dna_list, tree)
#print_all(Dna_list, tree)
print(Dna_list)
havok = pretty_highlights("floors and flaws falter not to meet me.", "fools drive malevolent laws." )
print(havok)

######      Unittest ##########

#!usr/bin/python3
import unittest
from ex23 import TSTreeNode, TSTree


"""
Unittest file for Ternary Search Tree,
ex 23 of LMPTHW
"""


apple_tree = ['asphyxiate', 'ax', 'ape', 'aggrigate', 'attitude', 'apple', 'axis']
duplicates = ['ax', 'ax', 'axis', 'axis']
TREE = TSTree()
pine_tree = ['christmas', 'paper', 'fresh', 'forest']
TREE2 = TSTree()

class TestTSTree(unittest.TestCase):

  def test_set(self):
"""
setting size in the T.S.Tree almost got me.
The value overwrites a duplicate value, because the len of the string is at an end
and the keys were all equal.
Only increase size if value == None when value is set
"""
    for fruit in apple_tree:
      TREE.set(fruit, fruit)

    length_apple = len(apple_tree)
    length_TREE = TREE.dump_root(count=True)
    self.assertEqual(length_apple, length_TREE)

 def test_duplicate_sets(self):
    for copies in duplicates:
      TREE.set(copies, copies)

    axes_len = len(set(duplicates))
    length_TREE = TREE.dump(count=True)
    self.assertEqual(axes_len, length_TREE)

  def test_error(self):
      for scent in pine_tree:
        TREE2.set(scent, scent)
      with self.assertRaises(TypeError):
          TREE2.get(9)


if __name__ == '__main__':
    unittest.main()


####### pytest  #######

#!usr/bin/python3
import pytest
"""
So far it seems like pytest will not interfere with unittest
"""
apple_tree = ['asphyxiate', 'ax', 'ape', 'aggrigate', 'attitude', 'apple', 'axis']
TREE = TSTree()
pine_tree = ['christmas', 'paper', 'fresh', 'forest']
TREE2 = TSTree()

def add(a, b):
  if type(a) == int and type(b) == int:
    return a + b
  else:
    raise TypeError

def test_add():
    with pytest.raises(TypeError):
        add('string', 7)



def test_set():
    for fruit in apple_tree:
        TREE.set(fruit, fruit)
    assert len(apple_tree) == TREE._size


def test_errors():
    with pytest.raises(TypeError):
        TREE.get(9)

     


Comments

Popular posts from this blog

playing with color in powershell python

JavaScript Ascii animation with while loops and console.log

playing with trigonometry sin in pygame