Junit Architecture LiuBing bliu76@yeah.net. Agenda Junit Background Usage Junit Junit architecture and design pattrens Conclusion

  • View
    219

  • Download
    2

Embed Size (px)

Text of Junit Architecture LiuBing bliu76@yeah.net. Agenda Junit Background Usage Junit Junit architecture...

  • Junit ArchitectureLiuBing bliu76@yeah.net

  • AgendaJunit BackgroundUsage JunitJunit architecture and design pattrensConclusion

  • 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.

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

    Martin FowlerUMLXP...ThoughtWorksMartin Fowler4Analysis Patterns : Reusable Object ModelsUML Distilled: Applying the Standard Object Modeling LanguageRefactoring: Improving the Design of Existing CodePlanning Extreme Programming

  • 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

  • Developer-Kent BeckKent Beck

    Kent BeckXPExtreme Programming17 CRCHotDrawxUnit Kent BeckThe Smalltalk Best Practice PatternsExtreme Programming ExplainedPlanning Extreme ProgrammingMartin FowlerXP Three Rivers InstituteTRIAgile AllianceAgile Alliance

  • Developer- Erich Gamma Erich Gamma is the Technical Director of the Software Technology Center of ObjectTechnologyInternational (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...

  • 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.

  • Usage Junit

  • JUnit Infected: Programmers Love Writing Testssee Test Infected: Programmers Love Writing Tests, Java Report, July 1998, Volume 3, Number 7

  • IDEJBuilderEclipseForte/NetbeansIntelliJTogetherJVisual AgeJDeveloper Integration

  • JB7

  • testpublic class test { public int add(int a,int b){ return a+b; }}

  • TestCasepublic 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)); }}

  • Junit Result

  • Junit Architecture & Patterns

  • Goals What are the goals of JUnit?

  • Junit Architecture -Microkernel

  • Microkernel

    extensions

    FrameWork

  • 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

  • Patterns

  • 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".

  • TestCase

  • 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

  • TestCaseHere 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

  • SubClass TestCasepublic 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)); }}

  • 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

  • TestSuitepublic 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);} }}

  • JB TestSuit

  • 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.

  • TestResult

  • TestCase Runpublic 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(); } }

  • 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.

  • 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)); }

  • AssertionFailedError

  • Observer

  • TestResultpublic 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);}public synchronized void removeListener(TestListener listener) {fListeners.removeElement(listener);}}

  • TestListenerpublic 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);}

  • TestRunnerpublic 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++ >= 40) {writer().println();fColumn= 0;} } public void endTest(Test test) { }}

  • AdapterConvert the interface of a class into another interface clients expect

  • Codepublic class TestMoneyEquals extends MoneyTest { public TestMoneyEquals(){ super("testMoneyEquals"); } protected void runTest () { testMoneyEquals(); } }

    TestCase test= new MoneyTest("testMoneyEquals ") { protected void runTest() { testMoneyEquals(); } };

  • Decorator

  • TestDecoratorpublic class TestDecorator extends Assert implements Test {protected Test fTest;

    public TestDecorator(Test test) {fTest= test;}/** * The basic run behaviour. */public void basicRun(TestResult