+ All Categories
Home > Documents > UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Date post: 18-Dec-2015
Category:
Upload: amos-cox
View: 223 times
Download: 0 times
Share this document with a friend
Popular Tags:
46
UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.
Transcript
Page 1: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

UNIT TESTING J2EE APPLICATIONS

Presented by:Sudheer Sabbineni.

Page 2: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

We will look at: What Unit Testing is and why you

should do it. Using the JUnit framework for unit

testing. How to incorporate unit testing into

your development cycle. How to unit test simple objects and

servlets.

Page 3: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

The reality of writing code is that even the best programmers make mistakes. As the schedule gets more demanding, programmers become overworked and even less likely to catch their mistakes. The solution is to give programmers the tools they need to catch mistakes.In this chapter we will discuss a tool that can give all these benefits a programmer-UNIT TESTING

The Concept of Unit Testing tells “Test First Design”.

Page 4: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

What is Unit Testing ? Unit Testing is a method of White box testing

that should be an important part of the development process

White box testing is distinguished from black box testing in that it focuses on the implementation details and should be performed by someone familiar with the implementation.

Unit testing only benefits the programmer if used correctly.It will streamline programming and make programmer more effective at work.

Page 5: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

When you are doing white box testing you are making sure your code works correctly. Black box testing on the other hand,is concerned with testing the system from the users prospective.The focus is on whether the requirements have been met and the actual implementation is not relevant.

Unit Testing focuses on small pieces of the system,and these individual components or units,are tested independently of other units.Unit tests should put the component through a serious of drills,including both valid and invalid inputs,to determine whether the component passed or failed each test.

Page 6: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

In practice the best person to do Unit testing is is the programmer.since the programmer interacts with the code at the low level.

As with any testing, unit tests are better written so that they are automated and easily repeated. Given the constraints the tests should be written by programmers.Although some try to add some written documentation,the process works best when the unit tests are allowed to stand alone. This is best done within a framework and,while you could write a framework yourself,there are a variety of frameworks available for this process.The premier for unit testing in java is JUnit, written by Erich Gamma and Kent Beck.

Page 7: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Essentially,a unit test is a piece of code that’s takes a predefined unit of code and manipulates it.

This Manipulation is a simulation of various inputs to the unit. A unit test’s purpose is to determine whether the unit works as designed.

A unit test should never focus on integration between components, we are merely checking the specific behavior of the unit

Page 8: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

What is a Unit ? In Object Oriented language like java, a unit

always corresponds to a class. First make sure you are really focusing on

testing a unit and not on integration or interaction between those components.

These are two major cases that confuse the issue:

1)Interface 2)Inheritance The Best approach is to test the methods in

the class they are defined in

Page 9: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

The tests that we write are related directly to the methods of the class. there are some guidelines to follow:

Don’t need to write tests for getter and setter methods unless they do something besides get and set properties.

You will need to have atleast one test per method,the key is to test a wide variety of inputs.

The various access modifiers also affect how to write tests.Your baseline is that if another method calls the method,it needs to be tested.

Your code needs to be tested either implicitly or Explicitly .there is also a very important need to document the testing and any changes made to the code on that basis

Page 10: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Introduction of JUnit Framework

Before we actually begin writing unit tests we need to understand a little about the JUnit framework and how it works.What's important to understand is not the details of JUnit but the basic idea behind what you’re doing.

How do the methods of your program actually test your class ? First the method manipulates an instance of the class being tested.This might mean calling a method or series of methods and passing in specific inputs.Once the Object has been manipulated, the methods of the program issue Assertion about the expected state of the object

Page 11: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

An Assertion is a statement that must be true if the code is working correctly.

We said that a test is a small program.In Java terms this means that you are writing a class with a main() method.The main() method when executed involves various methods in order to put the class you are testing into paces.

Page 12: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Using the JUint frameworkThe JUnit framework is a great framework for writing unit tests.

Let’s look at an example of how the JUnit framework might be applied to a class.Let’s assume we want to test a class called StringUtility that has one method, parse() which takes a string as an argument.

The test case might be called StringUtilityTest.A test case extends the junit.framework.TestCase class

For each test you want to write within the test case,you create a public,no arguments method whose name starts with test.

