code quality maintainability reusability debugging testing l.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
Code Quality, Maintainability, Reusability, Debugging , Testing PowerPoint Presentation
Download Presentation
Code Quality, Maintainability, Reusability, Debugging , Testing

Loading in 2 Seconds...

play fullscreen
1 / 71

Code Quality, Maintainability, Reusability, Debugging , Testing - PowerPoint PPT Presentation


  • 128 Views
  • Uploaded on

Code Quality, Maintainability, Reusability, Debugging , Testing. SIF8080, Sep. 27th 2001 Customer-driven project Carl-Fredrik Sørensen mailto:carlfrs@idi.ntnu.no. Spider-web. Outline. Code Quality & Standards . Debugging, logging etc. Testing. Key Principles; Coding. Understandability

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Code Quality, Maintainability, Reusability, Debugging , Testing' - meryl


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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
code quality maintainability reusability debugging testing

Code Quality, Maintainability, Reusability, Debugging, Testing

SIF8080, Sep. 27th 2001

Customer-driven project

Carl-Fredrik Sørensenmailto:carlfrs@idi.ntnu.no

outline
Outline
  • Code Quality & Standards.
  • Debugging, logging etc.
  • Testing.
key principles coding
Key Principles; Coding
  • Understandability
  • High cohesion
  • Loose coupling
  • Code Formatting
  • Consistent Naming
  • Information hiding
  • Valuable Comments
code standards 1
Code Standards (1)
  • Why?
    • Gives less defects.
    • Easier/cheaper maintenance.
    • Several people may work on and understand the same code.
    • Code to be read, not only written.
  • Java coding standards:
    • The Elements of Java Style; Vermeulen et.al. SIGS Books.
    • http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html.
code standards 2
Code Standards (2)
  • General rules:
    • Simplicity – Build simple classes and methods. Keep it as simple as possible, but not simpler (Einstein).
    • Clarity – Ensure item has a clear purpose. Explain where, when, why, and how to use each.
    • Completeness –Create complete documentation; document all features and functionality.
code standards 3
Code Standards (3)
  • General rules (continued):
    • Consistency – Similar entities should look and behave the same; dissimilar entities should look and behave differently. Create and apply standards whenever possible.
    • Robustness – Provide predictable documented behaviour in response to errors and exceptions. Do not hide errors and do not force clients to detect errors.
code standards 4
Code Standards (4)
  • Do it right the first time !
  • Your professionalism is expressed by applying code standards !
  • Document any deviations!
formatting
Formatting
  • Is important for readability, not for the compiler.
  • Use a common standard for code formatting.
  • Do notalter the style of old code to fit new standards.
examples 1
Examples (1)

class MyClass {

void function (int arg) {

if (arg < 0) {

for (int index = 0; index <= arg; index++) {

//… Some Action Code …

} // end for

} // end if

} // end function

} // end MyClass

examples 2
Examples (2)
  • Include white space:
    • Bad: double length=Math.sqrt(x*x+y*y);
    • Better: double length = Math.sqrt(x * x + y * y);
    • Use blank lines to separate.
    • Do not use hard tabs.
naming
Naming
  • Clear, unambiguous, readable, meaningful.Describe the purpose of the item:
    • Bad: X1, X2, mth, get, tmp, temp, result.
    • Give a descriptive name to temporary variables.
  • But: scientific formulas may be better formulated with single characters/words representing symbols instead of descriptive names.
naming13
Naming
  • Establish and use a common naming convention.
  • Problems creating a good name  purpose of the operation is not clear.
    • Bad: void get(…)., better: retrieveDataSamples.
    • Bad: Time day(Time p_day), better: getDate or getTruncDate.
    • Bad: void result(…), better: createResults.
    • Bad: void gas/oil/water, better: calculate…VolumeRate.
java naming convention
Java Naming Convention
  • Package: scope.mypackage
  • Classes: MyClass
  • Methods: myMethod
  • Constants: MY_CONSTANT
  • Attribute: myAttribute
  • Variable: myVariable
parameters
Parameters
  • Actual parameters should match the formal
  • Input-modify-output order
  • If several operations use similar parameters, put the similar parameters in a consistent order
  • Use all parameters
  • Document interface assumptions about parameters
    • access type, unit, ranges, non-valid values
  • Limit the number of parameters to about seven
comments why when where what
Comments; Why, when, where, what
  • Why: To be able to find out what a operation does after a half, one or two years. Automatic API documentation.
  • When; Document your code before or when you write it; Design before you implement. Put the design in the operation.
  • Where; Before the operation, at specific formulas, decision points etc.
  • What; Document the algorithm, avoid unnecessary comments. Refer to a specification if existing.
javadoc 1
JavaDoc (1)
  • Generates HTML-formatted class reference or API documentation.
  • Does only recognise documentation comments that appear immediately before
    • class
    • Interface
    • constructor,
    • method
    • field declaration.
