You are on page 1of 21

Introduction to Unit Testing SE 2 Tutorial

Herman Lee May 26, 2008

Based on tutorial slides prepared by Thiago Bartolomei SE 3 lecture slides prepared by Paulo Alencar

Testing Stages
Unit testing
Testing of individual components

Integration testing
Testing to expose problems arising from the combination of components

System testing
Testing the complete system prior to delivery

Acceptance testing
Testing by users to check that the system satisfies requirements. Sometimes called alpha testing

Approaches to Low Level Testing


Debugging/Output calls
Cannot be automated Time consuming Application and test code get tangled (output calls)

Unit testing
Set of test cases targeting a single module and organized in test suites Strongly encouraged by the agile community

More Reasons to do Unit Testing


Provide a working specification of the functional code Automation
Write test once, use many times Regression tests incorrect changes discovered immediately more confidence in the code

Test Driven Design (TDD)

TDD = Test First Development + Refactoring

Test First Development


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. (Robert C. Martin) Idea is to write first the unit tests for a module, and then implement the module. Why?
Writing the test makes you understand better the functional code and thus design it better (from the client perspective) Test becomes a documentation artifact, that clearly states the intention of the module

Test Driven Design Steps


Write tests that fail Implement modules to make tests pass Run all tests to make sure nothing is broken Refactor to keep code clean Continue development

Unit Testing with JUnit


Unit testing framework from Kent Beck (XP) and Erich Gamma (Gang of Four) Tool to support one of XP best practices Integrated in the Eclipse IDE Followed by cppUnit, phpUnit, pyUnit, etc

Preparing Eclipse Project


Create a regular project Project properties
Build Path add JUnit as a library (already shipped with Eclipse) Build Path optionally add a folder for tests Compiler if JUnit version 4, use Java version 5

That's it!

Example 1 Test Case (JUnit 3)


1) Test class must subclass TestCase. Usually it is named by adding suffix Test to tested class name. 2) Test methods must have prefix test 3) assertTrue(), assertEquals(), etc, give test pass conditions. E.g. assertTrue(x==10); 4) Test fixture a common environment to run a set of similar tests. Use setUp() and tearDown() methods to create and destroy the environment

Example 2 Test Suite (JUnit 3)


1) Test cases are organized in suites by subclassing (or constructing) TestSuite 2) Add single tests (methods) to suite using the add method or let JUnit extract them from the whole test case class 3) Execute tests using a test runner (in command line, standalone application or integrated in Eclipse)

JUnit 4
Test Cases
No longer have to extend TestCase Test methods annotated with @org.junit.Test setUp/tearDown annotated with @Before/@After Assertions statically accessed from Assert

Test Suites
No longer extend TestSuite Annotated with RunWith and Suite

Example

Source: http://www.devx.com/Java/Article/31983/0/page/1

JUnit 3 vs. JUnit 4

Source: http://www.devx.com/Java/Article/31983/0/page/2

DEMO in Eclipse

Some problems you may encounter


How to test a class A that depends on class B, if B has not been implemented yet?
Use a fake class B, called a Mock class Remember that classes should depend on interfaces B should be an interface! Note how this forces you to think about and minimize the dependencies, in order to make testing easier!

Some problems you may encounter


How to test a class that is very big and participates in many scenarios?
Rethink why this class is so big (God Class = Bad Smell) Refactor it in several smaller classes with well defined functionality and test them individually.

Some problems you may encounter


Where do I put my tests?
Either in the same package as the tested class:
pack.TheClass, pack.TheClassTest

Or in a test package:
pack.TheClass, pack.test.TheClassTest

Also, in an Eclipse project, you can have different source folders with the same package:
src/pack.TheClass, test/pack.TheClassTest Advantage you have protected access to the class

Some problems you may encounter


How to test UI?
Test functionality by accessing directly the lower tier (maybe a Facade or MVC pattern?) Testing UI itself usually requires specific tool support - Ex. HTTPUnit to do webpages testing

References / Further Study


Test Driven Development (TDD)
Test Driven Development: By Example, by Kent Beck http://www.agiledata.org/essays/tdd.html

Agile Software Development, Refactoring, Test First Design


Agile Software Development: Principles, Patterns, and Practices, by Robert C. Martin Refactoring: Improving Design of Existing Code, by Martin Fowler http://www.xprogramming.com and .org

References / Further Study


Unit test design patterns
http://www.marcclifton.com/tabid/87/Default.aspx http://www-106.ibm.com/developerworks/library/jmocktest.html

JUnit
http://www.junit.org JUnit 3 vs 4
http://www.devx.com/Java/Article/31983

You might also like