Java tools for XP (Testing your Web App) Web Apps and Services

Download Java tools for XP (Testing your Web App) Web Apps and Services

Post on 19-Jan-2016




2 download

Embed Size (px)


  • Java tools for XP(Testing your Web App)Web Apps and Services

  • AgendaIntroductionAntJunitInside JunitHow to write Test CaseTesting WebappTesting Non Functional Req.Conclusion

  • IntroductionXP VS RUPHeavy VS AgileCommon SenseIterative & incrementalTest emphasis

  • Is Safe..? Unit DevelopIntegrationTest

  • Safe with Automatic TestUnit DevelopIntegrationTestJunitCactusHttpUnit Jmeter JunitPerf

  • Motivation of AntModern team-based, cross-platform developmentDevelopers/users have different environments: c:\jdk1.3, d:\jdk1.3, c:\jdk1.2.2 Differences between user andDevelopers may prefer different IDEs IntelliJ, JBuilder, EmacsUsers may not have any IDE at all.Frequent releases and distributions.

  • AntAnalogous to make in UnixFor Continuous integrationCross-platform Extensible Open source Defacto standard for Java projects

  • Ant and J2EEWhy needed in J2EEMany source, many targetJar, war, earDifferent Server configuration

    Good reference with J2EE EJB Design Patterns Java Tools for Extreme Programming

  • JUnitJava Unit test libraryMinimizes delay between bug creation, detection and correctionProven to increase team productivityProvides regular, concrete feedback to project managers and sponsors And development teamMakes testing quick and simpleBecause testable code is better code

  • Run()

    public abstract class TestCase implements Test { private final String fName; public TestCase(String name) { fName= name; } public abstract void run(); }

  • Template Method

    public void run() { setUp(); runTest(); tearDown(); }

    protected void runTest() { } protected void setUp() { } protected void tearDown() { }

  • TestResult

    public void run(TestResult result) { result.startTest(this); setUp(); try { runTest(); } catch (AssertionFailedError e) { //1 result.addFailure(this, e); } catch (Throwable e) { // 2 result.addError(this, e); } finally { tearDown(); } }

  • TestCase

    protected void runTest() throws Throwable { Method runMethod= null; try { runMethod= getClass().getMethod(fName, new Class[0]); } catch (NoSuchMethodException e) { assert("Method \""+fName+"\" not found", false); } try { runMethod.invoke(this, new Class[0]); } }

  • public class TestSuite implements Test { private Vector fTests= new Vector(); }public void run(TestResult result) { for (Enumeration e= fTests.elements(); e.hasMoreElements(); ) { Test test= (Test)e.nextElement();; } }

  • Complete Structure

  • How to TestStep 1: Write A Test Case Step 2: Write A Test Suite Step 3: Organize The TestsStep 4: Run The Tests

  • Write A Test Case Define a subclass of TestCase. Override the setUp() method to initialize object(s) under test. Override the tearDown() method to release object(s) under test. Define one or more public testXXX() methods that exercise the object(s) under test and assert expected results. Define a static suite() factory method that creates a TestSuite containing all the testXXX() methods of the TestCase. Optionally define a main() method that runs the TestCase in batch mode.

  • Define a subclass of TestCase.public class ShoppingCartTest extends TestCase {

    private ShoppingCart _bookCart; private Product _defaultBook;

    public ShoppingCartTest(String name) { super(name); }

  • Setup() & tearDown()protected void setUp() {

    _bookCart = new ShoppingCart(); _defaultBook = new Product("Extreme Programming", 23.95); _bookCart.addItem(_defaultBook);}

    protected void tearDown() { _bookCart = null;}

  • testXXX() public void testProductAdd() { Product newBook = new Product("Refactoring", 53.95); _bookCart.addItem(newBook); double expectedBalance = _defaultBook.getPrice() + newBook.getPrice(); assertEquals(expectedBalance, _bookCart.getBalance(), 0.0); assertEquals(2, _bookCart.getItemCount());}public void testEmpty() { _bookCart.empty(); assertTrue(_bookCart.isEmpty());}

  • Suite()public static Test suite() { // Reflection is used here to add all Test TestSuite suite = new TestSuite(ShoppingCartTest.class);

    // TestSuite suite = new TestSuite(); // suite.addTest(new ShoppingCartTest("testEmpty")); // suite.addTest(new ShoppingCartTest("testProductAdd")); // suite.addTest(new ShoppingCartTest("testProductRemove")); // suite.addTest(new ShoppingCartTest("testProductNotFound")); return suite;}

  • Main()public static void main(String args[]) {;}

  • Write A Test SuiteDefine a subclass of TestCase. Define a static suite() factory method that creates a TestSuite containing all the tests. Optionally define a main() method that runs the TestSuite in batch mode

  • Suite() public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest(ShoppingCartTest.suite()); suite.addTest(CreditCardTestSuite.suite()); return suite; }

  • organizeCreate test cases in the same package as the code under test. For each Java package in your application, define a TestSuite class that contains all the testsDefine similar TestSuite classes that create higher-level and lower-level test suites in the other packages of the application.

  • SampleAllTests (Top-level Test Suite) SmokeTestSuite (Structural Integrity Tests) EcommerceTestSuite ShoppingCartTestCase CreditCardTestSuite AuthorizationTestCase CaptureTestCase VoidTestCase UtilityTestSuite MoneyTestCase DatabaseTestSuite ConnectionTestCase TransactionTestCase LoadTestSuite (Performance and Scalability Tests) DatabaseTestSuite ConnectionPoolTestCase ThreadPoolTestCase

  • Our SituationWEB!!

  • Approchs to testing webappsRequest-ResponseExercise code by issuing HTTP requests and examining the responsesIn-containerExercise code from within the container itselfNo-containerExercise code without going through a container

  • Request-ResponseIntuitive and easy to get startedCan be hard to maintain without frequent test refactoring, verification of HTML content can be convolutedApplicable to most situations, widely used for acceptance tests

  • In Container Enables low level unit testing, provides access to container specifics e.g. session, config, beans, Best for testing complex forward / include logic, code-heavy JSPs, or verifying container implementation differences

  • No ContainerTests run quickly and in isolationHard to test JSPs, not indicative of in-container results

  • Tools and FrameworksRequest- ResponseHttpUnit (sourceforge. net): tests defined in codeJMeter (jakarta): performance and stress testingIn- containerCactus (jakarta)No- containerMockObjects (sourceforge. net)

  • CactusJunit is not sufficient with J2EEHow can I get information from Session, request,response.Extension of jUnit for J2EEServletTestCaseFilterTestCaseJspTestCase

  • Sequence

  • ArchitecturebeginXXX(WebRequest request){}testXXX(){}endXXX(WebResponse response){}setup(){}tearDown(){}

  • Sample TestbeginRequestResponse(WebRequest req) throws IOException{ req.addParameter("param1",World");}testRequestResponse() throws IOException { servlet.doGet(request, response);}endRequestResponse(WebResponse res) throws IOException{ DataInputStream dis = new DataInputStream( res.getConnection().getInputStream()); assertEquals(Hello World", dis.readLine());}

  • Simple Testpublic void testXXX(){ SampleServlet servlet = new SampleServlet();

    session.setAttribute("name", "value");

    String result = servlet.doSomething(request);

    assertEquals("something", result); assertEquals("otherValue", session.getAttribute("otherName"));}

  • HttpUnitFor Functional TestWeb Client Maintain stateSend requestRetrive responseMethods that simplify verification of response

  • Sample public void testWelcomePage() throws Exception { WebConversation conversation = new WebConversation(); WebRequest request = new GetMethodWebRequest( "http://localhost/login.htm" ); WebResponse response = conversation.getResponse( request ); WebForm forms[] = response.getForms(); assertEquals( 1, forms.length ); assertEquals( 3, forms[0].getParameterNames().length ); assertEquals( "id", forms[0].getParameterNames()[2] ); }

  • Test to Nonfunctional Req.Functional TestIs run correctly?Non Functional TestResponse TimeActive UserTransaction per Second

  • Jmeter

  • Profiling

  • JunitPerfPerfermance Testing ExtensionDecoratersTimed TestLoadTestThreadedTest

  • Timed Testpublic static Test suite() { TestSuite suite = new TestSuite(); long maxTime = 1000 + tolerance; Test testCase = new ExampleTestCase("testOneSecond"); Test timedTest = new TimedTest(testCase, maxTime); suite.addTest(timedTest); return suite;}

  • Mixed Testpublic static Test suite() { int users = 1; int iterations = 10; long maxElapsedTime = 10000 + tolerance; TestSuite suite = new TestSuite(); Test testCase = new ExampleTestCase("testOneSecond"); Test repeatedTest = new RepeatedTest(testCase, iterations); Test loadTest = new LoadTest(repeatedTest, users); Test timedTest = new TimedTest(loadTest, maxElapsedTime); suite.addTest(timedTest); return suite;}

  • General Rules for OptimizationDon't optimi