SlideShare una empresa de Scribd logo
1 de 71
Software testing
            COMP9321



Julien Ponge (julienp@cse.unsw.edu.au)

 Invited lecture: september 7th 2006




                                     Computer School of Engineering
                The University of New South Wales, Sydney, Australia
• We will see:

 • why tests are important

 • what habits you should get rid of

 • how to create tests

 • tips to make your life easier with tests
Introduction



     3
Testing... but what?

• Unit testing
• Functional testing
• Conformance testing
• Performance testing



                   4
Unit testing

• Typically classes
• Isolate as much as possible
• Self-contained and automated
• “Developers love writing tests”
• Metrics: passed tests and code coverage


                      5
What to expect?

• Less stupid bugs + test more often
• Prevent regression bugs
• Reveal bad design early
• Easier deep refactorings



                    6
The cost of tests
• Requires more          4,8


  efforts in the early
  stages                 4




                         3,2

• A code base
  without tests can      2,4




  become too difficult    1,6


  to manage as it
  grows                  0,8




                         0     0,4   0,8   1,2   1,6   2   2,4   2,8   3,2


• Test suites help
  when scaling!                7
Old-school testing



        8
Typical approach
• Write a main method (console or GUI)
• Perform a few checkings and/or output
  values (System.out.println(...))
• You may feed data manually and/or
  interactively
• Manually check if it works or not

                    9
Example 1
import my.package.NiceClass;

public class OldSchoolTesting {
    public static void main(String[] args) {
        NiceClass nc = new NiceClass();
        System.out.println(quot;Hey!quot;);
        nc.doSomething();
        System.out.println(quot;It didn't crash!!! (yet)quot;);
        System.out.println(nc.getSomeValue());
    }
}



                           10
Example 2
public class MyGreatClass {
    // (...)

    public void doSomethingGreat() {
        String str = grabItSomewhereElse();
        System.out.println(quot;=> str is quot; + str);
        if (!str.equals(ONE_CONSTANT)) {
            cry();
            goToBed();
        } else {
            enjoy();
            haveOneBeerOrTwo();
        }
    }

    // (...)
}                             11
Example 3




    12
Problems
• Not automated:
 • you check
 • you feed the data
 • you need to run it
• System.out.println + messy outputs
• Most of the time... you throw it away
  when it works!
                   13
To address this...

• We will see an automated unit testing
  framework: JUnit
• We will see how to properly output
  data when need be: Logging



                   14
JUnit



  15
JUnit
• Most famous for Java, many extensions
• Very stupid set of classes simple
• Composite pattern for test cases & test
  suites
• Primarily for unit testing, but functional
  testing can be conducted as well
• Derivatives: NUnit, PyUnit, CppUnit, ...
                    16
Running JUnit
• It reports:
  • passed & failed tests
  • errors (exceptions)
• It provides a text-mode and a Swing-
  based runners
• Most IDEs embed JUnit and display a
  progress bar (green / red)
                    17
How it works
• Base class is TestCase
• Start testing methods names with test
• Override setUp() & tearDown() if
  initialization and cleanups are needed
• Check values with assertEquals,
  assertNotSame, assertNull,
  assertNotNull, ...

                     18
Basic test case canvas
• Create a class that extends TestCase, and
  name it as MyClassTest for MyClass
• Create a test method testFoo for each
  non-trivial method foo
• Instantiate data, invoke methods
• Use JUnit assertions

                    19
Example 1
public class DifferenceOperatorTest extends TestCase {

    private DifferenceOperator operator = new DifferenceOperator(new
     BusinessProtocolFactoryImpl());

    public void testApply() throws DocumentException {
        BusinessProtocol p1 = TestUtils.loadProtocol(quot;difference/p1.wsprotocolquot;);
        BusinessProtocol p2 = TestUtils.loadProtocol(quot;difference/p2.wsprotocolquot;);
        BusinessProtocol result = operator.apply(p2, p1);
        BusinessProtocol expected = TestUtils.loadProtocol(quot;difference/p2-diff-
        p1.wsprotocolquot;);

        TestCase.assertEquals(expected, result);
    }

    public void testComputeComplement() throws DocumentException {
        BusinessProtocol p1 = TestUtils.loadProtocol(quot;difference/p1.wsprotocolquot;);
        BusinessProtocol expected = TestUtils.loadProtocol(quot;difference/compl-p1.wsprotocolquot;);
        BusinessProtocol result = operator.computeComplement(p1);

        TestCase.assertEquals(expected, result);
    }
}

                                             20
Example 2
public class OperationImplTest extends TestCase {
    public void testEqualsObject() {
        State s1 = new StateImpl(quot;s1quot;, false);
        State s2 = new StateImpl(quot;s2quot;, false);
        State s3 = new StateImpl(quot;s3quot;, false);
        State s4 = new StateImpl(quot;s4quot;, false);
        Message m1 = new MessageImpl(quot;aquot;, Polarity.POSITIVE);
        Message m2 = new MessageImpl(quot;aquot;, Polarity.NEGATIVE);

        OperationImpl o1 = new OperationImpl(quot;T1quot;, s1, s2, m1);
        OperationImpl o2 = new OperationImpl(quot;T2quot;, s3, s4, m2);

        TestCase.assertEquals(o1, o1);
        TestCase.assertNotSame(o1, o2);
    }
    public void testToString() {
        State s1 = new StateImpl(quot;s1quot;, false);
        State s2 = new StateImpl(quot;s2quot;, false);
        Message m1 = new MessageImpl(quot;aquot;, Polarity.POSITIVE);
        OperationImpl o1 = new OperationImpl(quot;T1quot;, s1, s2, m1);

        TestCase.assertEquals(quot;T1: ((s1),[a](+),(s2),explicit)quot;, o1.toString());
    }
}
                                              21
What your tests should do
  • Test both good and bad cases
  • Challenge your code: push it with
    misuses and stupid values
  • Make sure you get a good coverage:
   • use dedicated tools
   • Eclipse since version 3.2

                      22
Separate tests
      from the rest
      of the code!




23
Build integration
• Apache Ant is similar to Make, but for
  Java
• There is a Ant task
• Apache Maven is project-oriented, and
  expects JUnit tests
• Tests must pass for many Maven goals

                    24
Ant + JUnit
<target name=quot;testsquot; depends=quot;build,build.testsquot;>
<junit printsummary=quot;yesquot; fork=quot;yesquot;
       haltonfailure=quot;yesquot;>
  <formatter type=quot;plainquot;/>
  <batchtest fork=quot;yesquot; todir=quot;${reports.tests}quot;>
    <fileset dir=quot;${src.tests}quot;>
      <include name=quot;**/*Test*.javaquot;/>
      <exclude name=quot;**/AllTests.javaquot;/>
    </fileset>
  </batchtest>
</junit>
</target>

                        25
IDE integration
   keep the
  bar green!
Logging



   27
Why?
• System.out and System.err are limited
• Not all events are of the same
  importance: informations, debugging
  messages, errors, ...
• Activate some messages on-demand,
  output to console, network, dbs, files, ...
• Useful for server-side applications, but
  also standalone applications or libraries
                     28
Logging in Java
• Log4J is a popular library
• Java 1.4+ has java.util.logging
• Apache commons-logging is a popular
  choice to abstract and dynamically
  discover the logging API
• Very minor impact on performances
• Never throw messages, keep them!
                     29
Logging levels
• Fatal : critical errors
• Error : errors that can be recovered
• Warn : warnings
• Info : general informations (start,
  stop, ...)
• Debug : only-useful for debugging
• Trace : only for critical debugging
                      30
Log4J
                                           outputs
root logger

                             formatters
      logger.A


      logger.B


              logger.B.a
                                  filters


                             31
Sample Log4J config

                                                           log4.properties
# Root logger
log4j.rootLogger=INFO, consoleAppender

# A console appender
log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender
log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.consoleAppender.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n




                                         32
Example
public class OperationImpl implements Operation {

(...)

    /** Logger. */
    private static Log log = LogFactory.getLog(OperationImpl.class);

(...)

