Unit Testing LEVEL GAME
Syntax varies based on framework TDD goals are the same regardless of language Approach to unit testing (e.g., what to test) is same/similar for various languages UNIT TESTING IS NOT JUST JAVA
BLACK BOX VS WHITE BOX CriteriaBlack Box TestingWhite Box Testing Definition Black Box Testing is a software testing method in which the internal structure/ design/ implementation of the item being tested is NOT known to the tester White Box Testing is a software testing method in which the internal structure/ design/ implementation of the item being tested is known to the tester. Levels Applicable To Mainly applicable to higher levels of testing: Acceptance Testing System Testing Mainly applicable to lower levels of testing: Unit Testing Integration Testing ResponsibilityGenerally, independent Software TestersGenerally, Software Developers Programming Knowledge Not RequiredRequired Implementation Knowledge Not RequiredRequired Basis for Test Cases Requirement SpecificationsDetail Design From:
WHAT TO TEST
Create pieces array Call interact Use getters or return type to verify correct behavior If interact with adjoining piece, put that piece & yours on board If interact within range, be sure to test locations within range PLUS one beyond TEST INTERACTION
Create pieces array Call move Use getters or return type to verify correct behavior Test ends (don’t go GameEngine.BOARD_SIZE-1) TEST MOTION
Can’t test random behavior deterministically Need to run method multiple times Do all possible results actually occur? Do the possible results account for ALL results? (i.e., no invalid moves) What if LOTS of valid results? (e.g., any location) Test ends Identify “categories” of possibilities If limited number of possibilities, test each one E.g., move one to right or left TEST RANDOM MOVEMENT
What if the player is within “range” of more than one piece? We’re not testing this, but the approach would be: Create a GameEngine Create a pieces array Add a setter to GameEngine for the pieces array Call interaction This would not be in the scope of unit testing pieces. This might be a unit test for the GameEngine. BUT, tests need to run quickly. Can’t test every scenario. TEST MULTIPLE INTERACTION
EMMA TEST COVERAGE
Not required for 306, but useful tool (some companies strive for close to 100% test coverage) Run the tests, see what parts of your code were/were not tested EMMA CODE COVERAGE
SNIPER INTERACT COVERED Entire interact method was tested
DOORMAT NOT COVERED - OK move method of RandomMotionPiece and Minion not covered – shouldn’t be other move-related (e.g., setLocation) not covered – shouldn’t be interact method of Minion not covered. oops always returns NONE. Do we need to test? Yes, if this is the spec. Because if someone changes that, tests will capture. LevelEngine not covered – shouldn’t be
PRIZE PARTIALLY COVERED yellow: 1 of 4 branches missed Why? my tests are only for location, don’t test if prize already won (first row) same location prize Won true false true false
TYPO IN TEST oops, this should be i=11 (kangalo is at location 10)
AN EXAMPLE
How much of your code are you actually testing? coverage-vs-branch-coverage.html coverage-vs-branch-coverage.html public static int doSomething(int x, int y, int z) { int val = 100; if (x > y) val += 10; if (x < z) val += 20; if (z > 20) val += 100; return va l; } How to address? (on your own) and-path-coverage-testing-in-java.html and-path-coverage-testing-in-java.html TEST COVERAGE (WHITE BOX) Quick: w/o looking at next slide, what tests would you write for this? Write down values for x, y and z (plus return value). Turn this in for class participation credit
PATH COVERAGE Condition 1: x > y Condition 2: x < z Condition 3: z > XYZ123Result TTT > 1020 < 3030 > TTF > 1015 < 1818 > TFT > 2030 < 2525 > TFF > 2020 < 1515 > FTT > 5015 < 2525 > FTF > 5010 < 2515 > FFT > 5030 < 2525 > FFF > 5030 < 2515 > 20100
UNIT public void pathTest() { assertEquals(230, TestCoverage.doSomething(20, 10, 30)); assertEquals(130, TestCoverage.doSomething(15, 10, 18)); assertEquals(210, TestCoverage.doSomething(30, 20, 25)); assertEquals(110, TestCoverage.doSomething(30, 20, 15)); assertEquals(220, TestCoverage.doSomething(15, 50, 25)); assertEquals(120, TestCoverage.doSomething(10, 50, 15)); assertEquals(200, TestCoverage.doSomething(30, 50, 25)); assertEquals(100, TestCoverage.doSomething(30, 50, 15)); }
SIDEBAR: CYCLOMATIC COMPLEXITY Based on linearly independent paths Condition 1: x > y Condition 2: x < z Condition 3: z > XYZ123Result TTT > 1020 < 3030 > TTF > 1015 < 1818 > TFT > 2030 < 2525 > FTT > 5015 < 2525 > and-path-coverage-testing-in-java.html
The cyclomatic complexity of a section of source code is the number of linearly independent paths within it. For instance, if the source code contained no control flow statements (conditionals or decision points), the complexity would be 1, since there would be only a single path through the code. If the code had one single-condition IF statement, there would be two paths through the code: one where the IF statement evaluates to TRUE and another one where it evaluates to FALSE, so the complexity would be 2. Two nested single-condition IFs, or one IF with two conditions, would produce a complexity of 4. SIDEBAR CC CONTINUED
Cyclomatic complexity is determined by drawing a control flow graph. It’s different from path coverage because you don’t test all combinations. In this example, there are 3 independent if statements. So cyclomatic complexity is 6. But there are 8 possible paths. So path coverage requires 8. SIDEBAR CC CONTINUED
Method to test all the possible discrete combinations of the parameters involved. SIDEBAR 2: ALL PAIRS TESTING