Test infrastructure, part 3 - Matching with Hamcrest

A word on Hamcrest, a library which integrates with JUnit to improve test readability.

When checking if two objects obj1 and obj2 are equals, the "classic" JUnit way is to write something like:

import org.junit.Test;

class Test

   @Test
   public void equalsTest(){  
  
      assertEquals(ob1, obj2);
      //is obj1 the expected or actual result ? 
      //not clear without resorting to the javadoc 
   }
}

with Hamcrest - the test reads (almost) like plain ordinary english and it is easier to see that obj1 is the actual result and obj2 is the expected result:

import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat; 
import static org.hamcrest.Matchers.is;

class Test{

   @Test
   public void equalsTest(){
      //asserts that the actual result is what's expected.
      assertThat (obj1, is(obj2));
   }
}


The above illustrates the use of the is() matcher, there are many other matchers to choose from... Just to name a few:

//hasEntry matcher
Map aMap = new HashMap ();
amap.put("test",123);
assertThat (aMap, hasEntry("test",123);

//greaterThan matcher
assertThat(stuff.size(), greaterThan(0));

//combining is and not matchers
assertThat (stuff.size(), is(not(0)))x

//assert that an array contains certain elements
String [] array1 =....;
assertThat (array1, allOf(hasItemInArray("element1"), hasItemInArray("element2")));

Test infrastructure, part 2 - randomizing data

The builder created in part 1 initialises the domain object under test with predefined values:

 id {123} and name {defaultName}

public class DomainObjectBuilder{
   private Integer id="123";
   private String name="defaultName";

   public DomainObject build(){
      return new CustomObject(id,name);
   }
   ....
}

The objects thus constructed by the builder are then used in tests. So far so good. Sometimes though we want these tests to work a little harder, and prove that they can run ok with different input values. The methods below can be used to that end, building on the RandomStringUtils and RandomUtils methods from Apache Commons.

eg. to randomise a string by adding a 2 digits to the end of it.
public String randomizedString(String aString){
   return aString+RandomStringUtils.randomAlphaNumeric(2);
}
and the builder becomes (assuming the randomizedString method is statically imported)
public class DomainObjectBuilder{
   private Integer id=randomizedString("123");
   private String name=randomizedString("defaultName");

   public DomainObject build(){
      return new CustomObject(id,name);
   }
   ....
}
Each invocation of the DomainOBjectBuilder.build() method will now return domain objects with slightly different values. Of course it's not only strings which can be randomized. The same principles applies to enums:
public static <T extends Enum> T randomizedEnum (class <T> enumClass){
   T[] enumConstants = enumClass.getEnumConstants();
  return enumConstants[RandomUtils.nextInt(enumConstants.length);
}
... and to lists.
public static <T>  T randomElementFromList(List aList){
   return aList.get(RandomUtils.nextInt(aList.size()));   
}

Test infrastructure, part 1 - building the builders

The basic brick of a test infrastructure is the ability to easily instantiate and set properties on the domain object under test. This can be achieved with a builder object, as per below. This builder exposes a fluent interface (in the chaining of methods withId and withName) to improve readibility.


Given a domain object such as

public class DomainObject{

   public DomainObject (Integer id, String name){
     this.id = id;
     this.name = name;
   }

   public Object doSomething(){
      ...
   }
}

then the associate builder will be:
public class DomainObjectBuilder{
   private Integer id="123";
   private String name="defaultName";

   public DomainObject build(){
      return new CustomObject(id,name);
   }

   public DomainObjectBuilder withId(Integer anId){
      this.id = anId;
      return this;
   }

   public DomainObjectBuilder withName(String name){
      this.name = name;
      return name;
   }
}
and a test for a DomainObject will look like:

DomainObject anObject = new DomainObjectBuilder()
.withId("345").withName("someTest").build();
assertThat (anObject.doSomething, is(anExpectedResult));

An alternative approach would be to do without a builder and simply add setters on the domain object, setters which would be invoked during the tests. The major drawback of this technique is that adding setters breaks immutability.

Why I (finally) moved from Eclipse to Intellij



I had to keep both Eclipse and Intellij running side-by-side for a while, because I could not peel away from Eclipse, my editor of choice for years. A few days later and Intellij has eclipsed Eclipse (pardon the pun). Here' s a few reasons why:


- I't s easy to switch between implementation and test (CTRL+shift+T) in Intellij, there's no equivalent in Eclipse.

- When searching for the usages of a variable/method/class Intellij scopes the search by test files, production files (or both).  In Eclipse you would have to manually specify the full path to search in each case.

- In general Intellij is pretty smart when it comes to refactoring. for instance when renaming a class attribute  the name of the getter method for that class attribute will  be renamed accordingly. 

- Smart code completion: Intellij will make much better suggestions as to what expression type is expected based on the context than Eclipse.

- automatically resolution of import static.
  
- Paste from history

- Use regex in search

- On the downside Intellij is a tad slower than Eclipse and tends to lock up for 30 secs or so once or twice a day.

So overall there's no major functionality or killer feature offered by Intellij that Eclipse cannot replicate. But the difference is in the many little details which are often better thought out in Intellij, resulting in a better experience (and increased productivity).


Regexp use for text transformation with Intellij

Given a snippet of code such as:
put("item123", x);
put("item456", x);
....
put("item888", x);


                
To retrieve the content in between quotes:
item123
item456
...
item888


Then this can be achieved using the in-place find and replace functionality offered by Intellij.
(obviously a manual edit would also work, but might not be as efficient if the block of code is repeated 1000 times).


1. search for the regex put\("


2. replace the selection with an empty field, this yields:

item123", x);
item456", x);
....
item888", x);


3. search for the regex \".+  (select everything extending from the first quote to the end of the line)


4.replace the selection with an empty string yields: 

item123
item456
....
item888

GC Tuning: NewRatio

When it comes to garbage collection tuning the first setting to be adjusted is often the heap size. This is not always the optimal choice though. If only because a bigger heap size will tend to mechanically lengthen the duration of GC pauses.

Instead of increasing the heap size it can pay to increase the size of the young generation relative to the old. That's where the NewRatio setting (i.e  ratio of the old gen space to the young gen space) comes in.

The screenshots below illustrate how GC activity differs when an application producing short-lived objects at a high frequency runs with NewRatio=2 and when it runs with NewRatio=1. Collections in the old gen disappear provided there's enough size in the young space to accomodate all the short lived objects.


NewRatio =2 (default setting on Windows 64 bits).





NewRatio =1


How to measure swap usage on Linux


On Linux (since version 2.6.14):

1- find out the pid of a process  
2- navigate to /proc/pid
3- edit the smaps file, and sum the swap value for each of the process mappings.

... or use the script found here to get the swap usage for each running process. The display below has been obtained by running that script on a Ubuntu guest OS (using Virtualbox on Windows) with base memory set at 128M.
















 All swaps values in kilobytes.