javadoc 2
JavaDoc (2)
  • Purpose: To define a programmingcontract between a client and a supplier of a service.
  • Keep the documentation synchronised with the code. MAKE DOCUMENTATION FIRST, then code!
  • JavaDoc tags:
    • @author, @version, @see, @param, @return, @exception.
    • {@link}.
javadoc example class
JavaDoc Example: Class

/**

* <code> MyConstants </code> is the base class for all the constants and

* implements any general constant responsibilities.

*

* @author Carl-Fredrik Sørensen

* @version $Revision: 1.0$

* @invariants p > 0

*

* @see MySpecificConstants

*/

javadoc 3
JavaDoc (3)
  • Document pre-, post- and invariant conditions (OCL…).
    • @pre-condition, @post-condition, @invariants.
  • Document known defects and deficiencies.
    • @defect.
  • Document synchronisation semantics.
javadoc example method
JavaDoc Example: Method

/**

* Method description

*

* @param paramName Name of the mechanism to search for,

* one of the constants in the <code>MyClass</code> class.

* @return The concrete instance of an <code>MyClass</code>

* that is currently in effect if one found, null if not.

* @exception Throwable Default finalizer exception.

* @pre-condition valid paramName.

* @post-condition (… described in @return here…)

*/

architecture how to avoid spider web
Architecture; How to Avoid Spider-web
  • Class/package organisation (loose coupling, high cohesion):
    • Split classes in (package/service) layers (user, data and business). Use package scoping (no.ntnu.idi…..).
    • Uni-directional dependencies.
information hiding
Information Hiding
  • Do not expose operations that should be local to a package.
  • Hide data access from the business services.
    • Create separate packages for performing data services.
    • Define interfaces for data access, like e.g. EJB.
  • Scoping:
    • public: classes exposed by interfaces, operations in interfaces.
    • package: classes and operation not exposed through interface, but used by other classes in package.
    • private: local attributes and methods.
information hiding25
Information Hiding
  • Hide the action part in control structures (functional cohesion) if complex, else delegate to a method.
  • What to hide:
    • Areas that are likely to change; hardware dependencies, input/output, non-standard language features, difficult design and implementation areas, data-size constraints, business rules, potential changes.
    • Complex data.
    • Complex logic.
binding
Binding
  • Bind constants as late as possible
    • Do not use magic Numbers, avoid hard-coded values

totalFooDay = totalFooHour * 24;

if (me.equals(”thirsty”)) return ”water”;

    • Avoid global variables (constants OK)
    • Use separate classes/methods to hide hard-coded values
      • Achieves faster maintenance, and avoids copy-paste errors
      • Makes code better suited for reuse
      • Static methods and/or constants

MyConstants.C1_SPECIFIC_GRAVITY

java exceptions 1
Java Exceptions (1)
  • Uncheckedrun-time exception: serious unexpected errors that may indicate an error in the program’s logic Termination.
  • Checkedexception: errors that may occur, however rarely, under normal program operation  The caller must catch this exception.
java exceptions 2
Java Exceptions (2)
  • Only convert exceptions to add information. If the method does not know how to handle an exception it should not be handled.
  • Do not silently absorb a run-time or error exception makes code very hard to debug.
  • Use finally blocks to release resources.
code defensively 1
Code Defensively (1)
  • Check input data for validity (Pre-conditions).
    • Range, comment assumptions about acceptable input ranges in the code.
    • Use a general approach for error handling when erroneous data.
  • Use exception handling only to draw attention to unexpected cases (Do NOT perform any processing in exception code) (invariants).
  • Anticipate changes; Hide to minimise impact of change.
code defensively 2
Code Defensively (2)
  • Introduce debugging aids early (logging).
  • Check function return values (post-conditions).
  • Return friendly error messages; Write to a log file any system specific error messages (IO/SQL Exceptions, error codes etc.).
summary
Summary
  • Remember your code should be understandable.
  • Maintenance is often up to 70% of a total project cost.
  • Use quality control.
outline32
Outline
  • Code quality and Code Standards.
  • Debugging, logging etc.
  • Testing.
debugging
Debugging
  • Single thread/process.
    • IDE’s with debugger most often sufficient.
  • Multiple clients, threads, distributed applications.
    • Synchronisation issues to protect the state of objects.
    • IDE’s (most often) lack good support.
    • Pre-instrumentation of code is often necessary.
  • Non-visual services (e.g. Real-time data conversions).
    • May debug single runs in IDE’s.
    • Hard to debug in real settings: system runs continuously or discretely at fixed times
application logging what and why
Application Logging: What and Why?
  • An application log is a text history of notable events logged by your application.
  • The logs helps you to figure out what went wrong (and right) during the execution of your application.
  • With the advent of N-tier architectures, Servlets, JSPs, and EJBs, application logging is particularly important to report errors that cannot or should not be surfaced to the user interface.
