Junit Architecture - PowerPoint PPT Presentation

1 / 51
About This Presentation
Title:

Junit Architecture

Description:

Junit Architecture LiuBing bliu76_at_yeah.net Agenda Junit Background Usage Junit Junit architecture and design pattrens Conclusion Junit JUnit is an open source Java ... – PowerPoint PPT presentation

Number of Views:156
Avg rating:3.0/5.0
Slides: 52
Provided by: cnjavaCom
Category:

less

Transcript and Presenter's Notes

Title: Junit Architecture


1
Junit Architecture
  • LiuBing
  • bliu76_at_yeah.net

2
Agenda
  • Junit Background
  • Usage Junit
  • Junit architecture and design pattrens
  • Conclusion

3
Junit
  • JUnit is an open source Java testing framework
    used to write and run repeatable tests. It is an
    instance of the xUnit architecture for unit
    testing frameworks.
  • JUnit features include
  • Assertions for testing expected results
  • Test fixtures for sharing common test data
  • Test suites for easily organizing and
    running tests
  • Graphical and textual test runners
  • JUnit was originally written by Erich Gamma and
    Kent Beck.

4
Martin Fowler
  • Never in the field of software development was so
    much owed by so many to so few lines of code"
    Martin Fowler

Martin Fowler??????????UML????????????XP???...??
,?????????,??ThoughtWorks??????Martin
Fowler??4?????Analysis Patterns Reusable
Object Models?UML Distilled Applying the
Standard Object Modeling Language?Refactoring
Improving the Design of Existing Code?Planning
Extreme Programming?
5
JavaWorld
  • 2002 JavaWorld Editors' Choice Awards (ECA)
  • Best Java Performance Monitoring/Testing Tool
  • 2001 JavaWorld Editors' Choice Awards (ECA)
  • Best Java Performance Monitoring/Testing Tool

6
Developer-Kent Beck
  • Kent Beck

Kent Beck?????????????,?XP(Extreme
Programming)????,?17????????????
????????????,CRC?????????????,HotDraw???????,??xUn
it?????,??????????????????????? Kent Beck?The
Smalltalk Best Practice Patterns?Extreme
Programming Explained?Planning Extreme
Programming(?Martin Fowler??)???,?????XP??????
????Three Rivers Institute????TRI???????????????,?
??????Agile Alliance?????,Agile
Alliance??????????????????
7
Developer- Erich Gamma
  • Erich Gamma is the Technical Director of the
    Software Technology Center of ObjectTechnologyInte
    rnational (OTI) in Zurich.
  • Some of his recent projects are
  • EclipseIde - IBM's new platform for development
    tools
  • JFace - the Eclipse UI Framework
  • Eclipse Java Tooling
  • IBM VisualAge MicroEdition? IDE
  • ULC - Ultra Light Client an infrastructure for
    thin Java clients.
  • Erich pairs as often as possible with KentBeck to
    work on JavaUnit.
  • He's author number 1 of the GangOfFour and feels
    more and more guilty that there isn't a 2nd
    edition...

8
XP
  • Extreme Programming is a discipline of
    software development based on values of
    simplicity, communication, feedback, and courage.
    It works by bringing the whole team together in
    the presence of simple practices, with enough
    feedback to enable the team to see where they are
    and to tune the practices to their unique
    situation.

Test-Driven development
9
Usage Junit
10
JUnit Infected Programmers Love Writing Tests
  • see Test Infected Programmers Love Writing
    Tests, Java Report, July 1998, Volume 3, Number 7

11
IDE
  • JBuilder
  • Eclipse
  • Forte/Netbeans
  • IntelliJ
  • TogetherJ
  • Visual Age
  • JDeveloper Integration

12
JB7
13
test
  • public class test
  • public int add(int a,int b)
  • return ab

14
TestCase
  • public class Testtest extends TestCase
  • public Testtest(String s)
  • super(s)
  • protected void setUp()
  • System.out.println("setUp")
  • protected void tearDown()
  • System.out.println("tearDown")
  • public void testAdd()
  • test test new test()
  • this.assertEquals(12,test.add(9, 1))

15
Junit Result
16
Junit Architecture Patterns
17
Goals
  • What are the goals of JUnit?

