Tuesday, May 13, 2008

Luntbuild : Installation

This is the second part of the little notes about Luntbuild. This gives some basic installation steps of Luntbuild. For an introduction on Luntbuild refer this post.
  1. Using zip distribution (without GUI), in Linux
  2. Using Luntbuild installer (with GUI), in Linux
  3. Using Luntbuild installer (with GUI), in Windows
via: http://thetalkouttrojans.blogspot.com/2008/05/luntbuild-installation.html

Tuesday, May 6, 2008

Luntbuild : Introduction

Luntbuild is a powerful build automation and management tool. Continuous Integration or nightly builds can be easily set using a clean web interface. Executed builds are well managed using functions such as search, categorization, promotion, patching, deletion, etc. It also acts as a central build artifacts repository and download area for your whole team.

Sunday, April 27, 2008

JUnit

Ref:

What is JUnit?

JUnit is a simple, open source framework 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 runners for running tests

When should tests be written?

Tests should be written before the code. Test-first programming is practiced by only writing new code when an automated test is failing.

Good tests tell you how to best design the system for its intended use. They effectively communicate in an executable format how to use the software. They also prevent tendencies to over-build the system based on speculation. When all the tests pass, you know you're done!

Whenever a customer test fails or a bug is reported, first write the necessary unit test(s) to expose the bug(s), then fix them. This makes it almost impossible for that particular bug to resurface later.

Test-driven development is a lot more fun than writing tests after the code seems to be working. Give it a try!

Basic test template

import org.junit.*;
import static org.junit.Assert.*;

public class SampleTest {

private java.util.List emptyList;

/**
* Sets up the test fixture.
* (Called before every test case method.)
*/
@Before
public void setUp() {
emptyList = new java.util.ArrayList();
}

/**
* Tears down the test fixture.
* (Called after every test case method.)
*/
@After
public void tearDown() {
emptyList = null;
}

@Test
public void testSomeBehavior() {
assertEquals("Empty list should have 0 elements", 0, emptyList.size());
}

@Test(expected=IndexOutOfBoundsException.class)
public void testForException() {
Object o = emptyList.get(0);
}
}

Handling Exception

* How test that passes when an expected exception is thrown?

Add the optional expected attribute to the @Test annotation. The following is an example test that passes when the expected IndexOutOfBoundsException is raised:

    @Test(expected=IndexOutOfBoundsException.class)
public void testIndexOutOfBoundsException() {
ArrayList emptyList = new ArrayList();
Object o = emptyList.get(0);
}

* How test that fails when an unexpected exception is thrown?

Declare the exception in the throws clause of the test method and don't catch the exception within the test method. Uncaught exceptions will cause the test to fail with an error.

The following is an example test that fails when the IndexOutOfBoundsException is raised:

    @Test
public void testIndexOutOfBoundsExceptionNotRaised()
throws IndexOutOfBoundsException {

ArrayList emptyList = new ArrayList();
Object o = emptyList.get(0);
}

Assertion Statement Reference

This is a list of the different types of assertion statements that are used to test your code. Any Java data type or object can be used in the statement. These assertions are taken from the JUnit API.

  • assertEquals(expected, actual)
  • assertEquals(message, expected, actual)
  • assertEquals(expected, actual, delta) - used on doubles or floats, where delta is the difference in precision
  • assertEquals(message, expected, actual, delta) - used on doubles or floats, where delta is the difference in precision
  • assertFalse(condition)
  • assertFalse(message, condition)
  • assertNotNull(object)
  • assertNotNull(message, object)
  • assertNotSame(expected, actual)
  • assertNotSame(message, expected, actual)
  • assertNull(object)
  • assertNull(message, object)
  • assertSame(expected, actual)
  • assertSame(message, expected, actual)
  • assertTrue(condition)
  • assertTrue(message, condition)
  • fail()
  • fail(message)
  • failNotEquals(message, expected, actual)
  • failNotSame(message, expected, actual)
  • failSame(message)

Ref:

