In chemistry or in physics if you are making some experiments you are putting the subject in a controlled environment.
You do it because you want to avoid external complexity and side effects.

The same thing we do in software development by mocking interaction partners of the unit under test.

Software, in particularly object oriented program, is all about communication. Every method call (message passing) is a communication. You passing some arguments and receiving values or exceptions. Your behavior depends on your communication partners because your algorithm will take different paths because of the return value or a thrown exception.

So if you want to make sure that the behavior is all good, you have to control what your partners are telling you. It is a part of the test scenario and of precondition to specify what will be received by the unit under test.

Another side effect that can be checked by a controlled environment is what your unit under test is telling it’s communication partners. That could be some computed values that you can’t check after the whole algorithm is executed.

If you make a Sequence diagram of the unit you are testing you should see all the communication options you have.
There you can also see if the communication can be controlled. If the communication partner is created by the algorithm under test you have no chance to controls its output and validate call parameters that are passed to it.

In this case a field and IoC is your friend. Same thing applies to Law of Demeter. It is easier to stub / control if you Only talk to your immediate friends and not to the friends of friends because in this way you also have to control friends of friends.

Shame on me!

I disappeared for a month but now I am back with some of topic stuff.
I will continue to work on MockitoViz as soon as I can, but now I want to write about some other pet project of mine.

Pflection is a view for FDT that shows some Software development metrics for selected project, package or what ever you selected in your project/outline view.
At the moment I implemented Pflection I was not aware of Sonar, but in my opinion the two projects has also different field of use. Sonar is a CI tool, Pflection other wise is development tool. The feedback cycle of Pflection is much shorter.

So what does Pflection can?

It watches you selecting elements(multi selections enabled) in Project or Outline View and shows aggregated data about selected items. For example if you are selecting a project it will aggregate the data about all the containing elements (libraries, source folders, packages etc..)

What data (metrics) we are talking about?

Metrics can be divided in following groups:
Source Containers:
- Number of Libraries (SWC)
- … source folders
- … packages
Compilation Units (Master Elements – representing the file):
- … classes
- … interfaces
- … functions
- … variables
- … constants
- … namespaces
Nested (hidden/local) Elements:
- … classes
- … interfaces
- … functions
- … variables
- … constants
- … namespaces
Type members:
- … methods
- … static methods
- … setter
- … getter
- … field
- … constantField
- … namespace
- … metatag
Object Oriented:
- Interface implementation rate
- class inheritance depth
Dependency based:
- Number of incoming references
- Number of outgoing references
Behavior (Function) based:
- Method lines of code
- Number of conditions
- Number of blocks
- Number of flow terminations

Now I would like to talk about the last three metrics and how they can be computed.
Lets start with the simple one – number of blocks.
blocks are code statements wrapped in ‘{}’.
So by providing the number of blocks in a function we can make assumptions about horizontal and vertical distance inside the function.
FDT has also a Parser that creates AST from source code.
Block is an AST element so we just have to walk throw a function AST and count the appearance of Block Nodes.

I wrote some Scenarios to test the visitor:

Scenario: Check an empty function
Given a function:
function foo(){
}
When applying Function Analyser
Then number of blocks is '1'

It’s pretty simple to test the visitor because there is no need of binding the function. But any way if your Visitor needs a binding based computations it’s better to delegate it to another Class and mock it out for the test. This way you also end up with a better responsibility distribution.

Here is another Scenario for block computations but than let’s move on

Scenario: Check function with nested if/else condition for blocks
Given a function:
function foo():void{
	if(true){
		if(false){
		}
	}else {
	}
}
When applying Function Analyser
Then number of blocks is '4'

Next metric I would like to mention is number of conditions.
This metric show how many ways your code can be executed and how many tests (at least) you should write to have a 100% code coverage.
I implemented all three metric computations in the same visitor for a better performance and because they all have the same responsibility – count appearance of some particular AST element.
The AST elements I am interested in for condition counting are:
all sort of loops, if and case statements.
I also included a try block because the code inside a try block can have different execution flows.
Oh and last but not least condition expression.
Here is a scenario

Scenario: Check a function with nested condition expression 
Given a function:
function foo():void{
	true ? true : false ? trace("a") : trace("b")
}
When applying Function Analyser
Then number of conditions is '2'

Number of flow terminations – this metric provides you with info how many exit points your function has. The more exit points your program has, the more aspects you have to keep in mind when you are reading it.
A simple void function has only one exit point.

Scenario: Check an empty function with void type
Given a function:
function foo():void{
}
When applying Function Analyser
Then number of flow terminations is '1'