18
Junit Architecture -Microkernel
19
Microkernel
20
Patterns Generate Architectures
  • The design of JUnit will be presented in a
    style first used in (see "Patterns Generate
    Architectures", Kent Beck and Ralph Johnson,
    ECOOP 94). The idea is to explain the design of a
    system by starting with nothing and applying
    patterns, one after another, until you have the
    architecture of the system. We will present the
    architectural problem to be solved, summarize the
    pattern that solves it, and then show how the
    pattern was applied to JUnit

21
Patterns
22
Getting started- TestCase
Encapsulate a request as an object, thereby
letting you queue or log requests" Command
tells us to create an object for an operation
and give it a method "execute".
23
TestCase
24
Blanks to fill in- run()
Define the skeleton of an algorithm in an
operation, deferring some steps to subclasses.
Template Method lets subclasses redefine certain
steps of an algorithm without changing the
algorithms structure
25
TestCase
  • Here is the template method
  • public void run()     setUp()     runTest()
        tearDown()
  • The default implementations of these methods do
    nothing
  • protected void runTest()
  • protected void setUp()
  • protected void tearDown()
  • Since setUp and tearDown are intended to be
    overridden but will be called by the framework we
    declare them as protected

26
SubClass TestCase
  • public class Testtest extends TestCase
  • public Testtest(String s)
  • super(s)
  • protected void setUp()
  • System.out.println("setUp")
  • protected void tearDown()
  • System.out.println("tearDown")
  • public void testAdd()
  • test test new test()
  • this.assertEquals(12,test.add(9, 1))

27
Dont care about one or many - TestSuite
Compose objects into tree structures to represent
part-whole hierarchies. Composite lets clients
treat individual objects and compositions of
objects uniformly
28
TestSuite
  • public class TestSuite implements Test
  • private Vector fTests new Vector(10)
  • public void addTest(Test test)
  • fTests.addElement(test)
  • public void run(TestResult result)
  • for (Enumeration e tests() e.hasMoreElements()
    )
  • if (result.shouldStop() )
  • break
  • Test test (Test)e.nextElement()
  • runTest(test, result)

29
JB TestSuit
30
Reporting results- TestResult
Collecting Parameter suggests that when you need
to collect results over several methods, you
should add a parameter to the method and pass an
object that will collect the results for you.
31
TestResult
32
TestCase Run
  • 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()
       

33
Extend TestResult
  • JUnit comes with different implementations
    of TestResult. The default implementation counts
    the number of failures and errors and collects
    the results. TextTestResult collects the results
    and presents them in a textual form. Finally,
    UITestResult is used by the graphical version of
    the JUnit Test Runner to update the graphical
    test status. TestResult is an extension point of
    the framework. Clients can define their own
    custom TestResult classes, for example, an
    HTMLTestResult reports the results as an HTML
    document.

34
AssertionFailedError
  • An AssertionFailedError is triggered by the
    assert method provided by TestCase. JUnit
    provides a set of assert methods for different
    purposes. Here is the simplest one
  • protected void assert(boolean condition)    
    if (!condition)         throw new
    AssertionFailedError()
  • The AssertionFailedError is not meant to be
    caught by the client (a testing method inside a
    TestCase) but inside the Template Method
    TestCase.run(). We therefore derive
    AssertionFailedError from Error.
  • public class AssertionFailedError extends Error
        public AssertionFailedError ()
  • The methods to collect the errors in TestResult
    are shown below
  • public synchronized void addError(Test test,
    Throwable t)     fErrors.addElement(new
    TestFailure(test, t)) public synchronized
    void addFailure(Test test, Throwable t)    
    fFailures.addElement(new TestFailure(test, t))

35
AssertionFailedError
36
Observer
  • ???????????????,?????????????,????????????????????
    ?

37
TestResult
  • public class TestResult extends Object
  • protected Vector fFailures
  • protected Vector fErrors
  • protected Vector fListeners
  • public synchronized void addError(Test test,
    Throwable t)
  • fErrors.addElement(new TestFailure(test, t))
  • for (Enumeration e cloneListeners().elements()
    e.hasMoreElements() )
  • ((TestListener)e.nextElement()).addError(test,
    t)
  • public synchronized void addFailure(Test test,
    AssertionFailedError t)
  • fFailures.addElement(new TestFailure(test, t))
  • for (Enumeration e cloneListeners().elements()
    e.hasMoreElements() )
  • ((TestListener)e.nextElement()).addFailure(test
    , t)
  • public synchronized void addListener(TestListener
    listener)
  • fListeners.addElement(listener)