Page 13: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

The test case should have a main() method that invokes the run() method on a TestRunner.JUnit has both textual and graphical test runners, so you can chose whatever option you prefer.

Choosing a textual user Interface is faster when running multiple tests very frequently

When you create a testX() method,each method throws exception. This will allow all unexpected exceptions to flow up to calling environment and display as errors.

Page 14: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Within the testX( ) method,you have a variety of assertions.where and assertion is a statement about the expected state of an object.There are a variety of assert( ) methods build in TestCase that we can use.

The easiest one is assert(), which takes an optional string followed by a boolean.The string will be printed if the assertion fails.If the boolean evaluates to true the assertion passes.If the boolean evaluates to false, the assertion and thus the test fails.

Page 15: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Ex: assert(“Id of the product shall be 7” , product.getId()==7)

The idea in the above code is that the statement product.getId()==7 should evaluate to true.If it does, true will be passed to the assert() method and the assertion will pass.if the expression evaluates to false,the assertion will fail.

The other important assertions are assertEquals()assertNotNull(), assertNull().

Page 16: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

How to Approach unit Testing: Writing the tests first might seem

counterintuitive. How do you even know what to code? In a unit test you are defining the contract with

the object.You implicitly define the API,but you also define all the requirements of the component.

If you had written unit tests before the component,you would have been forced to consider various inputs to the component, including null.

Page 17: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Steps of Unit Testing: Determine the functionality of the component. Design the behavior of the component. Write the unit test to confirm the behavior of

the component. Code the component so that all the tests will

pass. Test the alternatives. Refactor the code. Write new test cases when something new

happens. Return all tests when the code changes.

Page 18: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Writing Testable code: Effective testing is to write code that is

structured in a way that makes it testable. Things that make code testable are also the

things that make good object oriented code. Modular methods and clearly defined object

roles make code much easier to test. Best way to make sure that code is easily

testable is to write the test cases first.

Page 19: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Why Unit Test:It is important in software process for various

reasons: Writing unit tests before code gives you clarity

about the requirements of the object. Since you define both the API of the object all the expected behavior,your implementation is much easier.

Unit test document the requirements for an object.

Since the requirements for the code are documented in code as opposed to an elusive Word or HTML document,the requirements stay with the code

Page 20: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Unit tests give you a measurable confidence in the quality of the code.At any time you can run your suite of unit tests and get immediate feedback on how much of your code meets requirements.

Unit tests give you the freedom to learn from the system.

Since now you have a suite of unit tests, you are free to improve the code as you learn about the application without having to worry about breaking something.

A suite of comprehensive unit test makes it easy for someone unfamiliar with the code to make changes with confidence.

Unit tests are a great way to share knowledge about the code in a way that is easy for programmers to digest,as they are easier to read and so it is easier to share code.

Page 21: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Unit Testing of Simple Objects: Two of the simple types of objects to test are

business objects and utility objects. Utility objects carry out operations that re

largely independent of the system, normally low level operations used by many objects.

A business object is a simple object whose main purpose is to store some data and represent an object in a system.

Page 22: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Unit Testing a Utility Object

We have an application that retrieves data from a database and displays onto a HTML page.The data we retrieve from the database contains greater than(>) and less than(<) symbols, which can interface the display of the HTML page.To fix this we need to write a utility class that replaces every occurrence of “>” and “<” with “&gt;” and “&lt;” respectively.

