## Creature Project ## CSC323 ## UnitTests: Automated unit tests for the model import unittest from LocalWorld import LocalWorld from Species import Species from ConflictResolutionPolicy import ConflictResolutionPolicy from Predicate import Predicate from Instruction import Instruction from Rule import Rule import Direction import os.path from SpeciesDatabase import * class speciesDatabaseTest(unittest.TestCase): def setUp(self): self.sd = SpeciesDatabase.getInstance() self.helloSpecies = Species("Hello","green") self.sd.addSpecies(self.helloSpecies) def tearDown(self): SpeciesDatabase.getInstance().reset() def testgetInstance(self): '''Tests the getInstance method of a SpeciesDatabase''' self.assertTrue(isinstance(SpeciesDatabase.getInstance(),SpeciesDatabase)) def testExistence(self): """Tests if a known species is in a database""" self.assertEqual(self.sd.getSpecies("Hello"),self.helloSpecies) def testNonExistence(self): """Tests if a known species is in a database""" self.assertRaises(KeyError,self.sd.getSpecies,"foobar") def testGetByColor(self): """Tests if a known species is in a database by color""" self.assertEqual(self.sd.getSpeciesfromColor("green"),self.helloSpecies) def testgetColorfromName(self): self.assertEqual(self.sd.getColorfromName("Hello"),"green") class SpeciesDatabaseLoadTest(unittest.TestCase): def setUp(self): if not os.path.exists("conway-rule"): self.skipTest("Need file conway-rule to run this test") self.sd = SpeciesDatabase.getInstance() def testLoad(self): '''Tests loading a species database from a file''' self.sd.loadFile("conway-rule") def tearDown(self): self.sd.reset() class SpeciesDatabaseConwayTest(unittest.TestCase): def setUp(self): if not os.path.exists("conway-rule"): self.skipTest("Need file conway-rule to run this test") self.sd = SpeciesDatabase.getInstance(); self.sd.loadFile("conway-rule") def testConwayExists(self): self.assertEqual(self.sd.getSpecies("Conway").kind,"Conway") def testDeadExists(self): self.assertEqual(self.sd.getSpecies("Dead").kind,"Dead") def tearDown(self): self.sd.reset(); @unittest.skip("This test is known to fail currently") class ConwayLoadedGameTest(unittest.TestCase): def setUp(self): if not os.path.exists("conway-rule"): self.skipTest("Need file conway-rule to run this test") self.sd = SpeciesDatabase.getInstance() self.sd.loadFile("conway-rule") self.conwaySp = self.sd.getSpecies("Conway") self.deadSp = self.sd.getSpecies("Dead") self.board = LocalWorld(self.deadSp,6,6) def testConwayOneStep(self): '''Make a glider, test it for one step''' glider = [(2,0),(2,1),(2,2),(1,2),(0,1)] for loc in glider: self.board.setSpecies(loc[0],loc[1],self.conwaySp) self.board.step() shouldBeAlive=[(1,0),(1,2),(2,1),(2,2),(3,1)] for y in range(self.board.height): for x in range(self.board.width): if (x,y) in shouldBeAlive: self.assertEqual(self.board.getSpecies(x,y).kind,self.conwaySp.kind) else: self.assertEqual(self.board.getSpecies(x,y).kind,self.deadSp.kind) def tearDown(self): self.sd.reset() class ConwayGameTest(unittest.TestCase): def setUp(self): #make species ConwaySpec = Species("Conway", "green") DeadSpec = Species("Dead","grey") #make predicates two = QuantityPredicate(ConwaySpec, 2) three = QuantityPredicate(ConwaySpec, 3) #Make more complicated predictes comeAlive = OrPredicate([two,three]) becomeDead = NotPredicate(comeAlive) #Make instructions live = Instruction.Instruction(Direction.C,ConwaySpec) die = Instruction.Instruction(Direction.C,DeadSpec) #Make rules comeToLifeRule = Rule.Rule(three,[live]) liveRule = Rule.Rule(comeAlive, [live]) dieRule = Rule.Rule(becomeDead, [die]) #associate rules with species ConwaySpec.addRule(liveRule, 1) ConwaySpec.addRule(dieRule, 0) DeadSpec.addRule(comeToLifeRule, 1) #put the species in the database self.sd = SpeciesDatabase.getInstance() self.sd.addSpecies(DeadSpec) self.sd.addSpecies(ConwaySpec) self.conwaySp = self.sd.getSpecies("Conway") self.deadSp = self.sd.getSpecies("Dead") def testConwayGlider(self): '''Make a glider, test it for one step''' world = LocalWorld(self.deadSp,6,6) glider = [(2,0),(2,1),(2,2),(1,2),(0,1)] for loc in glider: world.setSpecies(loc[0],loc[1],self.conwaySp) world.step() shouldBeAlive=[(1,0),(1,2),(2,1),(2,2),(3,1)] for y in range(world.height): for x in range(world.width): if (x,y) in shouldBeAlive: self.assertEqual(world.getSpecies(x,y),self.conwaySp) else: self.assertEqual(world.getSpecies(x,y),self.deadSp) def tearDown(self): self.sd.reset() class baseTestCase(unittest.TestCase): def setUp(self): sdb = SpeciesDatabase.getInstance() sdb.addSpecies(Species("dead", "black")) sdb.addSpecies(Species("squirrel", "yellow")) sdb.addSpecies(Species("elephant", "gray")) self.dead_species = sdb.getSpecies("dead") self.squirrel_species = sdb.getSpecies("squirrel") self.elephant_species = sdb.getSpecies("elephant") self.default_world = LocalWorld(self.dead_species) self.small_world = LocalWorld(self.dead_species, 2,3) self.large_world = LocalWorld(self.squirrel_species, 40,25) #make predicate self.testPred = DirectionalTestPredicate(self.dead_species, Direction.W) #make instruction testInstruc1 = Instruction.Instruction(Direction.E,self.squirrel_species) testInstrucList = [testInstruc1] #make and add rule ##if dead to left, then create a squirrel right self.testRule = Rule.Rule(self.testPred,testInstrucList) #make predicate for elephant elePred = QuantityPredicate(self.dead_species, 8) notelePred = NotPredicate(elePred) #make instruction for elephant eleInst1 = Instruction.Instruction(Direction.S, self.elephant_species) eleInst2 = Instruction.Instruction(Direction.C, self.dead_species) eleInstLst = [eleInst1, eleInst2] #make rule #if elephant is next to anything, move south self.eleRule = Rule.Rule(notelePred, eleInstLst) #build priority #Used by predicate tests self.pred_world = LocalWorld(self.squirrel_species, 5,5) def tearDown(self): SpeciesDatabase.getInstance().reset() class LocalWorld_Init_Tests(baseTestCase): """Initialize three worlds: one with default settings, a small board, and a large board and tests all initialization settings in LocalWorld on each board""" def test_default_dimensions_test(self): """tests that the width and height of default world was set correctly""" self.assertEqual(self.default_world.height,10) self.assertEqual(self.default_world.width, 10) def test_small_dimensions_test(self): """tests that the width and height of small world was set correctly""" self.assertEqual(self.small_world.height,3) self.assertEqual(self.small_world.width, 2) def test_large_dimensions_test(self): """tests that the width and height of large world was set correctly""" self.assertEqual(self.large_world.height,25) self.assertEqual(self.large_world.width, 40) def test_default_board_test(self): """tests that the board for default world was created correctly""" for y in range(10): for x in range(10): self.assertEqual(self.default_world.getSpecies(x,y), self.dead_species) def test_small_board_test(self): """tests that the board for small world was created correctly""" for y in range(3): for x in range(2): self.assertEqual(self.small_world.getSpecies(x,y),self.dead_species) def test_large_board_test(self): """tests that the board for large world was created correctly""" for y in range(25): for x in range(40): self.assertEqual(self.large_world.getSpecies(x,y),self.squirrel_species) def test_toroid_test(self): """tests that elements in a board can be accessed with wrap-around toroids""" for y in range(-100,100): for x in range(-100,100): self.assertEqual(self.large_world.getSpecies(x,y), self.large_world.getSpecies(x%25,y%40)) def test_instruction_test(self): """tests that the instructions grid in a world is initialized correctly""" for y in range(25): for x in range(40): self.assertEqual(self.large_world.instructions[x][y],[None]) class LocalWorld_Tests(baseTestCase): """Tests all methods within LocalWorld""" def test_setandgetSpecies_test(self): """Tests that setSpecies sets a species in a given location correctly.""" #inside the grid self.assertEqual(self.large_world.getSpecies(1,1), self.squirrel_species) self.large_world.setSpecies(1, 1, self.dead_species) self.assertEqual(self.large_world.getSpecies(1,1), self.dead_species) def test_setSpeciesOutside(self): """Tests that setSpecies sets a species in a given location, outside the grid, correctly.""" #outside the grid self.assertEqual(self.small_world.getSpecies(1,5), self.dead_species) self.small_world.setSpecies(1, 5, self.squirrel_species) self.assertEqual(self.small_world.getSpecies(1,5), self.squirrel_species) def test_step_test(self): pass class Species_Tests(baseTestCase): def test_init(self): """Checks the fields of dead_species have been initialized correctly.""" self.assertEqual(self.dead_species.kind, "dead") self.assertEqual(self.dead_species.color, "black") self.assertEqual(self.dead_species.rules, []) def test_addRule(self): """Tests that addRule works as expected""" self.squirrel_species.addRule(self.testRule) self.assertEqual(self.squirrel_species.rules[0], self.testRule) def test_removeRule(self): """Tests that RemoveRule properly removes rules and handles exceptions""" self.squirrel_species.removeRule(self.testRule) #print(self.squirrel_species.rules) self.assertEqual(self.squirrel_species.rules.__len__(), 0) #add check for exception raised when removing a rule not in a list. class Directional_Predicate_Tests(baseTestCase): def test_directional_false_N(self): """Tests each direction""" for y in range(self.pred_world.height): for x in range(self.pred_world.width): self.assertFalse(DirectionalTestPredicate(self.dead_species,Direction.N).holds(self.pred_world,[x,y])) def test_directional_false_NE(self): """Tests each direction""" for y in range(self.pred_world.height): for x in range(self.pred_world.width): self.assertFalse(DirectionalTestPredicate(self.dead_species,Direction.NE).holds(self.pred_world,[x,y])) def test_directional_false_E(self): """Tests each direction""" for y in range(self.pred_world.height): for x in range(self.pred_world.width): self.assertFalse(DirectionalTestPredicate(self.dead_species,Direction.E).holds(self.pred_world,[x,y])) def test_directional_false_SE(self): """Tests each direction""" for y in range(self.pred_world.height): for x in range(self.pred_world.width): self.assertFalse(DirectionalTestPredicate(self.dead_species,Direction.SE).holds(self.pred_world,[x,y])) def test_directional_false_S(self): """Tests each direction""" for y in range(self.pred_world.height): for x in range(self.pred_world.width): self.assertFalse(DirectionalTestPredicate(self.dead_species,Direction.S).holds(self.pred_world,[x,y])) def test_directional_false_SW(self): """Tests each direction""" for y in range(self.pred_world.height): for x in range(self.pred_world.width): self.assertFalse(DirectionalTestPredicate(self.dead_species,Direction.SW).holds(self.pred_world,[x,y])) def test_directional_false_W(self): """Tests each direction""" for y in range(self.pred_world.height): for x in range(self.pred_world.width): self.assertFalse(DirectionalTestPredicate(self.dead_species,Direction.W).holds(self.pred_world,[x,y])) def test_directional_false_NW(self): """Tests each direction""" for y in range(self.pred_world.height): for x in range(self.pred_world.width): self.assertFalse(DirectionalTestPredicate(self.dead_species,Direction.NW).holds(self.pred_world,[x,y])) def test_directional_false_C(self): """Tests each direction""" for y in range(self.pred_world.height): for x in range(self.pred_world.width): self.assertFalse(DirectionalTestPredicate(self.dead_species,Direction.C).holds(self.pred_world,[x,y])) def test_directional_true_N(self): """Tests each direction""" for y in range(self.pred_world.height): for x in range(self.pred_world.width): self.assertTrue(DirectionalTestPredicate(self.squirrel_species,Direction.N).holds(self.pred_world,[x,y])) def test_directional_true_NE(self): """Tests each direction""" for y in range(self.pred_world.height): for x in range(self.pred_world.width): self.assertTrue(DirectionalTestPredicate(self.squirrel_species,Direction.NE).holds(self.pred_world,[x,y])) def test_directional_true_E(self): """Tests each direction""" for y in range(self.pred_world.height): for x in range(self.pred_world.width): self.assertTrue(DirectionalTestPredicate(self.squirrel_species,Direction.E).holds(self.pred_world,[x,y])) def test_directional_true_SE(self): """Tests each direction""" for y in range(self.pred_world.height): for x in range(self.pred_world.width): self.assertTrue(DirectionalTestPredicate(self.squirrel_species,Direction.SE).holds(self.pred_world,[x,y])) def test_directional_true_S(self): """Tests each direction""" for y in range(self.pred_world.height): for x in range(self.pred_world.width): self.assertTrue(DirectionalTestPredicate(self.squirrel_species,Direction.S).holds(self.pred_world,[x,y])) def test_directional_true_SW(self): """Tests each direction""" for y in range(self.pred_world.height): for x in range(self.pred_world.width): self.assertTrue(DirectionalTestPredicate(self.squirrel_species,Direction.SW).holds(self.pred_world,[x,y])) def test_directional_true_W(self): """Tests each direction""" for y in range(self.pred_world.height): for x in range(self.pred_world.width): self.assertTrue(DirectionalTestPredicate(self.squirrel_species,Direction.W).holds(self.pred_world,[x,y])) def test_directional_true_NW(self): """Tests each direction""" for y in range(self.pred_world.height): for x in range(self.pred_world.width): self.assertTrue(DirectionalTestPredicate(self.squirrel_species,Direction.NW).holds(self.pred_world,[x,y])) def test_directional_true_C(self): """Tests each direction""" for y in range(self.pred_world.height): for x in range(self.pred_world.width): self.assertTrue(DirectionalTestPredicate(self.squirrel_species,Direction.C).holds(self.pred_world,[x,y])) class Quantity_PredicateTests(baseTestCase): def test_counting(self): """Tests various counting predicates.""" self.assertEqual(CountingPredicate(self.squirrel_species,8,int.__eq__).holds(self.pred_world,[2,2]),True) def test_quantity(self): """Tests that the quantity predicate works for any quantity""" for y in range(self.pred_world.height): for x in range(self.pred_world.width): self.assertTrue(QuantityPredicate(self.squirrel_species,8).holds(self.pred_world,[x,y])) self.assertFalse(QuantityPredicate(self.squirrel_species,3).holds(self.pred_world,[x,y])) self.assertFalse(QuantityPredicate(self.squirrel_species,0).holds(self.pred_world,[x,y])) self.assertFalse(QuantityPredicate(self.dead_species,8).holds(self.pred_world,[x,y])) self.assertFalse(QuantityPredicate(self.dead_species,3).holds(self.pred_world,[x,y])) self.assertTrue(QuantityPredicate(self.dead_species,0).holds(self.pred_world,[x,y])) self.pred_world.setSpecies(2,2,self.dead_species) self.assertTrue(QuantityPredicate(self.dead_species,1).holds(self.pred_world,[1,2])) self.assertTrue(QuantityPredicate(self.dead_species,1).holds(self.pred_world,[1,1])) self.assertFalse(QuantityPredicate(self.dead_species,1).holds(self.pred_world,[4,4])) self.pred_world.setSpecies(4,4,self.dead_species) self.assertTrue(QuantityPredicate(self.dead_species,1).holds(self.pred_world,[0,0])) self.assertTrue(QuantityPredicate(self.dead_species,2).holds(self.pred_world,[3,3])) class AndPredicateTests(baseTestCase): """Tests that the 'and' predicate works for multiple sizes of predicate lists""" def test_both_true(self): '''Tests if returns True with 2 True Preds''' pred = AndPredicate([QuantityPredicate(self.squirrel_species,8),DirectionalTestPredicate(self.squirrel_species,Direction.N)]) self.assertEqual(pred.holds(self.pred_world, [0,4]),True) def test_one_false(self): '''Tests if returns False with 1 True, 1 False ''' pred = AndPredicate([QuantityPredicate(self.squirrel_species,3),DirectionalTestPredicate(self.squirrel_species,Direction.E)]) self.assertEqual(pred.holds(self.pred_world, [0,4]),False) def test_four_trues(self): '''Tests if returns True with 4 Trues''' pred = AndPredicate([QuantityPredicate(self.squirrel_species,8),DirectionalTestPredicate(self.squirrel_species,Direction.N), QuantityPredicate(self.dead_species,0),DirectionalTestPredicate(self.squirrel_species,Direction.C)]) self.assertEqual(pred.holds(self.pred_world, [6,6]),True) class OrPredicateTests(baseTestCase): """Tests that the 'or' predicate works for multiple sizes of predicate lists""" def test_both_true(self): """ Tests if returns True with 2 True Preds""" pred = OrPredicate([QuantityPredicate(self.squirrel_species,8),DirectionalTestPredicate(self.squirrel_species,Direction.N)]) self.assertEqual(pred.holds(self.pred_world, [0,4]),True) def test_one_true(self): """Tests if returns True with 1 True, 1 False""" pred = OrPredicate([QuantityPredicate(self.squirrel_species,3),DirectionalTestPredicate(self.squirrel_species,Direction.E)]) self.assertEqual(pred.holds(self.pred_world, [0,4]),True) def test_half_true(self): """Tests if returns True with 2 Trues, 2 Falses""" pred = OrPredicate([QuantityPredicate(self.squirrel_species,4),DirectionalTestPredicate(self.squirrel_species,Direction.N), QuantityPredicate(self.dead_species,0),DirectionalTestPredicate(self.dead_species,Direction.SE)]) self.assertEqual(pred.holds(self.pred_world, [3,3]),True) def test_all_false(self): """Tests if returns False with 3 Falses""" pred = OrPredicate([QuantityPredicate(self.squirrel_species,4),DirectionalTestPredicate(self.dead_species,Direction.S), DirectionalTestPredicate(self.dead_species,Direction.SE)]) self.assertEqual(pred.holds(self.pred_world, [0,0]), False) class NotPredicateTests: """Tests that the 'not' predicate holds for both a True and False predicate""" def test_return_true(self): """Returns True for a False Predicate""" pred = NotPredicate(OrPredicate([QuantityPredicate(self.squirrel_species,4), DirectionalTestPredicate(self.dead_species,Direction.S), DirectionalTestPredicate(self.dead_species,Direction.SE)])) self.assertEqual(pred.holds(self.pred_world, [0,0]), True) def test_return_false(self): """Returns False for a True Predicate""" pred = NotPredicate(AndPredicate([QuantityPredicate(self.squirrel_species,8), DirectionalTestPredicate(self.squirrel_species,Direction.N)])) self.assertEqual(pred.holds(self.pred_world, [0,4]),False) class Board_Tests(baseTestCase): def test_create(self): #On squirrel rules, one step arguement should contain 2 squirrels self.squirrel_species.addRule(self.testRule) self.dyn_world = LocalWorld(self.dead_species, 5,5) self.dyn_world.setSpecies(1,1,self.squirrel_species) self.dyn_world.specDatabase.addStrengthPair(self.squirrel_species,self.dead_species,1) self.dyn_world.step() self.assertNotEqual(self.dead_species, self.squirrel_species) for y in range(self.dyn_world.height): for x in range(self.dyn_world.width): if y==1 and (x==1 or x==2): self.assertEqual(self.dyn_world.getSpecies(x,y), self.squirrel_species) else: self.assertEqual(self.dyn_world.getSpecies(x,y), self.dead_species) def test_movement(self): #Our elephant should move if there's something nearby... self.elephant_species.addRule(self.eleRule) self.ele_world = LocalWorld(self.dead_species,5,5) self.ele_world.setSpecies(2,2,self.elephant_species) self.ele_world.specDatabase.addStrengthPair(self.squirrel_species,self.dead_species,1) self.ele_world.specDatabase.addStrengthPair(self.elephant_species,self.dead_species,1) self.ele_world.specDatabase.addStrengthPair(self.elephant_species,self.squirrel_species,1) self.ele_world.step() #Nothing nearby, so it shouldn't move for y in range(self.ele_world.height): for x in range(self.ele_world.width): if x == 2 and y == 2: self.assertEqual(self.ele_world.getSpecies(x,y), self.elephant_species) else: self.assertEqual(self.ele_world.getSpecies(x,y), self.dead_species) #The squirrel should not do anything. The elephant should move. self.ele_world.setSpecies(3,2,self.squirrel_species) self.ele_world.step() for y in range(self.ele_world.height): for x in range(self.ele_world.width): if x == 2 and y == 3: self.assertEqual(self.ele_world.getSpecies(x,y), self.elephant_species) elif x == 3 and y == 2: self.assertEqual(self.ele_world.getSpecies(x,y), self.squirrel_species) else: self.assertEqual(self.ele_world.getSpecies(x,y), self.dead_species) if __name__ == "__main__": unittest.main() """things to test: 1) LocalWorld a)board b)getSpecies c)setSpecies d)str e)step f)apply instructions g)get instructions 2) Species a) kind, name, color b) addRules c) remove/change attributes 3) Rules: a) Instructions b) Predicates i) Logic ii) Test a) Quantity b) Directional 4) ConflictResolution """