38
TestListener
  • public interface TestListener
  • /
  • An error occurred.
  • /
  • public void addError(Test test, Throwable t)
  • /
  • A failure occurred.
  • /
  • public void addFailure(Test test,
    AssertionFailedError t)
  • /
  • A test ended.
  • /
  • public void endTest(Test test)
  • /
  • A test started.
  • /
  • public void startTest(Test test)

39
TestRunner
  • public class TestRunner extends BaseTestRunner
  • public synchronized void addError(Test test,
    Throwable t)
  • writer().print("E")
  • public synchronized void addFailure(Test
    test, AssertionFailedError t)
  • writer().print("F")
  • public synchronized void startTest(Test test)
  • writer().print(".")
  • if (fColumn gt 40)
  • writer().println()
  • fColumn 0
  • public void endTest(Test test)

40
Adapter
Convert the interface of a class into another
interface clients expect
41
Code
  • public class TestMoneyEquals extends MoneyTest
        public TestMoneyEquals() super("testMoneyEqu
    als")  
  •    protected void runTest ()
    testMoneyEquals()
  • TestCase test new MoneyTest("testMoneyEquals ")
        protected void runTest()
    testMoneyEquals()

42
Decorator
??????????????????
43
TestDecorator
  • public class TestDecorator extends Assert
    implements Test
  • protected Test fTest
  • public TestDecorator(Test test)
  • fTest test
  • /
  • The basic run behaviour.
  • /
  • public void basicRun(TestResult result)
  • fTest.run(result)
  • public int countTestCases()
  • return fTest.countTestCases()
  • public void run(TestResult result)
  • basicRun(result)

44
TestSetup
  • public class TestSetup extends TestDecorator
  • public TestSetup(Test test)
  • super(test)
  • public void run(final TestResult result)
  • Protectable p new Protectable()
  • public void protect() throws Exception
  • setUp()
  • basicRun(result)
  • tearDown()
  • result.runProtected(this, p)

45
Summary
  • Command
  • Template method
  • Collecting Parameter
  • Adapter
  • Pluggables Selector
  • Composite
  • Observer
  • Decorator
  • MicroKernel (SA Pattern)

46
Conclusion
47
Patterns
  • We found discussing the design in terms of
    patterns to be invaluable, both as we were
    developing the framework and as we try to explain
    it to others. You are now in a perfect position
    to judge whether describing a framework with
    patterns is effective. If you liked the
    discussion above, try the same style of
    presentation for your own system.

48
Pattern density
  • There is a high pattern "density" around
    TestCase, which is the key abstraction of JUnit.
    Designs with high pattern density are easier to
    use but harder to change. We have found that such
    a high pattern density around key abstractions is
    common for mature frameworks. The opposite should
    be true of immature frameworks - they should have
    low pattern density. Once you discover what
    problem you are really solving, then you can
    begin to "compress" the solution, leading to a
    denser and denser field of patterns where they
    provide leverage.

49
Eat your own dog food
  • As soon as we had the base unit testing
    functionality implemented, we applied it
    ourselves. A TestTest verifies that the framework
    reports the correct results for errors,
    successes, and failures. We found this invaluable
    as we continued to evolve the design of the
    framework. We found that the most challenging
    application of JUnit was testing its own
    behavior.

50
Intersection, not union
  • There is a temptation in framework
    development to include every feature you can.
    After all, you want to make the framework as
    valuable as possible. However, there is a
    counteracting force- developers have to decide to
    use your framework. The fewer features the
    framework has, the easier it is to learn, the
    more likely a developer will use it. JUnit is
    written in this style. It implements only those
    features absolutely essential to running tests-
    running suites of tests, isolating the execution
    of tests from each other, and running tests
    automatically. Sure, we couldnt resist adding
    some features but we were careful to put them
    into their own extensions package
    (test.extensions). A notable member of this
    package is a TestDecorator allowing execution of
    additional code before and after a test.

51
Framework writers read their code
  • We spent far more time reading the JUnit code
    than we spent writing it, and nearly as much time
    removing duplicate functionality as we spent
    adding new functionality. We experimented
    aggressively with the design, adding new classes
    and moving responsibility around in as many
    different ways as we could imagine. We were
    rewarded (and are still being rewarded) for our
    monomania by a continuous flow of insights into
    JUnit, testing, object design, framework
    development, and opportunities for further
    articles.
Write a Comment
User Comments (0)
About PowerShow.com