jlog java logging framework
JLog – Java Logging Framework
  • Developed by Todd Lauinger.
  • A significant event happens in your Java code. That event could be any of several different types and conditions. Before you start using a logging framework:
    • categorize and document your events so that all users of the framework will log events consistently.
system event categories
System Event Categories
  • Levels:
    • CRITICAL_ERROR. (Highest - 1)
    • ERROR.
    • WARNING.
    • INFORMATION.
    • DETAIL.
    • TRACE. (Lowest - 6)
logging granularity
Logging Granularity
  • Agreed and documented set of event categories  determine the granularity to log those events.
  • Separate logs for e.g.
    • thread pool.
    • SQL processor.
logging events
Logging Events
  • Instrument code with logging statements:
    • AppLog.criticalError("Caught unexpected exception: " + e);
    • SQLLog.info("Executing SQL query: " + statement);
    • AppLog.trace("Entering method getName()");
  • Notice: the code does not need to have any "if" logic.
configuring the logs 1
Configuring the Logs (1)
  • Configuration from a properties file.

LogFileExtension = log

LogFilePath = c:\\temp\\

LoggingLevel = 2

LoggingMechanism = log.StandardErrLoggingMechanism

LogFieldSeparator = |

configuring the logs 2
Configuring the Logs (2)
  • You may select the output logging level. Default is the INFO level.
  • All events logged at a level less than or equal to the log's current logging level will be output to the logging mechanisms.
  • Events logged at a numerically higher level (i.e., a less critical level) will be discarded.
configuring the logs 3
Configuring the Logs (3)
  • At runtime, you can increase or decrease the logging level of any of your logs without affecting your other logs.
  • If you are trying to debug a nasty problem with your thread pool, you can programmatically change the log at runtime :

ThreadLog.getInstance().setLoggingLevel(Log.TRACE_LEVEL);

configuring the logs 4
Configuring the Logs (4)
  • Other ways to dynamically reset the logging level at runtime:
    • In a debugger, you can change the value of the log's currentLoggingLevel variable.
    • In an application server, you can examine and manipulate log properties with some JSPs.
    • Use RMI to manipulate the log properties of a remote JVM.
    • There are more options you can configure both programmatically and via a properties file.
reading the logs 1
Reading the Logs (1)
  • Sample entries from a shared log, a vertical bar ( | ), is used to delimit the various fields of log entries:

RequestLog|L4|09:32:23:769|ExecuteThread-5|Executing request number 4

SQLLog|L4|09:32:23:835|ExecuteThread-5|select * from Customer where id = 35.

RequestLog|L4|09:32:23:969|ExecuteThread-5|Request 4 took 200 milliseconds.

reading the logs 2
Reading the Logs (2)
  • Import the log into a spreadsheet:
    • ASCII text import with a vertical bar as a field delimiter.
    • Sort or filter the log using various spreadsheet capabilities.
outline46
Outline
  • Code quality and Code Standards.
  • Debugging, logging etc.
  • Testing.
testing
Testing
  • Not closely integrated with development prevents measurement of the progress of development - can't tell when something starts working or when something stops working.
  • JUnitto cheaply and incrementally build a test suite that helps to:
    • measure your progress,
    • spot unintended side effects.
    • focus your development efforts.
junit
JUnit
  • Automatic testing framework.
    • Acceptance tests.
    • Integration test.
    • Unit test.
  • Reports the number of defects graphically.
  • May create many tests for each method.
junit example
JUnit Example
  • Pay attention to the interplay of the code and the tests.
    • The style: to write a few lines of code, then a test that should run,
    • or even better: to write a test that won't run, then write the code that will make it run.
  • The program presented solves the problem of representing arithmetic with multiple currencies.
example money
Example: Money

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;    

}

}

j u nit
JUnit
  • JUnit defines how to structure your test cases and provides the tools to run them.
  • You implement a test in a subclass of TestCase.
example money52
Example: Money

public Money add(Money m) {

    return new Money(amount()+m.amount(), currency());

}

junit53
Junit
  • Define MoneyTest as a subclass of TestCase.
  • Put MoneyTest in the same package as the classes under test access to the package private methods.
    • Add method testSimpleAdd, that will exercise the simple version of Money.add() above.
    • A JUnit test method is an ordinary method without any parameters.
example moneytest
public class MoneyTest extends TestCase {    

//…    

public void testSimpleAdd() {        

Money m12CHF= new Money(12, "CHF");  // (1)

      Money m14CHF= new Money(14, "CHF");

      Money expected= new Money(26, "CHF");        

Money result= m12CHF.add(m14CHF);    // (2)

assert(expected.equals(result));     // (3)    

}

}