Pre and Post condition

  • A pre-condition is an expression of type Boolean that should always hold before the execution of the body of the method,conditions for each function that must be true for it to behave correctly
  • A post-condition is an expression of type Boolean that should always hold after the execution of the body of the method,conditional expressions that must be true when a method returns
  • The strategy is to construct a JUnit test case for each accessible method in the class under test, where each test case verifies both the preconditions and postconditions of the method. Example
    public class RangeTest extends TestCase {  
    private Range mRange;
    public RangeTest(String name) {
    super(name);
    }

    protected void setUp() throws Exception {
    super.setUp();
    mRange = new Range(1, 5);
    }

    public void testConstructor() {
    // pre: aLower < aUpper
    try {
    new Range(6, 4);
    fail("[6,4] should be precluded");
    }
    catch (AssertionError e) { }
    // pre: aLower == aUpper new Range(-3, -3);
    // post: aLower == getLower()
    Assert.assertEquals("[1,5].getLower() should be 1", 1,
    mRange.getLower());
    // post: aUpper == getUpper()
    Assert.assertEquals("[1,5].getUpper() should be 5", 5,
    mRange.getUpper());
    }

    public void testGetLower() {
    // pre: object constructed
    Assert.assertNotNull("[1,5] could not be constructed", mRange);
    // post: getLower() == aLower provided to c'tor
    Assert.assertEquals("[1,5].getLower() should be 1", 1,
    mRange.getLower());
    }

    public void testGetUpper() {
    // pre: object constructed
    Assert.assertNotNull("[1,5] could not be constructed",
    mRange);
    // post: getUpper() == aUpper provided to c'tor
    Assert.assertEquals("[1,5].getUpper() should be 5", 5,
    mRange.getUpper());
    }

    public void testIntersects() {
    // pre: anOther != null
    try {
    mRange.intersects(null);
    fail("intersects(null) should be precluded");
    }
    catch (AssertionError e) { }
    // post: true if two ranges have an integer in common
    Assert.assertTrue(!mRange.intersects(new Range(-3, -1)));
    Assert.assertTrue(!mRange.intersects(new Range(6, 7)));
    Assert.assertTrue(!mRange.intersects(new Range(-2, 1)));
    Assert.assertTrue(!mRange.intersects(new Range(5, 7)));
    Assert.assertTrue(mRange.intersects(new Range(0, 2)));
    Assert.assertTrue(mRange.intersects(new Range(3, 4)));
    Assert.assertTrue(mRange.intersects(new Range(4, 8)));
    }}

  • If these test cases pass, then we can be confident that all methods in Range are:
  • Checking for violation of their preconditions (and objecting by throwing a Runtime exception of some sort)
  • Adhering to their postconditions.

Ref: http://www.hacknot.info/hacknot/action/showEntry?eid=17

Monday, April 7, 2008

Renaming a MySQL database

MySQL does not support renaming a database (and prefers not to be done in the supported versions) as mentioned here.

However, use of this statement could result in loss of database contents, which is why it was removed. Do not use RENAME DATABASE in earlier versions in which it is present.
  • But there might be times when you want to do this, and the simple workaround I use is this.
  • Just export the current database. You can use mysqldump or any other GUI tool like HeidiSQL or phpMyAdmin.
  • The dump typically contains SQL statements to create the table, populate it, or both.
  • Then create a database with the name you want, the new database.
  • Then just mysqlimport the exported SQL file to the new database you just created.
  • Final step would be to drop the old database.
Also note,
If you are doing a backup on the server and your tables all are MyISAM tables, consider using the mysqlhotcopy instead because it can accomplish faster backups and faster restores.
 
This is not big deal and just a matter of simple workaround, thats all. So I'm sure there is no way one could get doubts on this. Still if you get any I might be able to give a hand. Feedback and questions are welcome via comment or you can email me at talkout AT SPAMFREE gmail DOT com

 

Sunday, March 23, 2008

Ant: Simple JUnit Test

This is the final part of the so called Ant series I have been writing in this blog, about Apache Ant. This is an extremely brief tutorial on JUnit. The goal is to test Ant and JUnit framework integration .

The previous posts on Ant can be found here:

  1. Apache Ant
  2. Ant: Installation
  3. Ant: Hello World in Ant
  4. Ant: Java Hello World in Ant
  5. Ant: Java Swing Hello World in Ant

Prerequisites

In order to do this we will need to have a Java compiler, Ant, and JUnit installed.

Java Classes

First, we need a Java class to test. I had to make this example too simple according to my Java knowledge. This lacks any Java Docs or comments, but it's a pretty simple bit of code. :)

public class Math {
static public int add(int a, int b) {
return a + b;
}

static public int multiply ( int a, int b) {
return a * b;
}
}

Then to test this code, we need a second Java class that will

  1. import junit.framework.*
  2. extend TestCase

There are two important points to note in the sample. First, the routine is named testAdd. This convention tells that the routine is supposed to be a test and that it's targeting the add functionality. Here's the matching example.

