BranchTester |
|
|
BranchTester is a testing library/framework I wrote to deal with a recurring problem I faced when writing unit tests for enterprise software. The problem was simply that of test overload - in order to test all the different scenarios and combinations of input data using a traditional unit test framework, an astoundingly large number of test methods where required. Most of these test methods were very similar and had lots of duplicated code, but were hard to refactor. BranchTester solves this problem in a relatively elegant way: it allows you to define branch points in your test method, and the test framework will go down each of the branches in turn. This allows you to reuse a lot of code, as well as test an exponential number of test scenarios with only a linear increase in code size. The code examples below illustrates how this works in a nutshell. Keep in mind that the framework offers some additional features that are not illustrated in the examples. DisclaimerBy downloading this software, you understand and agree that I provide absolutely no warranties (either express or implied) about the software. In no event will I or other contributors to the software be liable for any direct, indirect, incidental, special, exemplary, or consequential damages arising in any way out of the use of this software, even if advised of the possibility of such damage. Download BranchTester.jar (26,078 bytes) Using BranchTesterConsider a test suite for a web application with a credit card form. The form supports Visa and Mastercard, and allows people to sign up using billing addresses in the US and Canada. With a traditional test framework combination (such as JUnit and Webtest), the test code would look like this: testSignupVisaInCanada() { robot.fillUsername("johndoe"); robot.fillCreditCard("Visa", "4111111111111111"); robot.fillAddress("200 University Avenue, Waterloo", "Canada"); robot.submit(); assert(robot.canSeeText("Success")); } testSignupVisaInUsa() { robot.fillUsername("johndoe"); robot.fillCreditCard("Visa", "4111111111111111"); robot.fillAddress("59 Evergreen Terrace, Springfield", "USA"); robot.submit(); assert(robot.canSeeText("Success")); } testSignupMastercardInCanada() { robot.fillUsername("johndoe"); robot.fillCreditCard("Mastercard", "4123123123123123"); robot.fillAddress("200 University Avenue, Waterloo", "Canada"); robot.submit(); assert(robot.canSeeText("Success")); } testSignupMastercardInUsa() { robot.fillUsername("johndoe"); robot.fillCreditCard("Mastercard", "4123123123123123"); robot.fillAddress("59 Evergreen Terrace, Springfield", "USA"); robot.submit(); assert(robot.canSeeText("Success")); } Clearly, this code will grow exponentially with the number of parameters and options allowed. Instead, using the BranchTester, the test code would look like this: testSignup(BranchManager manager) { robot.fillUsername("johndoe"); switch (manager.nextBranch("card", 2)) { case 0: robot.fillCreditCard("Visa", "4111111111111111"); break; case 1: robot.fillCreditCard("Mastercard", "4123123123123123"); break; } switch (manager.nextBranch("address", 2)) { case 0: robot.fillAddress("200 University Avenue, Waterloo", "Canada"); break; case 1: robot.fillAddress("59 Evergree Terrace, Springfield", "USA"); break; } robot.submit(); assert(robot.canSeeText("Success")); } As you can see, the BranchTester code is much shorter, but tests the exact same set of tests as the previous code snippet. The BranchTester framework will automatically run the testSignup method over and over until all the branches defined in the code have been exhausted. The code below shows what a full test class would look like using the BranchTester framework. import com.stakface.lib.test.*; public class SomeTest implements Testable { public void setup() { System.out.println( "This gets called before each test branch" ); } public void cleanup() { System.out.println( "This gets called after each test branch" ); } @TestEntryPoint( TestRunnerImpl.class ) // run using a non-branch test runner public void testFoo() { Asserter.assertEqual( "This will never fail", "BranchTester", "BranchTester" ); } static enum CreditCards { VISA, MASTERCARD } @TestEntryPoint( BranchTestRunner.class ) // run using the branch test runner @RandomSample( 0.5 ) // run 50% of possible branches (random selection) public void testBar( BranchManager manager ) { String name = "johndoe"; CreditCards card = manager.nextBranch( "card", CreditCards.values() ); String country = (manager.nextBranch( "country", 2 ) == 0 ? "Canada" : "USA"); System.out.println( "Test signup " + card + " in " + country ); } } Once compiled, the above could be run using the Tester class in the provided library: echo "SomeTest" | java com.stakface.lib.test.Tester BranchTester is written using Java 5.0, and therefore is useful only for testing Java applications. However, BranchTester is public domain software, so feel free to port it to other languages/platforms, or otherwise hack it up any way you feel would be useful. If you do make modifications to it that you think would be widely useful, please do let me know and I can back-port them to this code (of course, since BranchTester is public domain, you are not obligated to release any modifications you make). |
(c) Kartikaya Gupta, 2004-2024. User comments owned by their respective posters. All rights reserved. You are accessing this website via IPv4. Consider upgrading to IPv6! |