A typed function has a termination when it has a return statement

Scenario: Check a simple typed function
Given a function:
function foo():int{
	return 0;
}
When applying Function Analyser
Then number of flow terminations is '1'

A termination point can also be a continue and break statement. Those are no end points for a complete behavior, but they merge two execution flows together.
A global behavior end point is also a throw statement.

Scenario: Check a void function with throw exeption
Given a function:
function foo():void{
	if(false){
		throw new Error("foo");
	}
}
When applying Function Analyser
Then number of flow terminations is '2'

All the scenarios can be browsed in FDT-OS project on google code website
http://code.google.com/p/fdt-os/source/browse/#svn/trunk/FDTPflectionTest/src/de/bomzhi/mz/pflection/model/scenario

So if you think there are some additional scenarios/features I haven’t thought of, please try it out and post it in comments.

As we discussed earlier tests shows how the program under test should work.
JUnit test can be understood by people having some Java background. But what’s about people on your team that have no programming background but still are interested in the way the program work or even want to contribute there own expectations.

Those problems are addressed by Behavior Driven Development (BDD).
There are dozen of frameworks for BDD and they all trying to make testing more readable. In my opinion BDD Tests also improves structure of the testing itself.

The framework can be divided in two categories. One that use internal DSL and others that use external DSL. (for a few months I wrote a short post on internal DSL in ActionScript)
In my opinion the problem with internal DSL approach is that you can mix the code inside your scenario declaration and this is not a structural improvement.
When you use an external DSL for testing you have to structure your code and the copy&paste amount of source code keeps to the minimum. If you have another scenario that is pretty similar to one you already wrote you just copy the scenario and changes the parameter. You don’t have to write or duplicate any line of code.

My BDD framework of choice for MockitoViz is JBehave. It’s external DSL based and has a clear structure.

It has three main keywords for Scenario description: Given, When, Then.

If you think about how a test is structured, you see that for a test you have to create a state where the unit under test will be used. It could be the instantiation of the class you would like to test, or creation of the input if it is a complex one.

The creation of the state should be described under the keyword Given.

Given a Compilation Unit from this source code:
package foo;
public class A {
  public void bar(){
    A a = mock(A.class)
  }
} 
And a visitor to FindMockedObjects with stubbed BindingHandler
And stubbed BindingHandler witch returns 'A' as type

The And keyword can be used so you don’t have to write Given every time.

After that you want to fire up an action that will give you some output you wan’t to test. In other word’s you want to use your program under test.

This should be described under the keyword When

When the visitor have visited the AST

Now we can write done our expectations leaded with the keyword Then

Then found mocks should not be empty
And 1 mock should be found
And mocks name should be 'a' 
And mocks type should be 'A'

Let’s write some actual code that we will use for visualization.

To visualize mocked object we should collect the creation of the mocks in the class or method you are interested in.
So we need to evaluate the code to find method calls that creates mocks in Mockito framework.
The simplest way to evaluate AST is to create an ASTVisitor. AST parser will generate the AST from code but it is not the only thing that it normally does. It also binds symbols to declarations. The problem with that is that the AST parser have to be in position to look up all declarations and this is a problem if you just want to provide a snippet of code.

So any way, here is the test class for visitor witch should find creations of mocked objects.

public class TestFindMockedObjects {
 
	private Block ast;
	private BindingHandler bindingHandler;
	private List<MockedObject> foundMocks;
 
	@Test
	public void canFindMock() throws Exception {
		String javaCode = "A a = mock(A.class);";
		setup(javaCode);
		when(bindingHandler.getTypeName(Matchers.any(Type.class))).thenReturn("A");
		findMocks();
		assertThat(foundMocks.isEmpty(), is(false));
	}
 
	@Test
	public void canFindMockWithProperName() throws Exception {
		String javaCode = "A a = mock(A.class);";
		setup(javaCode);
		when(bindingHandler.getTypeName(any(Type.class))).thenReturn("A");
		findMocks();
		assertThat(foundMocks.get(0).getObjectName(), is("a"));
		assertThat(foundMocks.get(0).getTypeName(), is("A"));
	}
 
	@Test
	public void canFindMockInAssignment() throws Exception {
		String javaCode = "A a; a = mock(A.class);";
		setup(javaCode);
		when(bindingHandler.getTypeName(Matchers.any(Type.class))).thenReturn("A");
		findMocks();
		assertThat(foundMocks.isEmpty(), is(false));
	}
 