import junit.framework.*;

public class TestMath extends TestCase {

protected void setUp() {
// put common setup code in here
}

protected void tearDown() {
// put common cleanup code in here



}

public void testAdd() {
int num1 = 3;
int num2 = 2;
int total = 5;
int sum = 0;
sum = Math.add(num1, num2);
assertEquals(sum, total);
}

public void testMulitply() {



int num1 = 3;
int num2 = 7;
int total = 21;
int sum = 0;
sum = Math.multiply(num1, num2);
assertEquals("Problem with multiply", sum, total);

num1 = 5;
num2 = 4;



total = 20;
sum = Math.multiply(num1, num2);
assertEquals("Problem with multiply", sum, total);
}
}

And both these files could be kept in a sub-folder named src

Ant Script

The last step is how to run your JUnit tests using Ant. Create a file called build.xml and place it in the main folder. The core of this scripts is the following, which does the JUnit tests.

<junit printsummary="yes" haltonfailure="yes" showoutput="yes" >
<classpath>
<pathelement path="${build}"/>
<fileset dir="lib">



<include name="**/*.jar"/>
</fileset>
</classpath>
<batchtest fork="yes" todir="${reports}/raw/">
<formatter type="xml"/>
<fileset dir="${src}">



<include name="**/*Test*.java"/>
</fileset>
</batchtest>
</junit>

The file I used is this one. (The inner details of this scripts are Ant Scripting and XML, which is not explained in this document, but really straightforward to understand)

Output

Run ant test in command line:

[root@nimal junit-sample]# ant test
Buildfile: build.xml

init:

compile:
[javac] Compiling 2 source files to /opt/junit-sample/bin

run-tests:
[junit] Running TestMath

[junit] Tests run: 2, Failures: 0, Errors: 0, Time elapsed: 0.321 sec

test:
[junitreport] Processing /opt/junit-sample/reports/TESTS-TestSuites.xml to /tmp/null1227203872
[junitreport] Loading stylesheet jar:file:/usr/local/ant/lib/ant-junit.jar!/org/apache/tools/ant



/taskdefs/optional/junit/xsl/junit-frames.xsl
[junitreport] Transform time: 1714ms
[junitreport] Deleting: /tmp/null1227203872

BUILD SUCCESSFUL
Total time: 6 seconds

Ant will also do nice things like create nice HTML reports! I've linked to a simple Ant script that will compile all the code in your "src" folder, run all the tests named "test*" and then create an HTML report in your "reports\html" folder.

I've linked to a zip file (ant-junit-sample.zip) that contains the build.xml file, the source code and the test class. (If you try to run it and get errors about JUnit not being found, remember to add that junit.jar to your Ant lib folder.)

Attachments


Thursday, March 6, 2008

Ant: Java Swing Hello World in Ant

This is the fourth part of the so called Ant series I have been writing in this blog, about Apache Ant. This post is mainly about building and running a Java Swing program using Ant.

The previous posts on Ant can be found here:

   1. Apache Ant
   2. Ant: Installation
   3. Ant: Hello World in Ant

   4. Ant: Java Hello World in Ant

Java Swing Program

Create the following simple swing program and save it as HelloWorldSwing.java in a sub folder src:

import javax.swing.JFrame;
import javax.swing.JLabel;

public class HelloWorldSwing {
public static void main(String[] args) {
JFrame frame = new JFrame("HelloWorldSwing"); final JLabel label = new JLabel("Hello World");
frame.getContentPane().add(label);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true); }
}

Ant Script

Use a text editor to create a file called build.xml and place it in the main folder:

<?xml version="1.0" encoding="UTF-8"?>
<project name="Run Test" default="run" basedir=".">

<target name="clean"> <delete dir="build"/>
</target>

<target name="compile" depends="clean">
<mkdir dir="build/classes"/>
<javac srcdir="src" destdir="build/classes"/> </target>

<target name="jar" depends="compile">
<mkdir dir="build/jar"/>
<jar destfile="build/jar/HelloWorldSwing.jar" basedir="build/classes"> <manifest>
<attribute name="Main-Class" value="HelloWorldSwing"/>
</manifest>
</jar>
</target>

<target name="run" depends="jar"> <java jar="build/jar/HelloWorldSwing.jar" fork="true"/>
</target>

</project>

Outputs and Problems

When we run this is text mode it, it compiles but fails to run. But when in GUI it runs.