    public void setMessage(Message message) {
        Message oldMessage = this.message;
        this.message = message;
        listeners.firePropertyChange(MESSAGE_PROPERTY_CHANGE, oldMessage, message);

        if (log.isDebugEnabled()) {
            log.debug(quot;Changing the message from quot; + oldMessage + quot; to quot; + message);
        }
    }

(...)
}
                                          33
Beyond just tests



        34
Life of a tests suite

• A test suite is like good wine: it gets better
  over time!
• A good example is to reproduce bugs as
  they get identified: you will prevent
  regressions


                       35
Handling bugs


                (ah ah I’m back)   (I am a bug)
Test case



            Tests suite

                36
Tests are also...
• Useful to enforce API contracts
• An excellent API usage documentation
• A solid test suite allows deep
  refactorings: it acts as a safeguard
  against regressions
• Tests reveal bad design early: it is
  difficult to test, then you need to
  refactor!
                     37
Self-containment



       38
Self-containment

• Your test suites should be as self-
  contained as possible
• Avoid environment setup requirements
  (databases servers, application
  servers, ...)
• Eases automation in any context


                     39
Examples

data access              relational
  objects                database




   HTTP                    HTTP
   client                 server
                 40
Self-contained DB
public abstract class DAOTestBase extends TestCase {
    protected Map<String, String> queries;
    protected QueryRunner runner;

                                                                  base class
    protected Connection connection;

    public DAOTestBase() throws IOException {
        super();
        DbUtils.loadDriver(quot;org.hsqldb.jdbcDriverquot;);
        runner = new QueryRunner();
        queries = QueryLoader.instance().load(DBConstants.INIT_DB_SQL_RESOURCE);
    }
    protected void setUp() throws Exception {
        connection = DriverManager.getConnection(quot;jdbc:hsqldb:mem:CustomerDAOTestquot;, quot;saquot;, quot;quot;);
        runner.update(connection, queries.get(quot;create.customersquot;));
        runner.update(connection, queries.get(quot;create.transactionsquot;));
        runner.update(connection, queries.get(quot;data.1quot;));
        runner.update(connection, queries.get(quot;data.2quot;));
        runner.update(connection, queries.get(quot;data.3quot;));
        runner.update(connection, queries.get(quot;data.4quot;));
        runner.update(connection, queries.get(quot;data.5quot;));
    }
    protected void tearDown() throws Exception {
        runner.update(connection, queries.get(quot;drop.transactionsquot;));
        runner.update(connection, queries.get(quot;drop.customersquot;));
        DbUtils.closeQuietly(connection);
    }
                                               41
}
Self-contained DB
public class CustomerDAOTest extends DAOTestBase {
    public void testSaveAndUpdate() throws IOException, SQLException {
        CustomerDAO dao = new CustomerDAO(connection);
        Customer customer = new Customer();

                                                                      test class
        customer.setName(quot;Bernard Minetquot;);
        customer.setEmail(quot;bernard@les-muscles.comquot;);
        customer.setAddress(quot;Francequot;);
        dao.save(customer);

       Customer readCustomer = dao.loadCustomerByName(quot;Bernard Minetquot;);
       assertEquals(customer, readCustomer);

       customer.setName(quot;Framboisierquot;);
       customer.setEmail(quot;framboisier@les-muscles.comquot;);
       customer.setAddress(quot;Paris, Francequot;);
       customer.setUrl(quot;http://blog.les-muscles.com/framboisier/quot;);
       customer.creditBalance(50.0);
       dao.update(customer);

       readCustomer = dao.loadCustomerByName(quot;Bernard Minetquot;);
       assertNull(readCustomer);

       readCustomer = dao.loadCustomerByName(quot;Framboisierquot;);
       assertNotNull(readCustomer);
       assertEquals(customer, readCustomer);
   }                                          42
Self-contained HTTP
public abstract class AbstractHttpSoapTransportTest extends TestCase {
    private Server server;

                                                                 base class
    private Servlet servlet;
    private ServletHandler servletHandler;

    protected AbstractHttpSoapTransportTest(Servlet servlet) {
        this.servlet = servlet;
        server = new Server();
        SelectChannelConnector connector = new SelectChannelConnector();
        connector.setPort(8085);
        server.setConnectors(new Connector[]{connector});
        servletHandler = new ServletHandler();
        servletHandler.addServletWithMapping(new ServletHolder(servlet), quot;/dtcquot;);
        server.setHandler(servletHandler);
    }
    protected void setUp() throws Exception {
        server.start();
    }
    protected void tearDown() throws Exception {
        server.stop();
    }
}                                         43
Self-contained HTTP
public class DummyServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse
      httpServletResponse) throws ServletException, IOException {
         InputStream in = request.getInputStream();
         OutputStream out = httpServletResponse.getOutputStream();
         byte[] buffer = new byte[1024];

                                                                    servlet for
         int nbytes = 0;
         while ((nbytes = in.read(buffer, 0, 1024)) != -1) {
             out.write(buffer, 0, nbytes);
                                                                      testing
         }
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse
      httpServletResponse) throws ServletException, IOException {
         InputStream in = SoapMessageTest.class.getResourceAsStream(quot;simple-soap-
         message.xmlquot;);
         OutputStream out = httpServletResponse.getOutputStream();
         byte[] buffer = new byte[1024];
         int nbytes = 0;
         while ((nbytes = in.read(buffer, 0, 1024)) != -1) {
             out.write(buffer, 0, nbytes);
         }
    }
}                                           44
Self-contained HTTP
public class HttpSoapTransportWithDummyServletTest extends
  AbstractHttpSoapTransportTest {

    private NodeComparator nodeComparator = new NodeComparator();

    public HttpSoapTransportWithDummyServletTest() {
                                                                test class
        super(new DummyServlet());
    }

    public void testSend() throws DocumentException, IOException,
     XmlPullParserException, SoapTransportException {
        HttpSoapTransport soapTransport = new HttpSoapTransport();
        SoapMessage message = SoapMessageUtils.readSoapMessageFromStream
       (SoapMessageTest.class
                .getResourceAsStream(quot;simple-soap-message.xmlquot;));
        SoapMessage response = soapTransport.send(quot;http://localhost:8085/dtcquot;,
       message, null);
        assertEquals(0, nodeComparator.compare(message, response));
    }
}

                                         45
HttpUnit: testing webapps



            46
HttpUnit
• Functional testing
• Works like a web browser / HTTP
  client (cookies, form submissions, ...)
• Embeds a JavaScript engine (Rhino)
• JUnit integration
• Provides ServletUnit to unit-test servlets
  in isolation of servlet containers
                      47
Main classes
• WebConversation: stateful client session
• WebRequest: a single GET or POST
  HTTP request
• WebResponse: HTTP response
• WebForm, WebLink, (...): many helper
  classes to access the pages content

