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)
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
Post a Comment