Page 23: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Package com.wrox.simple;Import junit.framework;public class HTMLScrubberTest extends TestCase{public HTMLScrubberTest(String arg1) {Super(arg1);Public static void main (String[ ] args){//invoke the run method of the textual test runner.//pass into this method a Test created by the Suite() method.Junit.text.ui.TestRunner.run(suite( ));}Public static Test suite() {//construct a test suite using the .class property of the

TestCasereturn new TestSuite(HTMLScrubberTest.class);}//…..}

Page 24: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

We will define the following test methods and add them to the test case :

public void testAlreadyScrubbed( ) throws Exception{ }public void testEmptyString( ) throws Exception{ }public void testGreaterThanAndLessThanScrubing( ) throws Exception{ }public void testGreaterThanScrubing( )throws

Exception{ }public void testLessThanScrubing( ) throws Exception{ }public void testMultipleGreaterThanScrubing( ) throws Exception{ }public void testMultipleLessThanScrubing( ) throws Exception{ }Public void testNull( ) throws exception{ }

Page 25: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

We need to compare the output of the scrub( ) method and make sure that the less than sign is replaced with &lt;.our test looks like this:

Public void testLessThanScrubbing( ) Throws Exception{

//Construct an Instance of HTML ScrubberHTMLScrubber scrub=new HTMLScrubber();

//Construct the string to pass into scrubString before =“test < test”;

//Construct the string which is expectedString after =“test &lt; test”;

/* asserting that after string should be equal to the results. */assertEquals(“string should be equal ” , after ,

scrubber.scrub(before));}

Page 26: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Package com.wrox.simple;

Public class HTMLScrubber {

Private static final char LESS_THAN=‘<’; Private static final char GREATER_THAN=‘>’; Private static final char LESS_THAN_SCRUB=‘&lt;’; Private static final char GREATER_THAN_SCRUB=‘&gt;’;

Public HTMLScrubber( ) { super( ); }

Public String scrub(String s){StringBuffer buf=new StringBuffer();For(int x=0; x< s.length(); x++) { char c=s.charAt(x);

Page 27: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

if(c==LESS_THAN) buf.append(LESS_THAN_SCRUB); else(c==GREATER_THAN) buf.append(GREATER_THAN_SCRUB); else buf.append(c ); } } Return buf.toString(); }}

In the scrub() method we iterate through each character and check if it is a greater than or a less than sign,If it is we replace with its equivalent.

Page 28: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Unit Testing a Business objectA business object is one which usually have logic in it.

Suppose as a part of our application we want to create a User object.This object is responsible for storing the user’s name as well as a Vector of Strings representing the id’s.In addition, the user object must be able to present the Vector of Strings as one comma delimneted string.It must also take in a string of this format and convert into a vector.

Page 29: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

package com.wrox.simple;import junit.framework.*;public class UserTest extends TestCase {

public UserTest(String arg1) { super(arg1); }

public static void main(String[ ] args) { junit.text.ui.TestRunner.run(suite()); }

public static Test suite() { return new TestSuite(UserTest.class); }//}

Page 30: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Now that we know the basic format of the test case, Let’s think about what we need to test.We want to make sure that when we pass in a string its will be converted to a vector. Lets define a test method to make sure that when we pass in a string the same string comes out:

public void testStringPathInEqualsStringPathOut() throws Exception { User u = new User(); String in = "1,2,3,4,5,6,7"; u.setPathString(in);

assertEquals(in, u.getPathString()); }

Page 31: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Notice that in the this test,we create an instance of user.we then pass a string in .The assumption is that when we get the path string out via the getPathString() method,it will be the same regardless of the transformation it has gone through.

Different Tests that the code need to pass are:

Public void testStringPathEmptyStringIn() Throws Exception{ User u = new User(); u.setPathString(""); assertEquals("", u.getPathString( ) ); }Public void testStringPathNullIn( ) throws Exception{ User u = new User(); u.setPathString(null); assertEquals("", u.getPathString());}

Page 32: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Package com.wrox.simpleImport java.util.*;Public class User Private String name ; Private Vector path;Public User(){Super();}Public String getName( ){return name;}Public Vector getPath( ){return path;}Public void setName(String newName ){Name= newName;}Public void setPath(Vector newPath ){path= newPath;}

Page 33: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Public String getPathString( ) {Return null;}Public set void setPathString( ) { }}

We Still need to give the method body for the methods in the user class to run the tests.

Public String getPathString ( ) { if(getPath( ) == null) { return “ ”;}Public Void setPathString (String newPathString ) { if(newPathString == null) { setPath(null) ;}

Page 34: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Unit Testing Servlets By definition a servlet functions in a request/

response environment Although some people advocate running the

servlet and writing HTML pages to test it, this unnecessarily tests the development environment and become complex.it becomes hard to isolate the cause of the problem.

Servlets are not different from other components. Rather than running the components in web container where the request and response objects are created for us,we create the objects for ourselves and pass them into the service() method.

Page 35: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

The servlet gets the output stream from the response object and write to it,If you want to make sure that it is writing the appropriate data,so that you could override the response to provide on output stream that is stored in the response object where we can examine in out test method.

In this example we will write a servlet that takes in one parameter ,called id which corresponds to the id of a product we want to display.The servlet will output the corresponding HTML tags.Only id’s 1,2 and 3 are valid.

We will create an instance of a request and a response,these are the parameters passed to the service( ) method.

Page 36: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

package com.wrox.servlet;import java.io.*;import java.util.*;import javax.servlet.*;

public class TestRequest implements ServletRequest { HashMap paramMap = new HashMap( ); public TestRequest( ) { super( ); } public String getParameter(String key) { return (String) paramMap.get(key); } public void setParameter(String key, String value) { paramMap.put(key, value); }/* it has a lot of other methods which either returns null or “0”. */}

Page 37: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

import java.io.*;import java.util.*;import javax.servlet.*;

public class TestResponse implements ServletResponse { TestWriter writer = new TestWriter(); public TestResponse() { super(); } public PrintWriter getWriter() throws IOException { return writer; }}

Page 38: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

package com.wrox.servlet;import java.io.*;import javax.servlet.*;public class TestWriter extends PrintWriter { private String output=new String(); public TestWriter() {

/* We really want to have a default constructor for TestWriter to make it easy to construct in the test case. Unfortunately, the API dictates that PrintWriter's constructer needs an OutputStream or Writer. Fortunately, in a test case, we are not bound by the rules that govern "real" IO. In order to get our default constructor, we'll just fake out an OutputStream to satisfy the constructor.This type of sneaky behavior can be useful when you need a particular type of object to satisfy typing requirements, but you want to circumvent the API. */

Page 39: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

super(new OutputStream( ) { public void write(int b) throws IOException { } }); } public String getOutput( ) { return output; } public void println(String x) { setOutput(getOutput( ) + x); } public void setOutput(String newOutput) { output = newOutput; }}

Page 40: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Now that we have got the classes we need to test the servlet,we can write the test case .There are three basic cases to tests:

package com.wrox.servlet;import junit.framework.*;Public class DisplayProductInfoServletTest extends TestCase{Public DisplayProductInfoServletTest(String arg1){Super(arg1)}Public static void main(String args[ ]){Junit.text.ui.TetRunner.run(suite( ));}Public static Test suite( ){Return new TestSuite( DisplayProductInfoServletTest.class);}public void testInvalidId( ) Throws Exception{ }public void testNoId( ) Throws Exception{ }public void testValidId( ) Throws Exception{ }}

Page 41: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Public void testInvalidId( ) throws Exception{

//create the request object to pass inTestRequest req=new TestRequest();

//give the request a parameter called id with a value 7req.setParameter(“id”,”7” );

//create the response object to pass inTestResponce res=new TestResponce();

//create the servlet and call the service() methodDisplayProductInfoServletTest Servlet= new DisplayProductInfoServletTest( );Servlet.service(req,res);

//construct the expected output StringString expected =“<html><head><title>Invalid Product </title></head>”=“<body>The product id is invalid </body> </html>”;

assertEquals(expected,((TestWriter)res.getWriter()).getOutput()); }

Page 42: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Package com.wrox.servlet;Import javax.servlet.*;Import javax.servlet.http.*;Import java.io.*;

Public class DisplayProductInfoServletTest extends HttpServlet {

//calling the constructor of super classPublic DisplayProductInfoServletTest( ) {Super();}

Public void service(ServletRequest req, ServletResponce res); throws ServletException,IOException{ } }

Page 43: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Summary Unit testing is a powerful tool for programmers

and can make your development faster, and of higher quality.

The key is to focus on the objects itself rather than the details of the implementation.

There are no hard and fast rules that dictate unit testing must be done. Instead, there are basic guidelines that make it more effective and beneficial.

You will find challenges in testing the components in your code that will require you to use your imagination.

Page 44: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Thank you

Page 45: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

Questions

Page 46: UNIT TESTING J2EE APPLICATIONS Presented by: Sudheer Sabbineni.

References: JUnit API www.junit.org

Examples of JUnit www.xprogramming.com/software.htm


Recommended