Unit testing with JUnit and CPPUnit Krzysztof Pietroszek kmpietro@swen.uwaterloo.ca
Old-fashioned low-level testing Stepping through a debugger drawbacks: 1. not automatic 2. time-consuming Littering code with stream output calls drawbacks: 1. makes code ugly (ok, nowadays you could use aspects to avoid it;-)) 2. generates to much informations
What is unit testing? Unit testing ensures that code in repository is correct 3-steps solution 1. Create a set of tests for each unit (a small piece of system, eg. a class) of code. 2. Organize tests in test suite. 3. Run automated tests after any source code changes and before check-in. The act of writing a unit test is more an act of design than of verification. It is also more an act of documentation than of verification. --Bob Martin
Advantages of unit testing Write test = understand better what has to be done Silly bugs appear immediately = less time spent on debugging Provide a working specification of your functional code Speed-up the development write test once, use test to find errors many times Gain confidence in your code Repeatable and deterministic Regression tests incorrect changes discovered immediately; unautomated refactoring enabled Encouraged by extreme Programming community
Unit testing and test-driven developement TDD is a programming technique with a side effect of ensuring that your source code is thoroughly unit tested But, there is more about testing: acceptance tests system tests
JUnit and CPPUnit history JUnit testing framework from Kent Beck (XP) and Erich Gamma(Gang of Four)...developed as a tool support for one of the best practices from extreeme Programming style...then CPPUnit came (for C++ community)
Test-driven development and JUnit/CPPUnit How to write JUnit/CPPUnit tests? Do it TDD! Workflow: 1. Think about functionality to be implemented & scenarios in which the unit to be tested will play a role. 2. Create a stub of the unit you want to implement. 3. Write a test for each scenario and/or use of the unit. 4. Make the unit fail the tests (nothing is implemented yet!). 5. Develop the unit until it passes every test. Encountered new scenario/use? - make a test before implementing it!
Example 1 - TestCase 1. Create test class by subclassing TestCase. Name it by adding sufix Test to tested class name. 2. Name test methods adding prefix test to tested method name. 3. Use asserttrue(), assertequals(), assertfalse() etc. to give test pass conditions e.g. asserttrue(x == 10); 4. Build test fixture a common environment to run a set of similar tests. Use setup() and teardown() methods to construct & deconstruct the environment.
Example 2 - TestSuit Organize tests into test suites by subclassing TestSuite class. Use add method to add test cases or let JUnit/CPPUnit to extract a tests from test case. Execute your tests using test runner. java junit.awtui.testrunner old AWT UI java junit.swingui.testrunner new Swing UI, java junit.textui.testrunner textual UI, CppUnit::TextUi::TestRunner CPPUnit text UI.
FAQ Q: Writing tests looks like LOTS of work. A: Yes, but it is proven that writing tests BEFORE occurrence of error is much more efficient and easy than writing test after. Q: I want to test class A that depends on class B which is not yet implemented? A: Create a fake class B. Its methods will only return expected values. Q: My class is so big, and is used in so many scenarios that I don't know where to start A: That indicates your modularity is bad (God Class problem). Break it up into well defined small pieces and test them individually.
FAQ Q: Where to put my tests? A: Either in the same package (package.myclass, package.myclasstest) or in the separate package (package.myclass, packagetest.myclasstest). Q: How to test UI? A: Each UI scenario is a series of events. Make a fake UI class, that will produce them! It is difficult without tool support. Q: How to test communication between processes? A: That is a system or integration test rather than unit test.
References JUnit cookbook junit.sourceforge.net/doc/cookbook/cookbook.htm CPPUnit cookbook cppunit.sourceforge.net/doc/lastest/cppunit_cookbook.html Introduction to TDD www.agiledata.org/essays/tdd.html FAQ junit.sourceforge.net/doc/faq/faq.htm Common testing patterns www.codeproject.com/gen/design/autp5.asp How to use mock objects? www-106.ibm.com/developerworks/library/j-mocktest.html