Example: MoneyTest
developing tests
Developing Tests

public void testEquals() {    

Money m12CHF= new Money(12, "CHF");

  Money m14CHF= new Money(14, "CHF");    

assert(!m12CHF.equals(null));

 assertEquals(m12CHF, m12CHF);

assertEquals(m12CHF, new Money(12, "CHF")); // (1)

assert(!m12CHF.equals(m14CHF));

}

developing tests56
Developing Tests

public boolean equals(Object anObject) {

if (anObject instanceof Money) {      

   Money aMoney= (Money)anObject;        

return aMoney.currency().equals(currency())

&& amount() == aMoney.amount();    

}  

  return false;

}

  • Override the method hashCode whenever you override method equals.
assertions
Assertions
  • Verification in JUnit by calling assert which is inherited from TestCase.
    • Assert triggers a failure that is logged by JUnit when the argument isn't true.
    • Since assertions for equality are very common, TestCase defines an assertEquals convenience method. Logs the printed value of the two objects if they differ.
    • Shows why a test failed in a JUnit test result report. Logged as a string representation created by toString.
test fixture
Test Fixture

public class MoneyTest extends TestCase {  

   private Money f12CHF;

private Money f14CHF;

  protected void setUp() {

     f12CHF= new Money(12, "CHF");

     f14CHF= new Money(14, "CHF");    

}

}

tests refactored
Tests Refactored

public void testEquals() {

  assert(!f12CHF.equals(null));

assertEquals(f12CHF, f12CHF);

  assertEquals(f12CHF, new Money(12, "CHF"));    

assert(!f12CHF.equals(f14CHF));

}

public void testSimpleAdd() {

  Money expected= new Money(26, "CHF");

  Money result= f12CHF.add(f14CHF);

  assert(expected.equals(result));

}

running of tests
Running of Tests
  • Two additional steps are needed to run the two test cases:
    • define how to run an individual test case,
    • define how to run a test suite.
  • JUnit supports two ways of running single tests:
    • static.
    • dynamic.
test case static
Test Case: Static
  • Overrides the runTest method inherited from TestCase and call the desired test case.
    • Convenient way:anonymous inner class.
    • Note: each test must be given a name to identify it if it fails.

TestCase test= new MoneyTest("simple add") {    

public void runTest() {

      testSimpleAdd();    

}

};

    • A template method in the super-class will make sure runTest is executed when the time comes.
  • Dynamic: TestCase test=new MoneyTest("testSimpleAdd");
test suite dynamic
Test Suite: Dynamic
  • Illustration of the creation of a test suite with the dynamic way to run a test:
    • You only pass the class with the tests to a TestSuite and it extracts the test methods automatically.

public static Test suite() { return new TestSuite(MoneyTest.class);}

test suite static
public static Test suite() {   

  TestSuite suite= new TestSuite();

  suite.addTest(new MoneyTest("money equals"){

        protected void runTest() {

testEquals();

}        

}

 );         

suite.addTest(new MoneyTest("simple add") {

        protected void runTest() {

testSimpleAdd();

}

    }    

);    

return suite;

}

Test Suite: Static
junit review 1
JUnit Review (1)
  • In general: development will go much smoother writing tests a little at a time when developing.
  • When coding the imaginationof how the code will work. Capture the thoughts in a test.
  • Test code is just like model code in working best if it is factored well.
junit review 2
JUnit Review (2)
  • Keeping old tests running is just as important as making new ones run.
  • The ideal is to always run all of your tests.
  • When you are struck by an idea, defer thinking about the implementation. First write the test. Then run it. Then work on the implementation.
testing practices 1
Testing Practices (1)
  • Martin Fowler: "Whenever you are tempted to type something into a print statement or a debugger expression, write it as a test instead.”
  • Only a fraction of the tests are actually useful.
    • Write tests that fail even though they should work, or tests that succeed even though they should fail.
    • Think of it is in cost/benefit terms. You want tests that pay you back with information.
testing practices 2
Testing Practices (2)
  • Receive a reasonable return on your testing investment:
    • During Development.
    • During Debugging.
  • Caution:
    • Once you get them running, make sure they stay running.
  • Ideally, run every test in the suite every time you change a method. Practically, the suite will soon grow too large to run all the time.
testing practices 3
Testing Practices (3)
  • Try to optimise your set-up code so you can run all the tests.
  • Or,
    • create special suites that contain all the tests that might possibly be affected by your current development.
    • run the suite every time you compile.
    • make sure you run every test at least once a day: overnight, during lunch, during one of those long meetings….
references
References
  • Code Complete; Steve McConnell, Microsoft Press.
  • The Elements of Java Style; Allan Vermeulen, SIGS Reference Library, Cambridge
  • http://www.javareport.com/
  • http://www.catapult-technologies.com/whitepapers/jlog/
  • http://www.junit.org/