	@Test
	public void canFindMocksWithProperNamesForDeclarationAndAssignment() throws Exception {
		String javaCode = "A a1 = mock(A.class); B b2; b2 = mock(B.class);";
		setup(javaCode);
		when(bindingHandler.getTypeName(any(Type.class))).thenReturn("A");
		when(bindingHandler.getTypeName(any(Expression.class))).thenReturn("B");
		findMocks();
		assertThat(foundMocks.get(0).getObjectName(), is("a1"));
		assertThat(foundMocks.get(0).getTypeName(), is("A"));
		assertThat(foundMocks.get(1).getObjectName(), is("b2"));
		assertThat(foundMocks.get(1).getTypeName(), is("B"));
	}
 
	@Test
	public void canFindMockAlsoIfItIsASpy() throws Exception {
		String javaCode = "A a = spy(new A());";
		setup(javaCode);
		when(bindingHandler.getTypeName(Matchers.any(Type.class))).thenReturn("A");
		findMocks();
		assertThat(foundMocks.isEmpty(), is(false));
	}
 
	private void setup(String javaCode) {
		createAst(javaCode);
		prepareBindingHandler();
	}
 
	private void createAst(String javaCode) {
		ASTParser newParser = ASTParser.newParser(AST.JLS3);
		newParser.setKind(ASTParser.K_STATEMENTS);
		newParser.setSource(javaCode.toCharArray());
		ast = (Block)newParser.createAST(new NullProgressMonitor());
	}
 
	private void prepareBindingHandler(){
		bindingHandler = mock(BindingHandler.class);
	}
 
	private void findMocks() {
		FindMockedObjects finder = new FindMockedObjects();
		finder.setBindingHandler(bindingHandler);
		ast.accept(finder);
		foundMocks = finder.getFoundMocks();
	}
}

I created no @Before method because the state I am testing on is different from test to test. So I am reusing by extracting the logic in private methods and calling them in every test with different parameters. I have to copy and paste code though. This problem will be addressed in next posts.

So any way, the visitor can evaluate the AST, but we also need it to be binded because of Type name of mocked object.

	@Override
	public boolean visit(MethodInvocation node) {
		if(isMockingMethod(node)){
			VariableDeclaration variableDecl = getParent(node, VariableDeclarationFragment.class);
			if(variableDecl != null){
				String objectName = variableDecl.getName().getIdentifier();
				VariableDeclarationStatement parent = getParent(variableDecl, VariableDeclarationStatement.class);
				Type type = parent.getType();
				foundMocks.add(new MockedObject(objectName, bindingHandler.getTypeName(type)));
				return true;
			}
			Assignment assignment = getParent(node, Assignment.class);
			if(assignment!=null){
				Expression leftHandSide = assignment.getLeftHandSide();
				if(leftHandSide instanceof SimpleName){
					SimpleName name = (SimpleName)leftHandSide;
					foundMocks.add(new MockedObject(name.getIdentifier(), bindingHandler.getTypeName(leftHandSide)));
					return true;
				}
 
			}
		}
 
		return true;
	}

So I extracted the logic that is depends on AST binding and put it in an extra class that I am mocking out in Test.

...
bindingHandler = mock(BindingHandler.class);
...
FindMockedObjects finder = new FindMockedObjects();
finder.setBindingHandler(bindingHandler);
...
when(bindingHandler.getTypeName(Matchers.any(Type.class))).thenReturn("A");
...

This way I can concentrate myself on the actual AST visiting and check binding resolving.
I another test.

Now we want to check what we get from AST parser.

For this cause we need more consumers with deeper expectations.

As I will test only single behavior, it is better to put it in an setup method of the test class

        private ASTNode ast;
        ...
        @Before
	public void createAst() {
		String javaCode = "class A {}";
		ASTParser newParser = ASTParser.newParser(AST.JLS3);
		newParser.setSource(javaCode.toCharArray());
		ast = newParser.createAST(new NullProgressMonitor());
	}

The element that we get from AST parser is a compilation unit.
Compilation unit is a smallest chunk of code than can be compiled to binary.
In Eclipse AST class type hierarchy CompilationUnit is a subtype of ASTNode.

        @Test
	public void ensureThatParsedElementIsAnCompilationUnit() throws Exception {
		assertThat(ast, is(CompilationUnit.class));
	}

This looks like a simple and readable Expectation.
It also shows us that “is” Method can be used with a Class instance.

I already explained that “assertThat” uses Matchers to validate assumptions. But how does it work. The Hamcrest Tutorial is a very good place to lookup everything you need.