[root@sanjaya-vm ant-swing]# ant
Buildfile: build.xml

clean:
[delete] Deleting directory /opt/ant-swing/build

compile:
[mkdir] Created dir: /opt/ant-swing/build/classes
[javac] Warning: HelloWorldSwing.java modified in the future.
[javac] Compiling 1 source file to /opt/ant-swing/build/classes

jar:
[mkdir] Created dir: /opt/ant-swing/build/jar
[jar] Building jar: /opt/ant-swing/build/jar/HelloWorldSwing.jar

run:
[java] Exception in thread "main" java.awt.HeadlessException:
[java] No X11 DISPLAY variable was set, but this program performed an operation which requires it.
[java] at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:159)
...
...
 [java] at java.awt.Window.<init>(Window.java:406)
[java] at java.awt.Frame.<init>(Frame.java:402)
[java] at javax.swing.JFrame.<init>(JFrame.java:207)
[java] at HelloWorldSwing.main(Unknown Source) [java] Java Result: 1

BUILD SUCCESSFUL
Total time: 3 seconds
This is one another basic level post and I strongly advice you to refer to any more advanced document, if you are going to do this for any production system. :)

Feedback and questions are welcome via comment or you can email me at talkout AT SPAMFREE gmail DOT com
 
 

Wednesday, February 27, 2008

Ant: Java Hello World in Ant

This is the third part of the so called Ant series I have been writing in this blog, about Apache Ant. This post is mainly about building and running a Java program using Ant. In the example I'm using here, its a Hello World program in simple Java, but most of these basic Ant steps would be same for any other Java program you might run.

The previous posts on Ant can be found here:
  1. Apache Ant
  2. Ant: Installation
  3. Ant: Hello World in Ant

Java Program

Create the following simple program and save it as HelloWorld.java in a sub folder src:

public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}

Ant Script

Use a text editor to create a file called build.xml and place it in the main folder:

<?xml version="1.0" encoding="UTF-8"?>
<project name="Run Test" default="run" basedir=".">

<target name="clean"> <delete dir="build"/>
</target>

<target name="compile" depends="clean">
<mkdir dir="build/classes"/>
<javac srcdir="src" destdir="build/classes"/> </target>

<target name="jar" depends="compile">
<mkdir dir="build/jar"/>
<jar destfile="build/jar/HelloWorld.jar"
basedir="build/classes"> <manifest>
<attribute name="Main-Class" value="HelloWorld"/>
</manifest>
</jar>
</target>

<target name="run" depends="jar"> <java jar="build/jar/HelloWorld.jar" fork="true"/>
</target>

</project>

Output

Run ant in command line:

[root@nimal ant-hw]# ant
Buildfile: build.xml

clean:
[delete] Deleting directory /opt/ant-hw/build

compile:
[mkdir] Created dir: /opt/ant-hw/build/classes
[javac] Warning: HelloWorld.java modified in the future. [javac] Compiling 1 source file to /opt/ant-hw/build/classes

jar:
[mkdir] Created dir: /opt/ant-hw/build/jar
[jar] Building jar: /opt/ant-hw/build/jar/HelloWorld.jar

run:
[java] Hello World
BUILD SUCCESSFUL
Total time: 4 seconds

Enhance the build file

Now we have a working buildfile we could do some enhancements: many time you are referencing the same directories, main-class and jar-name are hard coded, and while invocation you have to remember the right order of build steps.

<project name="HelloWorld" basedir="." default="main">

<property name="src.dir" value="src"/>
<property name="build.dir" value="build"/>
<property name="classes.dir" value="${build.dir}/classes"/>
<property name="jar.dir" value="${build.dir}/jar"/>
<property name="main-class" value="HelloWorld"/>
<target name="clean">
<delete dir="${build.dir}"/>
</target>

<target name="compile">
<mkdir dir="${classes.dir}"/> <javac srcdir="${src.dir}" destdir="${classes.dir}"/>
</target>

<target name="jar" depends="compile">
<mkdir dir="${jar.dir}"/>
<jar destfile="${jar.dir}/${ant.project.name}.jar"
basedir="${classes.dir}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/> </manifest>
</jar>
</target>

<target name="run" depends="jar">
<java jar="${jar.dir}/${ant.project.name}.jar" fork="true"/> </target>

<target name="clean-build" depends="clean,jar"/>

<target name="main" depends="clean,run"/>

</project>
Feedback and questions are welcome via comment or you can email me at talkout AT SPAMFREE gmail DOT com