                    48
Example
public void testGoodLogin() throws Exception {
        WebConversation conversation = new WebConversation();
        WebRequest request = new GetMethodWebRequest(

     

   
   quot;http://www.meterware.com/servlet/TopSecretquot;);

        WebResponse response = conversation.getResponse(request);
        WebForm loginForm = response.getForms()[0];
        request = loginForm.getRequest();
        request.setParameter( quot;namequot;, quot;masterquot; );
        response = conversation.getResponse( request );
        assertTrue( quot;Login not acceptedquot;,

              response.getText().indexOf( quot;You made it!quot; ) != -1 );

        assertEquals( quot;Page titlequot;, quot;Top Secretquot;, response.getTitle() );
    }



                                      49            http://fb2.hu/x10/Articles/HttpUnit.html
(from the cookbook)
WebConversation wc   = new WebConversation();
WebResponse   resp   = wc.getResponse( quot;http://www.httpunit.org/doc/cookbook.htmlquot; );
WebLink       link   = resp.getLinkWith( quot;responsequot; );
link.click();
WebResponse   jdoc   = wc.getCurrentPage();


WebTable table = resp.getTables()[0];
assertEquals( quot;rowsquot;, 4, table.getRowCount() );
assertEquals( quot;columnsquot;, 3, table.getColumnCount() );
assertEquals( quot;linksquot;, 1, table.getTableCell( 0, 2 ).getLinks().length );



WebForm form = resp.getForms()[0];
assertEquals( quot;La Cerentollaquot;, form.getParameterValue(   quot;Namequot; ) );
assertEquals( quot;Chinesequot;,       form.getParameterValue(   quot;Foodquot; ) );
assertEquals( quot;Manayunkquot;,      form.getParameterValue(   quot;Locationquot; ) );
assertEquals( quot;onquot;,            form.getParameterValue(   quot;CreditCardquot; ) );
form.setParameter( quot;Foodquot;, quot;Italianquot; );
form.removeParameter( quot;CreditCardquot; );
form.submit();
                                           50
ServletUnit example
ServletRunner sr = new ServletRunner();
sr.registerServlet( quot;myServletquot;, StatefulServlet.class.getName() );

ServletUnitClient sc = sr.newClient();
WebRequest request   = new PostMethodWebRequest(quot;http://test.meterware.com/myServletquot;);
request.setParameter( quot;colorquot;, quot;redquot; );
WebResponse response = sc.getResponse( request );
assertNotNull( quot;No response receivedquot;, response );
assertEquals( quot;content typequot;, quot;text/plainquot;, response.getContentType() );
assertEquals( quot;requested resourcequot;, quot;You selected redquot;, response.getText() );


                          public class StatefulServlet extends HttpServlet {
                              protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                                              throws ServletException,IOException {
                                  resp.setContentType( quot;text/plainquot; );
                                  writeSelectMessage( req.getParameter( quot;colorquot; ), resp.getWriter() );
                                  setColor( req, req.getParameter( quot;colorquot; ) );
                              }
                              protected void writeSelectMessage(String color, PrintWriter pw)
                                   throws IOException {
                                  pw.print( quot;You selected quot; + color );
                                  pw.close();
                              }
                              void setColor( HttpServletRequest req, String color )
                                   throws ServletException {
                                  req.getSession().setAttribute( quot;colorquot;, color );
                              }
                                                      51
                          }
Tests-friendly patterns



           52
Problem: dependencies

  AdressBook          PersonDAO

                    + loadPerson(...)
                    + savePerson(...)




               53
Hard-dependencies

• Isolating the class to test is difficult
  and/or impossible
• Failures may be induced by a
  dependency
• More generally, it reveals potential code
  evolution problems: strong coupling


                      54
Depending on interfaces
                            <<interface>>
 AdressBook                      IPersonDAO

                            + loadPerson(...)
                            + savePerson(...)




              DBPersonDAO    FilePersonDAO      MockPersonDAO




                            55
Interfaces dependencies

 • Interfaces introduce loose coupling
 • At execution time: use the real class
 • At test time: use a mock class
 • Future evolution is easier
 • BTW, don’t over-use interfaces!


                     56
Mock objects
• Give a simple behavior: fixed values,
  random values, values passed by
  methods of the mock class, ...
• They allow you to test even if the real
  class hasn’t been created yet
• EasyMock, JMockIt allow to generate
  mocks on-the-fly

                    57
Object.equals()
public boolean equals(Object obj)
{
    if (obj instanceof ComparisonNode)
    {
        ComparisonNode other = (ComparisonNode) obj;
        return symbol.equals(other.symbol)
               && leftChild.equals(other.leftChild)
               && rightChild.equals(other.rightChild);
    }
    return false;
                                important for
}

                          TestCase.assertXXX(...)
                            58
Dependency injection
• 2 types of injection: setter-based &
  constructor-based
• Constructor injection is preferable, and
  make your objects ready right after
  their instanciation
• Clarifies classes dependencies
• Principle used in inversion of control
  frameworks: PicoContainer, Spring, ...
                     59
Example
private IConstraintNode leftChild;
private IConstraintNode rightChild;
private String symbol;

public ComparisonNode(String symbol, VariableNode var, ConstantNode cst)
{
        this(var, cst, symbol);
}

public ComparisonNode(String symbol, ConstantNode cst, VariableNode var)
{
        this(cst, var, symbol);
}

protected ComparisonNode(IConstraintNode leftChild, IConstraintNode rightChild,
                         String symbol)
{
        super();
        this.symbol = symbol;
        this.leftChild = leftChild;
        this.rightChild = rightChild;
}
                                        60
A few tips



    61
Do
• Try to really write your tests first
• Test as soon as you create a new class
• Test often
• Start with sensible simple scenarios
• Load data from resources
  (Class.getResourceAsStream(“/path/to”))
• Check for code coverage
                     62
Don’t
• Write overly exhaustive test cases
• Write tests for trivial methods (getters,
  setters, ...) even if it lowers coverage
• Catch exceptions, unless you actually
  test that
• Fix bugs without first reproducing them
  in a test case

                     63
Traversing object graphs

 • Sometimes you will need to walk
   through deep object graphs to test
   values
 • This is really boring
 • JXPath uses XPath on objects, and
   replaces iterations/loops by requests


                     64
JXPath example
Iterator it;
String str;
JXPathContext ctx = JXPathContext.newContext(bp2);

TestCase.assertEquals(quot;s0quot;, bp2.getInitialState().getName());
it = ctx.iterate(quot;finalStates/namequot;);
TestCase.assertTrue(it.hasNext());
TestCase.assertEquals(quot;s1quot;, (String) it.next());
TestCase.assertFalse(it.hasNext());

it = ctx.iterate(quot;states[name='s0']/successors/namequot;);
TestCase.assertTrue(it.hasNext());
TestCase.assertEquals(quot;s1quot;, (String) it.next());
TestCase.assertEquals(quot;s0quot;, (String) it.next());
TestCase.assertFalse(it.hasNext());

(...)

Operation toRemove = (Operation) ctx.getValue(quot;operations[message/name='a']quot;);
bp2.removeOperation(toRemove);

List remainingOps = (List) ctx.getValue(quot;states[name='s0']/incomingOperationsquot;);
TestCase.assertTrue(remainingOps.size() == 1);


                                            65
The case of ‘old’ software
  • Test cases can be added to existing
    applications
  • In many situations the design can make
    it difficult to test / isolate...
  • You cannot break existing APIs
  • Don’t expect to introduce tests cases for
    100% of the code base...
  • It will still allow you to spot new bugs!
                      66
Continuous integration



          67
Problem
• Developers work on different portions
  of the code base
• Traditional integration may not be
  frequent enough (~ weekly)
• It can be difficult to find who, when and
  how the build was broken
• Continuous integration aims at
  detecting problems in nearly real-time
                    68
C.I. environment
                           4          email
    developers




                           instant messaging



1                                              continuous integration
         changeset
                                                  (Continuum, ...)


                                                                    3
                                                     execute
                     notification via hooks


                                    2
 source code                                        tests suite
  repository
                                    69
(SVN, CVS, ...)
• Demo:

 • project using Maven2

 • Apache Continuum configuration

 • launch the tests from Continuum



                 70
Thanks!



   71

Más contenido relacionado

La actualidad más candente

Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsAzul Systems, Inc.
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good TestsTomek Kaczanowski
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good TestsTomek Kaczanowski
 
Riga Dev Day 2016 - Having fun with Javassist
Riga Dev Day 2016 - Having fun with JavassistRiga Dev Day 2016 - Having fun with Javassist
Riga Dev Day 2016 - Having fun with JavassistAnton Arhipov
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleGeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleAnton Arhipov
 
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)Danny Preussler
 
Jersey framework
Jersey frameworkJersey framework
Jersey frameworkknight1128
 
Spock: A Highly Logical Way To Test
Spock: A Highly Logical Way To TestSpock: A Highly Logical Way To Test
Spock: A Highly Logical Way To TestHoward Lewis Ship
 
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, howTomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, howTomasz Polanski
 
Kotlin 101 for Java Developers
Kotlin 101 for Java DevelopersKotlin 101 for Java Developers
Kotlin 101 for Java DevelopersChristoph Pickl
 
Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011Anton Arhipov
 
Smarter Testing with Spock
Smarter Testing with SpockSmarter Testing with Spock
Smarter Testing with SpockDmitry Voloshko
 
Advanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesAdvanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesGanesh Samarthyam
 
JavaOne 2015 - Having fun with Javassist
JavaOne 2015 - Having fun with JavassistJavaOne 2015 - Having fun with Javassist
JavaOne 2015 - Having fun with JavassistAnton Arhipov
 
Demystifying dependency Injection: Dagger and Toothpick
Demystifying dependency Injection: Dagger and ToothpickDemystifying dependency Injection: Dagger and Toothpick
Demystifying dependency Injection: Dagger and ToothpickDanny Preussler
 
JEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with JavassistJEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with JavassistAnton Arhipov
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleThierry Wasylczenko
 

La actualidad más candente (20)

Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM Mechanics
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
 
Riga Dev Day 2016 - Having fun with Javassist
Riga Dev Day 2016 - Having fun with JavassistRiga Dev Day 2016 - Having fun with Javassist
Riga Dev Day 2016 - Having fun with Javassist
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleGeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassle
 
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
 
Jersey framework
Jersey frameworkJersey framework
Jersey framework
 
Spock: A Highly Logical Way To Test
Spock: A Highly Logical Way To TestSpock: A Highly Logical Way To Test
Spock: A Highly Logical Way To Test
 
Migrating to JUnit 5
Migrating to JUnit 5Migrating to JUnit 5
Migrating to JUnit 5
 
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, howTomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
 
Kotlin meets Gadsu
Kotlin meets GadsuKotlin meets Gadsu
Kotlin meets Gadsu
 
Kotlin 101 for Java Developers
Kotlin 101 for Java DevelopersKotlin 101 for Java Developers
Kotlin 101 for Java Developers
 
Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011
 
Smarter Testing with Spock
Smarter Testing with SpockSmarter Testing with Spock
Smarter Testing with Spock
 
Advanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesAdvanced Debugging Using Java Bytecodes
Advanced Debugging Using Java Bytecodes
 
devday2012
devday2012devday2012
devday2012
 
JavaOne 2015 - Having fun with Javassist
JavaOne 2015 - Having fun with JavassistJavaOne 2015 - Having fun with Javassist
JavaOne 2015 - Having fun with Javassist
 
Demystifying dependency Injection: Dagger and Toothpick
Demystifying dependency Injection: Dagger and ToothpickDemystifying dependency Injection: Dagger and Toothpick
Demystifying dependency Injection: Dagger and Toothpick
 
JEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with JavassistJEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with Javassist
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
 

Destacado

IzPack - PoitouJUG
IzPack - PoitouJUGIzPack - PoitouJUG
IzPack - PoitouJUGjulien.ponge
 
Slides Aquarium Paris 2008
Slides Aquarium Paris 2008Slides Aquarium Paris 2008
Slides Aquarium Paris 2008julien.ponge
 
IzPack Glassfish Lightning Talks 2008
IzPack Glassfish Lightning Talks 2008IzPack Glassfish Lightning Talks 2008
IzPack Glassfish Lightning Talks 2008julien.ponge
 
IzPack - fOSSa 2009
IzPack - fOSSa 2009IzPack - fOSSa 2009
IzPack - fOSSa 2009julien.ponge
 
IzPack at LyonJUG'11
IzPack at LyonJUG'11IzPack at LyonJUG'11
IzPack at LyonJUG'11julien.ponge
 

Destacado (6)

IzPack - PoitouJUG
IzPack - PoitouJUGIzPack - PoitouJUG
IzPack - PoitouJUG
 
Slides Aquarium Paris 2008
Slides Aquarium Paris 2008Slides Aquarium Paris 2008
Slides Aquarium Paris 2008
 
IzPack Glassfish Lightning Talks 2008
IzPack Glassfish Lightning Talks 2008IzPack Glassfish Lightning Talks 2008
IzPack Glassfish Lightning Talks 2008
 
IzPack - fOSSa 2009
IzPack - fOSSa 2009IzPack - fOSSa 2009
IzPack - fOSSa 2009
 
IzPack at LyonJUG'11
IzPack at LyonJUG'11IzPack at LyonJUG'11
IzPack at LyonJUG'11
 
FOSS - PoitouJUG
FOSS - PoitouJUGFOSS - PoitouJUG
FOSS - PoitouJUG
 

Similar a Software Testing - Invited Lecture at UNSW Sydney

Developer Tests - Things to Know (Vilnius JUG)
Developer Tests - Things to Know (Vilnius JUG)Developer Tests - Things to Know (Vilnius JUG)
Developer Tests - Things to Know (Vilnius JUG)vilniusjug
 
What's up with Prototype and script.aculo.us?
What's up with Prototype and script.aculo.us?What's up with Prototype and script.aculo.us?
What's up with Prototype and script.aculo.us?Christophe Porteneuve
 
Unit Testing with JUnit4 by Ravikiran Janardhana
Unit Testing with JUnit4 by Ravikiran JanardhanaUnit Testing with JUnit4 by Ravikiran Janardhana
Unit Testing with JUnit4 by Ravikiran JanardhanaRavikiran J
 
A exception ekon16
A exception ekon16A exception ekon16
A exception ekon16Max Kleiner
 
Никита Галкин "Testing in Frontend World"
Никита Галкин "Testing in Frontend World"Никита Галкин "Testing in Frontend World"
Никита Галкин "Testing in Frontend World"Fwdays
 
Error handling in XPages
Error handling in XPagesError handling in XPages
Error handling in XPagesdominion
 
Building unit tests correctly with visual studio 2013
Building unit tests correctly with visual studio 2013Building unit tests correctly with visual studio 2013
Building unit tests correctly with visual studio 2013Dror Helper
 
Code igniter unittest-part1
Code igniter unittest-part1Code igniter unittest-part1
Code igniter unittest-part1Albert Rosa
 
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMockUnit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMockRobot Media
 
GeeCON 2012 Bad Tests, Good Tests
GeeCON 2012 Bad Tests, Good TestsGeeCON 2012 Bad Tests, Good Tests
GeeCON 2012 Bad Tests, Good TestsTomek Kaczanowski
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitMichelangelo van Dam
 
Core Java Programming Language (JSE) : Chapter VIII - Exceptions and Assertions
Core Java Programming Language (JSE) : Chapter VIII - Exceptions and AssertionsCore Java Programming Language (JSE) : Chapter VIII - Exceptions and Assertions
Core Java Programming Language (JSE) : Chapter VIII - Exceptions and AssertionsWebStackAcademy
 
Containerize your Blackbox tests
Containerize your Blackbox testsContainerize your Blackbox tests
Containerize your Blackbox testsKevin Beeman
 

Similar a Software Testing - Invited Lecture at UNSW Sydney (20)

J Unit
J UnitJ Unit
J Unit
 
Developer Tests - Things to Know (Vilnius JUG)
Developer Tests - Things to Know (Vilnius JUG)Developer Tests - Things to Know (Vilnius JUG)
Developer Tests - Things to Know (Vilnius JUG)
 
What's up with Prototype and script.aculo.us?
What's up with Prototype and script.aculo.us?What's up with Prototype and script.aculo.us?
What's up with Prototype and script.aculo.us?
 
Unit Testing with JUnit4 by Ravikiran Janardhana
Unit Testing with JUnit4 by Ravikiran JanardhanaUnit Testing with JUnit4 by Ravikiran Janardhana
Unit Testing with JUnit4 by Ravikiran Janardhana
 
00_Introduction to Java.ppt
00_Introduction to Java.ppt00_Introduction to Java.ppt
00_Introduction to Java.ppt
 
A exception ekon16
A exception ekon16A exception ekon16
A exception ekon16
 
Никита Галкин "Testing in Frontend World"
Никита Галкин "Testing in Frontend World"Никита Галкин "Testing in Frontend World"
Никита Галкин "Testing in Frontend World"
 
Error handling in XPages
Error handling in XPagesError handling in XPages
Error handling in XPages
 
Building unit tests correctly with visual studio 2013
Building unit tests correctly with visual studio 2013Building unit tests correctly with visual studio 2013
Building unit tests correctly with visual studio 2013
 
Testing
TestingTesting
Testing
 
Code igniter unittest-part1
Code igniter unittest-part1Code igniter unittest-part1
Code igniter unittest-part1
 
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMockUnit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
 
GeeCON 2012 Bad Tests, Good Tests
GeeCON 2012 Bad Tests, Good TestsGeeCON 2012 Bad Tests, Good Tests
GeeCON 2012 Bad Tests, Good Tests
 
Golang dot-testing-lite
Golang dot-testing-liteGolang dot-testing-lite
Golang dot-testing-lite
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
 
PHPUnit testing to Zend_Test
PHPUnit testing to Zend_TestPHPUnit testing to Zend_Test
PHPUnit testing to Zend_Test
 
Core Java Programming Language (JSE) : Chapter VIII - Exceptions and Assertions
Core Java Programming Language (JSE) : Chapter VIII - Exceptions and AssertionsCore Java Programming Language (JSE) : Chapter VIII - Exceptions and Assertions
Core Java Programming Language (JSE) : Chapter VIII - Exceptions and Assertions
 
Unit testing
Unit testingUnit testing
Unit testing
 
Containerize your Blackbox tests
Containerize your Blackbox testsContainerize your Blackbox tests
Containerize your Blackbox tests
 
Test driven development
Test driven developmentTest driven development
Test driven development
 

Último

Prescribed medication order and communication skills.pptx
Prescribed medication order and communication skills.pptxPrescribed medication order and communication skills.pptx
Prescribed medication order and communication skills.pptxraviapr7
 
HED Office Sohayok Exam Question Solution 2023.pdf
HED Office Sohayok Exam Question Solution 2023.pdfHED Office Sohayok Exam Question Solution 2023.pdf
HED Office Sohayok Exam Question Solution 2023.pdfMohonDas
 
Easter in the USA presentation by Chloe.
Easter in the USA presentation by Chloe.Easter in the USA presentation by Chloe.
Easter in the USA presentation by Chloe.EnglishCEIPdeSigeiro
 
Clinical Pharmacy Introduction to Clinical Pharmacy, Concept of clinical pptx
Clinical Pharmacy  Introduction to Clinical Pharmacy, Concept of clinical pptxClinical Pharmacy  Introduction to Clinical Pharmacy, Concept of clinical pptx
Clinical Pharmacy Introduction to Clinical Pharmacy, Concept of clinical pptxraviapr7
 
Quality Assurance_GOOD LABORATORY PRACTICE
Quality Assurance_GOOD LABORATORY PRACTICEQuality Assurance_GOOD LABORATORY PRACTICE
Quality Assurance_GOOD LABORATORY PRACTICESayali Powar
 
Philosophy of Education and Educational Philosophy
Philosophy of Education  and Educational PhilosophyPhilosophy of Education  and Educational Philosophy
Philosophy of Education and Educational PhilosophyShuvankar Madhu
 
Drug Information Services- DIC and Sources.
Drug Information Services- DIC and Sources.Drug Information Services- DIC and Sources.
Drug Information Services- DIC and Sources.raviapr7
 
In - Vivo and In - Vitro Correlation.pptx
In - Vivo and In - Vitro Correlation.pptxIn - Vivo and In - Vitro Correlation.pptx
In - Vivo and In - Vitro Correlation.pptxAditiChauhan701637
 
PISA-VET launch_El Iza Mohamedou_19 March 2024.pptx
PISA-VET launch_El Iza Mohamedou_19 March 2024.pptxPISA-VET launch_El Iza Mohamedou_19 March 2024.pptx
PISA-VET launch_El Iza Mohamedou_19 March 2024.pptxEduSkills OECD
 
Diploma in Nursing Admission Test Question Solution 2023.pdf
Diploma in Nursing Admission Test Question Solution 2023.pdfDiploma in Nursing Admission Test Question Solution 2023.pdf
Diploma in Nursing Admission Test Question Solution 2023.pdfMohonDas
 
The basics of sentences session 10pptx.pptx
The basics of sentences session 10pptx.pptxThe basics of sentences session 10pptx.pptx
The basics of sentences session 10pptx.pptxheathfieldcps1
 
CHUYÊN ĐỀ DẠY THÊM TIẾNG ANH LỚP 11 - GLOBAL SUCCESS - NĂM HỌC 2023-2024 - HK...
CHUYÊN ĐỀ DẠY THÊM TIẾNG ANH LỚP 11 - GLOBAL SUCCESS - NĂM HỌC 2023-2024 - HK...CHUYÊN ĐỀ DẠY THÊM TIẾNG ANH LỚP 11 - GLOBAL SUCCESS - NĂM HỌC 2023-2024 - HK...
CHUYÊN ĐỀ DẠY THÊM TIẾNG ANH LỚP 11 - GLOBAL SUCCESS - NĂM HỌC 2023-2024 - HK...Nguyen Thanh Tu Collection
 
How to Solve Singleton Error in the Odoo 17
How to Solve Singleton Error in the  Odoo 17How to Solve Singleton Error in the  Odoo 17
How to Solve Singleton Error in the Odoo 17Celine George
 
Practical Research 1: Lesson 8 Writing the Thesis Statement.pptx
Practical Research 1: Lesson 8 Writing the Thesis Statement.pptxPractical Research 1: Lesson 8 Writing the Thesis Statement.pptx
Practical Research 1: Lesson 8 Writing the Thesis Statement.pptxKatherine Villaluna
 
AUDIENCE THEORY -- FANDOM -- JENKINS.pptx
AUDIENCE THEORY -- FANDOM -- JENKINS.pptxAUDIENCE THEORY -- FANDOM -- JENKINS.pptx
AUDIENCE THEORY -- FANDOM -- JENKINS.pptxiammrhaywood
 
CAULIFLOWER BREEDING 1 Parmar pptx
CAULIFLOWER BREEDING 1 Parmar pptxCAULIFLOWER BREEDING 1 Parmar pptx
CAULIFLOWER BREEDING 1 Parmar pptxSaurabhParmar42
 
Ultra structure and life cycle of Plasmodium.pptx
Ultra structure and life cycle of Plasmodium.pptxUltra structure and life cycle of Plasmodium.pptx
Ultra structure and life cycle of Plasmodium.pptxDr. Asif Anas
 
How to Add Existing Field in One2Many Tree View in Odoo 17
How to Add Existing Field in One2Many Tree View in Odoo 17How to Add Existing Field in One2Many Tree View in Odoo 17
How to Add Existing Field in One2Many Tree View in Odoo 17Celine George
 
Patient Counselling. Definition of patient counseling; steps involved in pati...
Patient Counselling. Definition of patient counseling; steps involved in pati...Patient Counselling. Definition of patient counseling; steps involved in pati...
Patient Counselling. Definition of patient counseling; steps involved in pati...raviapr7
 
General views of Histopathology and step
General views of Histopathology and stepGeneral views of Histopathology and step
General views of Histopathology and stepobaje godwin sunday
 

Último (20)

Prescribed medication order and communication skills.pptx
Prescribed medication order and communication skills.pptxPrescribed medication order and communication skills.pptx
Prescribed medication order and communication skills.pptx
 
HED Office Sohayok Exam Question Solution 2023.pdf
HED Office Sohayok Exam Question Solution 2023.pdfHED Office Sohayok Exam Question Solution 2023.pdf
HED Office Sohayok Exam Question Solution 2023.pdf
 
Easter in the USA presentation by Chloe.
Easter in the USA presentation by Chloe.Easter in the USA presentation by Chloe.
Easter in the USA presentation by Chloe.
 
Clinical Pharmacy Introduction to Clinical Pharmacy, Concept of clinical pptx
Clinical Pharmacy  Introduction to Clinical Pharmacy, Concept of clinical pptxClinical Pharmacy  Introduction to Clinical Pharmacy, Concept of clinical pptx
Clinical Pharmacy Introduction to Clinical Pharmacy, Concept of clinical pptx
 
Quality Assurance_GOOD LABORATORY PRACTICE
Quality Assurance_GOOD LABORATORY PRACTICEQuality Assurance_GOOD LABORATORY PRACTICE
Quality Assurance_GOOD LABORATORY PRACTICE
 
Philosophy of Education and Educational Philosophy
Philosophy of Education  and Educational PhilosophyPhilosophy of Education  and Educational Philosophy
Philosophy of Education and Educational Philosophy
 
Drug Information Services- DIC and Sources.
Drug Information Services- DIC and Sources.Drug Information Services- DIC and Sources.
Drug Information Services- DIC and Sources.
 
In - Vivo and In - Vitro Correlation.pptx
In - Vivo and In - Vitro Correlation.pptxIn - Vivo and In - Vitro Correlation.pptx
In - Vivo and In - Vitro Correlation.pptx
 
PISA-VET launch_El Iza Mohamedou_19 March 2024.pptx
PISA-VET launch_El Iza Mohamedou_19 March 2024.pptxPISA-VET launch_El Iza Mohamedou_19 March 2024.pptx
PISA-VET launch_El Iza Mohamedou_19 March 2024.pptx
 
Diploma in Nursing Admission Test Question Solution 2023.pdf
Diploma in Nursing Admission Test Question Solution 2023.pdfDiploma in Nursing Admission Test Question Solution 2023.pdf
Diploma in Nursing Admission Test Question Solution 2023.pdf
 
The basics of sentences session 10pptx.pptx
The basics of sentences session 10pptx.pptxThe basics of sentences session 10pptx.pptx
The basics of sentences session 10pptx.pptx
 
CHUYÊN ĐỀ DẠY THÊM TIẾNG ANH LỚP 11 - GLOBAL SUCCESS - NĂM HỌC 2023-2024 - HK...
CHUYÊN ĐỀ DẠY THÊM TIẾNG ANH LỚP 11 - GLOBAL SUCCESS - NĂM HỌC 2023-2024 - HK...CHUYÊN ĐỀ DẠY THÊM TIẾNG ANH LỚP 11 - GLOBAL SUCCESS - NĂM HỌC 2023-2024 - HK...
CHUYÊN ĐỀ DẠY THÊM TIẾNG ANH LỚP 11 - GLOBAL SUCCESS - NĂM HỌC 2023-2024 - HK...
 
How to Solve Singleton Error in the Odoo 17
How to Solve Singleton Error in the  Odoo 17How to Solve Singleton Error in the  Odoo 17
How to Solve Singleton Error in the Odoo 17
 
Practical Research 1: Lesson 8 Writing the Thesis Statement.pptx
Practical Research 1: Lesson 8 Writing the Thesis Statement.pptxPractical Research 1: Lesson 8 Writing the Thesis Statement.pptx
Practical Research 1: Lesson 8 Writing the Thesis Statement.pptx
 
AUDIENCE THEORY -- FANDOM -- JENKINS.pptx
AUDIENCE THEORY -- FANDOM -- JENKINS.pptxAUDIENCE THEORY -- FANDOM -- JENKINS.pptx
AUDIENCE THEORY -- FANDOM -- JENKINS.pptx
 
CAULIFLOWER BREEDING 1 Parmar pptx
CAULIFLOWER BREEDING 1 Parmar pptxCAULIFLOWER BREEDING 1 Parmar pptx
CAULIFLOWER BREEDING 1 Parmar pptx
 
Ultra structure and life cycle of Plasmodium.pptx
Ultra structure and life cycle of Plasmodium.pptxUltra structure and life cycle of Plasmodium.pptx
Ultra structure and life cycle of Plasmodium.pptx
 
How to Add Existing Field in One2Many Tree View in Odoo 17
How to Add Existing Field in One2Many Tree View in Odoo 17How to Add Existing Field in One2Many Tree View in Odoo 17
How to Add Existing Field in One2Many Tree View in Odoo 17
 
Patient Counselling. Definition of patient counseling; steps involved in pati...
Patient Counselling. Definition of patient counseling; steps involved in pati...Patient Counselling. Definition of patient counseling; steps involved in pati...
Patient Counselling. Definition of patient counseling; steps involved in pati...
 
General views of Histopathology and step
General views of Histopathology and stepGeneral views of Histopathology and step
General views of Histopathology and step
 

Software Testing - Invited Lecture at UNSW Sydney

  • 1. Software testing COMP9321 Julien Ponge (julienp@cse.unsw.edu.au) Invited lecture: september 7th 2006 Computer School of Engineering The University of New South Wales, Sydney, Australia
  • 2. • We will see: • why tests are important • what habits you should get rid of • how to create tests • tips to make your life easier with tests
  • 4. Testing... but what? • Unit testing • Functional testing • Conformance testing • Performance testing 4
  • 5. Unit testing • Typically classes • Isolate as much as possible • Self-contained and automated • “Developers love writing tests” • Metrics: passed tests and code coverage 5
  • 6. What to expect? • Less stupid bugs + test more often • Prevent regression bugs • Reveal bad design early • Easier deep refactorings 6
  • 7. The cost of tests • Requires more 4,8 efforts in the early stages 4 3,2 • A code base without tests can 2,4 become too difficult 1,6 to manage as it grows 0,8 0 0,4 0,8 1,2 1,6 2 2,4 2,8 3,2 • Test suites help when scaling! 7
  • 9. Typical approach • Write a main method (console or GUI) • Perform a few checkings and/or output values (System.out.println(...)) • You may feed data manually and/or interactively • Manually check if it works or not 9
  • 10. Example 1 import my.package.NiceClass; public class OldSchoolTesting { public static void main(String[] args) { NiceClass nc = new NiceClass(); System.out.println(quot;Hey!quot;); nc.doSomething(); System.out.println(quot;It didn't crash!!! (yet)quot;); System.out.println(nc.getSomeValue()); } } 10
  • 11. Example 2 public class MyGreatClass { // (...) public void doSomethingGreat() { String str = grabItSomewhereElse(); System.out.println(quot;=> str is quot; + str); if (!str.equals(ONE_CONSTANT)) { cry(); goToBed(); } else { enjoy(); haveOneBeerOrTwo(); } } // (...) } 11
  • 12. Example 3 12
  • 13. Problems • Not automated: • you check • you feed the data • you need to run it • System.out.println + messy outputs • Most of the time... you throw it away when it works! 13
  • 14. To address this... • We will see an automated unit testing framework: JUnit • We will see how to properly output data when need be: Logging 14
  • 16. JUnit • Most famous for Java, many extensions • Very stupid set of classes simple • Composite pattern for test cases & test suites • Primarily for unit testing, but functional testing can be conducted as well • Derivatives: NUnit, PyUnit, CppUnit, ... 16
  • 17. Running JUnit • It reports: • passed & failed tests • errors (exceptions) • It provides a text-mode and a Swing- based runners • Most IDEs embed JUnit and display a progress bar (green / red) 17
  • 18. How it works • Base class is TestCase • Start testing methods names with test • Override setUp() & tearDown() if initialization and cleanups are needed • Check values with assertEquals, assertNotSame, assertNull, assertNotNull, ... 18
  • 19. Basic test case canvas • Create a class that extends TestCase, and name it as MyClassTest for MyClass • Create a test method testFoo for each non-trivial method foo • Instantiate data, invoke methods • Use JUnit assertions 19
  • 20. Example 1 public class DifferenceOperatorTest extends TestCase { private DifferenceOperator operator = new DifferenceOperator(new BusinessProtocolFactoryImpl()); public void testApply() throws DocumentException { BusinessProtocol p1 = TestUtils.loadProtocol(quot;difference/p1.wsprotocolquot;); BusinessProtocol p2 = TestUtils.loadProtocol(quot;difference/p2.wsprotocolquot;); BusinessProtocol result = operator.apply(p2, p1); BusinessProtocol expected = TestUtils.loadProtocol(quot;difference/p2-diff- p1.wsprotocolquot;); TestCase.assertEquals(expected, result); } public void testComputeComplement() throws DocumentException { BusinessProtocol p1 = TestUtils.loadProtocol(quot;difference/p1.wsprotocolquot;); BusinessProtocol expected = TestUtils.loadProtocol(quot;difference/compl-p1.wsprotocolquot;); BusinessProtocol result = operator.computeComplement(p1); TestCase.assertEquals(expected, result); } } 20
  • 21. Example 2 public class OperationImplTest extends TestCase { public void testEqualsObject() { State s1 = new StateImpl(quot;s1quot;, false); State s2 = new StateImpl(quot;s2quot;, false); State s3 = new StateImpl(quot;s3quot;, false); State s4 = new StateImpl(quot;s4quot;, false); Message m1 = new MessageImpl(quot;aquot;, Polarity.POSITIVE); Message m2 = new MessageImpl(quot;aquot;, Polarity.NEGATIVE); OperationImpl o1 = new OperationImpl(quot;T1quot;, s1, s2, m1); OperationImpl o2 = new OperationImpl(quot;T2quot;, s3, s4, m2); TestCase.assertEquals(o1, o1); TestCase.assertNotSame(o1, o2); } public void testToString() { State s1 = new StateImpl(quot;s1quot;, false); State s2 = new StateImpl(quot;s2quot;, false); Message m1 = new MessageImpl(quot;aquot;, Polarity.POSITIVE); OperationImpl o1 = new OperationImpl(quot;T1quot;, s1, s2, m1); TestCase.assertEquals(quot;T1: ((s1),[a](+),(s2),explicit)quot;, o1.toString()); } } 21
  • 22. What your tests should do • Test both good and bad cases • Challenge your code: push it with misuses and stupid values • Make sure you get a good coverage: • use dedicated tools • Eclipse since version 3.2 22
  • 23. Separate tests from the rest of the code! 23
  • 24. Build integration • Apache Ant is similar to Make, but for Java • There is a Ant task • Apache Maven is project-oriented, and expects JUnit tests • Tests must pass for many Maven goals 24
  • 25. Ant + JUnit <target name=quot;testsquot; depends=quot;build,build.testsquot;> <junit printsummary=quot;yesquot; fork=quot;yesquot; haltonfailure=quot;yesquot;> <formatter type=quot;plainquot;/> <batchtest fork=quot;yesquot; todir=quot;${reports.tests}quot;> <fileset dir=quot;${src.tests}quot;> <include name=quot;**/*Test*.javaquot;/> <exclude name=quot;**/AllTests.javaquot;/> </fileset> </batchtest> </junit> </target> 25
  • 26. IDE integration keep the bar green!
  • 27. Logging 27
  • 28. Why? • System.out and System.err are limited • Not all events are of the same importance: informations, debugging messages, errors, ... • Activate some messages on-demand, output to console, network, dbs, files, ... • Useful for server-side applications, but also standalone applications or libraries 28
  • 29. Logging in Java • Log4J is a popular library • Java 1.4+ has java.util.logging • Apache commons-logging is a popular choice to abstract and dynamically discover the logging API • Very minor impact on performances • Never throw messages, keep them! 29
  • 30. Logging levels • Fatal : critical errors • Error : errors that can be recovered • Warn : warnings • Info : general informations (start, stop, ...) • Debug : only-useful for debugging • Trace : only for critical debugging 30
  • 31. Log4J outputs root logger formatters logger.A logger.B logger.B.a filters 31
  • 32. Sample Log4J config log4.properties # Root logger log4j.rootLogger=INFO, consoleAppender # A console appender log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout log4j.appender.consoleAppender.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n 32
  • 33. Example public class OperationImpl implements Operation { (...) /** Logger. */ private static Log log = LogFactory.getLog(OperationImpl.class); (...) public void setMessage(Message message) { Message oldMessage = this.message; this.message = message; listeners.firePropertyChange(MESSAGE_PROPERTY_CHANGE, oldMessage, message); if (log.isDebugEnabled()) { log.debug(quot;Changing the message from quot; + oldMessage + quot; to quot; + message); } } (...) } 33
  • 35. Life of a tests suite • A test suite is like good wine: it gets better over time! • A good example is to reproduce bugs as they get identified: you will prevent regressions 35
  • 36. Handling bugs (ah ah I’m back) (I am a bug) Test case Tests suite 36
  • 37. Tests are also... • Useful to enforce API contracts • An excellent API usage documentation • A solid test suite allows deep refactorings: it acts as a safeguard against regressions • Tests reveal bad design early: it is difficult to test, then you need to refactor! 37
  • 39. Self-containment • Your test suites should be as self- contained as possible • Avoid environment setup requirements (databases servers, application servers, ...) • Eases automation in any context 39
  • 40. Examples data access relational objects database HTTP HTTP client server 40
  • 41. Self-contained DB public abstract class DAOTestBase extends TestCase { protected Map<String, String> queries; protected QueryRunner runner; base class protected Connection connection; public DAOTestBase() throws IOException { super(); DbUtils.loadDriver(quot;org.hsqldb.jdbcDriverquot;); runner = new QueryRunner(); queries = QueryLoader.instance().load(DBConstants.INIT_DB_SQL_RESOURCE); } protected void setUp() throws Exception { connection = DriverManager.getConnection(quot;jdbc:hsqldb:mem:CustomerDAOTestquot;, quot;saquot;, quot;quot;); runner.update(connection, queries.get(quot;create.customersquot;)); runner.update(connection, queries.get(quot;create.transactionsquot;)); runner.update(connection, queries.get(quot;data.1quot;)); runner.update(connection, queries.get(quot;data.2quot;)); runner.update(connection, queries.get(quot;data.3quot;)); runner.update(connection, queries.get(quot;data.4quot;)); runner.update(connection, queries.get(quot;data.5quot;)); } protected void tearDown() throws Exception { runner.update(connection, queries.get(quot;drop.transactionsquot;)); runner.update(connection, queries.get(quot;drop.customersquot;)); DbUtils.closeQuietly(connection); } 41 }
  • 42. Self-contained DB public class CustomerDAOTest extends DAOTestBase { public void testSaveAndUpdate() throws IOException, SQLException { CustomerDAO dao = new CustomerDAO(connection); Customer customer = new Customer(); test class customer.setName(quot;Bernard Minetquot;); customer.setEmail(quot;bernard@les-muscles.comquot;); customer.setAddress(quot;Francequot;); dao.save(customer); Customer readCustomer = dao.loadCustomerByName(quot;Bernard Minetquot;); assertEquals(customer, readCustomer); customer.setName(quot;Framboisierquot;); customer.setEmail(quot;framboisier@les-muscles.comquot;); customer.setAddress(quot;Paris, Francequot;); customer.setUrl(quot;http://blog.les-muscles.com/framboisier/quot;); customer.creditBalance(50.0); dao.update(customer); readCustomer = dao.loadCustomerByName(quot;Bernard Minetquot;); assertNull(readCustomer); readCustomer = dao.loadCustomerByName(quot;Framboisierquot;); assertNotNull(readCustomer); assertEquals(customer, readCustomer); } 42
  • 43. Self-contained HTTP public abstract class AbstractHttpSoapTransportTest extends TestCase { private Server server; base class private Servlet servlet; private ServletHandler servletHandler; protected AbstractHttpSoapTransportTest(Servlet servlet) { this.servlet = servlet; server = new Server(); SelectChannelConnector connector = new SelectChannelConnector(); connector.setPort(8085); server.setConnectors(new Connector[]{connector}); servletHandler = new ServletHandler(); servletHandler.addServletWithMapping(new ServletHolder(servlet), quot;/dtcquot;); server.setHandler(servletHandler); } protected void setUp() throws Exception { server.start(); } protected void tearDown() throws Exception { server.stop(); } } 43
  • 44. Self-contained HTTP public class DummyServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException { InputStream in = request.getInputStream(); OutputStream out = httpServletResponse.getOutputStream(); byte[] buffer = new byte[1024]; servlet for int nbytes = 0; while ((nbytes = in.read(buffer, 0, 1024)) != -1) { out.write(buffer, 0, nbytes); testing } } protected void doGet(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException { InputStream in = SoapMessageTest.class.getResourceAsStream(quot;simple-soap- message.xmlquot;); OutputStream out = httpServletResponse.getOutputStream(); byte[] buffer = new byte[1024]; int nbytes = 0; while ((nbytes = in.read(buffer, 0, 1024)) != -1) { out.write(buffer, 0, nbytes); } } } 44
  • 45. Self-contained HTTP public class HttpSoapTransportWithDummyServletTest extends AbstractHttpSoapTransportTest { private NodeComparator nodeComparator = new NodeComparator(); public HttpSoapTransportWithDummyServletTest() { test class super(new DummyServlet()); } public void testSend() throws DocumentException, IOException, XmlPullParserException, SoapTransportException { HttpSoapTransport soapTransport = new HttpSoapTransport(); SoapMessage message = SoapMessageUtils.readSoapMessageFromStream (SoapMessageTest.class .getResourceAsStream(quot;simple-soap-message.xmlquot;)); SoapMessage response = soapTransport.send(quot;http://localhost:8085/dtcquot;, message, null); assertEquals(0, nodeComparator.compare(message, response)); } } 45
  • 47. HttpUnit • Functional testing • Works like a web browser / HTTP client (cookies, form submissions, ...) • Embeds a JavaScript engine (Rhino) • JUnit integration • Provides ServletUnit to unit-test servlets in isolation of servlet containers 47
  • 48. Main classes • WebConversation: stateful client session • WebRequest: a single GET or POST HTTP request • WebResponse: HTTP response • WebForm, WebLink, (...): many helper classes to access the pages content 48
  • 49. Example public void testGoodLogin() throws Exception { WebConversation conversation = new WebConversation(); WebRequest request = new GetMethodWebRequest( quot;http://www.meterware.com/servlet/TopSecretquot;); WebResponse response = conversation.getResponse(request); WebForm loginForm = response.getForms()[0]; request = loginForm.getRequest(); request.setParameter( quot;namequot;, quot;masterquot; ); response = conversation.getResponse( request ); assertTrue( quot;Login not acceptedquot;, response.getText().indexOf( quot;You made it!quot; ) != -1 ); assertEquals( quot;Page titlequot;, quot;Top Secretquot;, response.getTitle() ); } 49 http://fb2.hu/x10/Articles/HttpUnit.html
  • 50. (from the cookbook) WebConversation wc = new WebConversation(); WebResponse resp = wc.getResponse( quot;http://www.httpunit.org/doc/cookbook.htmlquot; ); WebLink link = resp.getLinkWith( quot;responsequot; ); link.click(); WebResponse jdoc = wc.getCurrentPage(); WebTable table = resp.getTables()[0]; assertEquals( quot;rowsquot;, 4, table.getRowCount() ); assertEquals( quot;columnsquot;, 3, table.getColumnCount() ); assertEquals( quot;linksquot;, 1, table.getTableCell( 0, 2 ).getLinks().length ); WebForm form = resp.getForms()[0]; assertEquals( quot;La Cerentollaquot;, form.getParameterValue( quot;Namequot; ) ); assertEquals( quot;Chinesequot;, form.getParameterValue( quot;Foodquot; ) ); assertEquals( quot;Manayunkquot;, form.getParameterValue( quot;Locationquot; ) ); assertEquals( quot;onquot;, form.getParameterValue( quot;CreditCardquot; ) ); form.setParameter( quot;Foodquot;, quot;Italianquot; ); form.removeParameter( quot;CreditCardquot; ); form.submit(); 50
  • 51. ServletUnit example ServletRunner sr = new ServletRunner(); sr.registerServlet( quot;myServletquot;, StatefulServlet.class.getName() ); ServletUnitClient sc = sr.newClient(); WebRequest request = new PostMethodWebRequest(quot;http://test.meterware.com/myServletquot;); request.setParameter( quot;colorquot;, quot;redquot; ); WebResponse response = sc.getResponse( request ); assertNotNull( quot;No response receivedquot;, response ); assertEquals( quot;content typequot;, quot;text/plainquot;, response.getContentType() ); assertEquals( quot;requested resourcequot;, quot;You selected redquot;, response.getText() ); public class StatefulServlet extends HttpServlet { protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException { resp.setContentType( quot;text/plainquot; ); writeSelectMessage( req.getParameter( quot;colorquot; ), resp.getWriter() ); setColor( req, req.getParameter( quot;colorquot; ) ); } protected void writeSelectMessage(String color, PrintWriter pw) throws IOException { pw.print( quot;You selected quot; + color ); pw.close(); } void setColor( HttpServletRequest req, String color ) throws ServletException { req.getSession().setAttribute( quot;colorquot;, color ); } 51 }
  • 53. Problem: dependencies AdressBook PersonDAO + loadPerson(...) + savePerson(...) 53
  • 54. Hard-dependencies • Isolating the class to test is difficult and/or impossible • Failures may be induced by a dependency • More generally, it reveals potential code evolution problems: strong coupling 54
  • 55. Depending on interfaces <<interface>> AdressBook IPersonDAO + loadPerson(...) + savePerson(...) DBPersonDAO FilePersonDAO MockPersonDAO 55
  • 56. Interfaces dependencies • Interfaces introduce loose coupling • At execution time: use the real class • At test time: use a mock class • Future evolution is easier • BTW, don’t over-use interfaces! 56
  • 57. Mock objects • Give a simple behavior: fixed values, random values, values passed by methods of the mock class, ... • They allow you to test even if the real class hasn’t been created yet • EasyMock, JMockIt allow to generate mocks on-the-fly 57
  • 58. Object.equals() public boolean equals(Object obj) { if (obj instanceof ComparisonNode) { ComparisonNode other = (ComparisonNode) obj; return symbol.equals(other.symbol) && leftChild.equals(other.leftChild) && rightChild.equals(other.rightChild); } return false; important for } TestCase.assertXXX(...) 58
  • 59. Dependency injection • 2 types of injection: setter-based & constructor-based • Constructor injection is preferable, and make your objects ready right after their instanciation • Clarifies classes dependencies • Principle used in inversion of control frameworks: PicoContainer, Spring, ... 59
  • 60. Example private IConstraintNode leftChild; private IConstraintNode rightChild; private String symbol; public ComparisonNode(String symbol, VariableNode var, ConstantNode cst) { this(var, cst, symbol); } public ComparisonNode(String symbol, ConstantNode cst, VariableNode var) { this(cst, var, symbol); } protected ComparisonNode(IConstraintNode leftChild, IConstraintNode rightChild, String symbol) { super(); this.symbol = symbol; this.leftChild = leftChild; this.rightChild = rightChild; } 60
  • 62. Do • Try to really write your tests first • Test as soon as you create a new class • Test often • Start with sensible simple scenarios • Load data from resources (Class.getResourceAsStream(“/path/to”)) • Check for code coverage 62
  • 63. Don’t • Write overly exhaustive test cases • Write tests for trivial methods (getters, setters, ...) even if it lowers coverage • Catch exceptions, unless you actually test that • Fix bugs without first reproducing them in a test case 63
  • 64. Traversing object graphs • Sometimes you will need to walk through deep object graphs to test values • This is really boring • JXPath uses XPath on objects, and replaces iterations/loops by requests 64
  • 65. JXPath example Iterator it; String str; JXPathContext ctx = JXPathContext.newContext(bp2); TestCase.assertEquals(quot;s0quot;, bp2.getInitialState().getName()); it = ctx.iterate(quot;finalStates/namequot;); TestCase.assertTrue(it.hasNext()); TestCase.assertEquals(quot;s1quot;, (String) it.next()); TestCase.assertFalse(it.hasNext()); it = ctx.iterate(quot;states[name='s0']/successors/namequot;); TestCase.assertTrue(it.hasNext()); TestCase.assertEquals(quot;s1quot;, (String) it.next()); TestCase.assertEquals(quot;s0quot;, (String) it.next()); TestCase.assertFalse(it.hasNext()); (...) Operation toRemove = (Operation) ctx.getValue(quot;operations[message/name='a']quot;); bp2.removeOperation(toRemove); List remainingOps = (List) ctx.getValue(quot;states[name='s0']/incomingOperationsquot;); TestCase.assertTrue(remainingOps.size() == 1); 65
  • 66. The case of ‘old’ software • Test cases can be added to existing applications • In many situations the design can make it difficult to test / isolate... • You cannot break existing APIs • Don’t expect to introduce tests cases for 100% of the code base... • It will still allow you to spot new bugs! 66
  • 68. Problem • Developers work on different portions of the code base • Traditional integration may not be frequent enough (~ weekly) • It can be difficult to find who, when and how the build was broken • Continuous integration aims at detecting problems in nearly real-time 68
  • 69. C.I. environment 4 email developers instant messaging 1 continuous integration changeset (Continuum, ...) 3 execute notification via hooks 2 source code tests suite repository 69 (SVN, CVS, ...)
  • 70. • Demo: • project using Maven2 • Apache Continuum configuration • launch the tests from Continuum 70
  • 71. Thanks! 71