Any way I would like to introduce another test. It will expect the compilation unit to provide types and one of this types should be our A class.
So hear is the test:

        @Test
	public void ensureThatCompilationUnitHasTypeCalledA() throws Exception {
		CompilationUnit cu = (CompilationUnit)ast;
		List<AbstractTypeDeclaration> allTypes = cu.types();
		assertThat(allTypes, is(notNullValue()));
		assertThat(allTypes, hasItem(isTypeWithName("A")));
	}

And this test is also pretty self explaining and readable.
Here you can see the real power of Matcher. Matcher can be combined with each other and you can also provide your own matcher as I did with “isTypeName”.
So you don’t have to write code for iterating through collection, just nest two Factory Methods will do the trick.

Here is the code of the Matcher I wrote to evaluate a type declaration.

public class TypeHasName extends BaseMatcher<AbstractTypeDeclaration>{
 
	private final String name;
 
	public TypeHasName(String name) {
		this.name = name;
	}
 
	@Override
	public boolean matches(Object item) {
		AbstractTypeDeclaration type = (AbstractTypeDeclaration)item;
		return type.getName().getIdentifier().equals(name);
	}
 
	@Override
	public void describeTo(Description description) {
		description.appendText("type with name ").appendValue(name);
	}
 
	@Factory
	public static TypeHasName isTypeWithName(String typeName) {
		return new TypeHasName(typeName);
	}
}

By the way I created a Git repository for MockitoViz
http://github.com/mzaks/MockitoViz

Every post with examples will be tagged in repository.

What do we need to start a Test driven Eclipse Project.

Well, first of all we need Eclipse RCP!
Than we create two PlugIn project MockitoViz and MockitoVizTest. (It is better to create create two projects so you don’t mix productive code with test code)

I saw an opening sequence of introduction to TDD from Kent Beck on vimeo. (by the way Kent Beck is the Father of XP, TDD and JUnit) And he introduced some interesting idea to me.

Mostly if I would start with Test first approach, I would start with theoretical classes that I would create and instantiate in my test (Programming by intention style), the test will not be compilable so I will have to create this classes. So in other word you create a consumer for something that does not yet exist and it’s kind of picky because you directly making assumptions about something.

Kent Beck started to implement the logic directly in the test and then extracted it to a Class under test. So if I would transfer it to my Consumer metaphor:

Do something your self, than delegate it to somebody else and check if he doing it write.

Now back to the real implementation and why I mentioned this stuff.
I created two projects and I know that I would need “org.eclipse.jdt.core” plugin for code evaluation. So I start with a test for parsing Java Code. I add two dependencies to my test Plugin:
- already mentioned “org.eclipse.jdt.core”
- and JUnit 4.

Now I implement something like this:

package de.bomzhi.jdt.exploration;
 
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
 
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.junit.Test;
 
public class ExploreParser {
 
	@Test
	public void parseSimpleClassDeclaration() throws Exception {
		String javaCode = "class A {}";
		ASTParser newParser = ASTParser.newParser(AST.JLS3);
		newParser.setSource(javaCode.toCharArray());
		ASTNode ast = newParser.createAST(new NullProgressMonitor());
		assertThat(ast, is(notNullValue()));
	}
}

By implementing this code I see that I need another two plugins:
- “org.eclipse.core.resources” because of IProgressMonitor that is used in “createAST” method
- and “org.eclipse.core.runtime” that is used internally by ASTParser

So here you see a client that converts a string to AST (Abstract Syntax Tree) and checks if he was successful. It has no expectations about the AST it becomes. The client is just happy that AST is not null.

By the way I am using the assertThat function for checking the assumption. assertThat was introduced in JUnit 4 and is based on matchers from Hamcrest framework.
Matchers provides pretty cool DSL for assertions. The error messages are also very readable.

Never the less, in this first short cast we created a first test which learns us how to use Eclipse ASTParser.

Lately I was experimenting with code evaluation and visualization in Eclipse.

So why shouldn’t I create a code visualization PlugIn for Eclipse while discussing about Testing.

And what should I visualize?

Well I planned to use Mockito as mocking framework anyway. Wouldn’t it be great if I would create a plugin that will visualize the mocked objects?

I think it would, so let’s start…

For me to test or not to test is not a question.

As a “lightly” paranoid person I like to know if my work does what it suppose.
And how do I achieve that knowledge?
I try it out!
I become a customer of my own code.

Automatic tests has the same assignment. They use the code and they complain if this code does something they don’t expect it to do.

So by providing automatic test you provide your system with users.
And how do you understand a system?
By looking how it is used.

That means that you score two times. You satisfy you paranoia and give people information how they could use your code.

Second task could be achieved by documentation. But documents could lie. Tests become red when they do.

© 2011 Max Blog Suffusion theme by Sayontan Sinha