1 / 44

OOSC – Lab 1

OOSC – Lab 1. Welcome. Object Oriented programming is first and foremost a method for software construction, whose goal is to build high-quality software in a repeatable way. Achieved by designing classes that: Correspond well to the application domain Have simple and clean interface

melba
Télécharger la présentation

OOSC – Lab 1

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. OOSC – Lab 1

  2. Welcome • Object Oriented programming is first and foremost a method for software construction, whose goal is to build high-quality software in a repeatable way. • Achieved by designing classes that: • Correspond well to the application domain • Have simple and clean interface • Documented interface for future re-use and modification

  3. Design By Contract • A method of separating the concerns of the user and implementer of the class, and giving both enough information for their tasks. • Work in this course will be done with Java, offers partial support for those concepts. • Each class and method should be documented in Javadoc style.

  4. Design By Contract • In order to implement the principles of Design-by-Contract in Java, we will use a free tool from Man Machine Systems names JMSAssert. • It works with Sun’s JDK 1.2 & 1.3 but not 1.4

  5. Design By Contract • A powerful technique for writing reliable software. • Specifying the software purpose with the implementation. • Key elements: • Invariant • Preconditions • Postconditions

  6. Design By Contract • Precondition – The constraints under which the routine will function properly. • Postconditions – The state of the class after the routine execution • The Contract: If you call routine R() with the preconditions satisfied, R() will return satisfying the postconditions. • Invariant – Always holds

  7. When are condition checked?

  8. JMS Syntax - Invariant • Invariant - @inv • May access all class members or its direct/indirect bases, including private members • May appear in any JavaDoc comment • Preferable in the class comment

  9. JMS Syntax - Preconditions • Precondition - @pre • JavaDoc preceding the respective method • May reference class members and arguments • Multiple @pre markers are conjugated (AND)

  10. JMS Syntax - Postconditions • Postconditions - @post • JavaDoc preceding the respective method • May use $prev(expression) to access the value at the method entry. • May use $ret to denote method’s return value • Multiple @post markers are conjugated (AND)

  11. Example Precondition /** * @pre !isEmpty() * @post (top == $prev(top- 1)) * @post $ret == elems[top] * @post !isFull */ public synchronized Object pop() { return elems[--top]; } Postconditions

  12. JMS Syntax - General • Order has no meaning • @macro – for complicated conditions • Recursion – as expected, on every call • Inner classes can access outer classes’ members • Anonymous classes – specify invariant in one of its methods

  13. Downloads & Installations • Download Java J2SE SDK 1.3.1 from http://java.sun.com/downloads (~41MB)Install into C:\Program Files\jdk1.3.1_07 • Download JMSAssert 1.02 from http://www.mmsindia (~1.2MB)Run the jmssetup-1.02.exe installation fileInstall into C:\Program Files\AMSAssert1.0

  14. JMSAssert Installation • The following lines are added to the path: REM Next two lines are added by JMSAssert SET CLASSPATH=%CLASSPATH%;C:\PROGRA~1\JMSASS~1.0\ bin\mmsclasses.jar; SET PATH=%PATH%;C:\PROGRA~1\JMSASS~1.0\bin; • Copy the “classic” directory from “C:\Program Files\jdk1.3.1_07\jre\bin\” to the directory:“C:\Program Files\JavaSoft\JRE\1.3.1_07\bin\”

  15. Setup (cont.) • Your JavaSoft directory should look like:

  16. JMSAssert – how does it work • Annotate source code with assertions • Compile your code using javac (as usual) • Preprocess the code using jmsassert: creates contract files (*.jms) and a Startup.jms file. • *.jms files contain java code for the assertions. • Execute using: jmsjava Startup <filename>to check assertions. • jmsjava makes sure method assertions are called before/after the method invocation.

  17. JMS Execution • “jmsassert” – generates help text • “jmsassert –s <filename.java>” – generate assertions for a class file • “jmsassert –r –s .” – generate assertions for all class files in the directory and sub-dirs. (use for packages) • “javac <filename.java>” – compile • “jmsjava Startup <main>” - execute and check assertions

  18. Execution process Stack Demo files Annotate source with assertions MyStack.java Preprocess to generate assertion files Startup.jms default_MyStack.jms jmsassert –s <file.java> default_MyStack_StackEnum.jms Compile Java file javac <file.java> MyStack.class MyStack$StackEnum.class Execute using jmsjava MyStack$StackEnum.class StackTest.class jmsjava Startup <file.java>

  19. Notes • Execute these steps form the command line! • Make sure your CLASSPATH environment variable contains the current directory.Add “CLASSPATH=%CLASSPATH%;.;” to autoexec.bat.

  20. An Example (MyStack) • A stack with invariants, pre conditions and post conditions: MyStack.java • A main file: StackTest.java • Compile all .java files (using javac) • Generate JMSAssert triggers by:jmsassert –s MyStack.java • Run and test assertions byjmsjava Startup StackTest • You can always run your test program in byjava StackTest

  21. MyStack.java (#1) /** @inv (top >= 0 && top < max) */ class MyStack { private Object[] elems; private int top, max; /** @pre (sz > 0) @post (max == sz && elems != null) */ public MyStack(int sz) { max = sz; elems = new Object[sz]; }

  22. MyStack.java (#2) /** @pre !isFull() @post (top == $prev (top) + 1) && elems[top-1] == obj */ public void push(Object obj) { elems[top++] = obj; } /** @pre !isEmpty() @post (top == $prev (top) - 1) && $ret == elems[top] */ public Object pop() { return elems[--top]; }

  23. MyStack.java (#3) /** @post ($ret == (top == max)) */ public boolean isFull() { return top == max; } /** @post ($ret == (top == 0)) */ public boolean isEmpty() { return top == 0; } } // End MyStack

  24. StackTest.java class StackTest { public static void main(String[] args) { MyStack s = new MyStack(2); // Can push at most 2 elements s.push(new Integer(1)); s.push(new Integer(23)); s.push(new Integer(0)); // Precondition violation here! } }

  25. Eclipse • Download and install eclipse 2.0.2 from http://www.eclipse.org/downloads/index.php(simply extract to C:\Program Files\eclipse) • Instructions are under http://www1.idc.ac.il/oosc/jm+e.htm • Also under http://dev.eclipse.org:8080/help/help.jsp

  26. JUnit • JUnit is a regression testing framework written by Erich Gamma and Kent Beck. It is used by the developer who implements unit tests in Java. JUnit is Open Source Software, released under the IBM's Common Public License Version 1.0 and hosted on SourceForge

  27. Junit - Installation • Download from http://www.junit.org • UnZip to C:\Program Files\junit3.8.1 • Add junit.jar to your CLASSPATH • Test samples under junit by • java junit.textui.TestRunner junit.samples.AllTestsOR • java junit.awtui.TestRunner junit.samples.AllTests

  28. Unit testing • Developers write unit tests to check their own code. • Unit testing differs from integration testing, which confirms that components work well together, and acceptance testing, which confirms that an application does what the customer expects it to do. • Unit tests are so named because they test a single unit of code. • In the case of Java, a unit usually equates to a single class

  29. Unit testing (cont.) • A unit test is fully automated, non-interactive, and binary—that is, it either succeeds or fails. • So running your code and examining its output to see if it works is not a test. • Neither is writing a little "test driver" that drives your code and allows you to check logs to see if it's working correctly • For years, unit testing languished in the "I know I should be doing it" category

  30. The problem • Every programmer knows they should write tests for their code. Few do • The universal response to "Why not?" is "I'm in too much of a hurry." This quickly becomes a vicious cycle

  31. An example (money .. Yeh!) class Money { private int fAmount; private String fCurrency; public Money(int amount, String currency) { fAmount= amount; fCurrency= currency; } public int amount() { return fAmount; } public String currency() { return fCurrency; } }

  32. An Example (cont.) public Money add(Money m) { return new Money(amount()+m.amount(), currency()); } import junit.framework.TestCase; public class MoneyTest extends TestCase { //… public void testSimpleAdd() { Money m12NIS= new Money(12, "NIS"); // (1) Money m14NIS= new Money(14, "NIS"); Money expected= new Money(26, "NIS"); Money result= m12NIS.add(m14NIS); // (2) assertTrue(expected.equals(result)); // (3) } }

  33. An Example (cont.) • We have code (1) to create the objects • We have code (2) to exercise the objects in the fixture • We have code (3) to verify the result • Before we can verify the result we have to digress a little since we need a way to test that two Money objects are equal. The Java idiom to do so is to override the method equals defined in Object

  34. An example (cont.) public boolean equals(Object anObject) { if (anObject instanceof Money) { Money aMoney = (Money)anObject; return aMoney.currency().equals(currency()) && amount() == aMoney.amount(); } return false; }

  35. An Example (cont.) public void testEquals() { Money m12NIS= new Money(12, “NIS"); Money m14NIS= new Money(14, “NIS"); assertTrue(!m12NIS.equals(null)); assertEquals(m12NIS, m12NIS); assertEquals(m12NIS, new Money(12, “NIS")); // (1) assertTrue(!m12NIS.equals(m14NIS)); }

  36. Using TestCase subclass public class MoneyTest extends TestCase { private Money f12NIS; private Money f14NIS; protected void setUp() { f12NIS= new Money(12, “NIS"); f14NIS= new Money(14, “NIS"); } }

  37. Rewrite test cases public void testEquals() { Assert.assertTrue(!f12NIS.equals(null)); Assert.assertEquals(f12NIS, f12NIS); Assert.assertEquals(f12NIS, new Money(12, “NIS")); Assert.assertTrue(!f12NIS.equals(f14NIS)); } public void testSimpleAdd() { Money expected= new Money(26, “NIS"); Money result= f12NIS.add(f14NIS); Assert.assertTrue(expected.equals(result)); }

  38. A static run • override the runTest method inherited from TestCase and call the desired test case TestCase test= new MoneyTest("simple add") { public void runTest() { testSimpleAdd(); } }; • Name the test so you can identify it if it fails

  39. A dynamic run • create a test case to be run uses reflection to implement runTest • the name of the test is the name of the test case method to invoke • dynamically finds and invokes the test method TestCase test= new MoneyTest("testSimpleAdd"); • The dynamic way is more compact to write but it is less static type safe

  40. Define a TestSuite and run • The suite method is like a main method that is specialized to run tests public static Test suite() { TestSuite suite= new TestSuite(); suite.addTest(new MoneyTest("testEquals")); suite.addTest(new MoneyTest("testSimpleAdd")); return suite; }

  41. Testing practices • Whenever you are tempted to type something into a print statement or a debugger expression, write it as a test instead • You can always write more tests. However, you will quickly find that only a fraction of the tests you can imagine are actually useful • During Development- When you need to add new functionality to the system, write the tests first • During Debugging- When someone discovers a defect in your code, first write a test that will succeed if the code is working • Once you get them running, make sure they stay running

  42. Sacrifice design for testing • If you ever feel tempted to make a private method public purely for testing purposes, don't do it. • Testing is meant to improve the quality of your code, not decrease it

  43. Statistical testing for non-deterministic code • Whenthe detailed results of a method are influenced by more than just the code in the method • A chaotic example: testing the time it takes a message to travel from a Web server to a browser over the Internet • Try to make some useful predictions about the expected values

  44. Conclusion • Unit tests are fairly easy to write and have very rapid performance, so it's not going to take you long to run them

More Related