Apr 18 2011

iPhone Unit Test tips: Read a file in your test

Category: bdd,objective-cgiordano scalzo @ 12:44 pm

Very often I need to unit test something read from a file, but it seems very difficult to accomplish this simple task in iOS, so usually I give up.
But today I felt was a good day to find a solution ;-)
In my code I want to read a JSon data from a file, so I wrote a simple test:

describe(@"Conference", ^{
    it(@"loads given a filename", ^{
        Conference *conference = [[Conference alloc]initWithFile:@"talks_with_three_tracks"];
        [[theValue([conference hasData]) should] beTrue];
    });
});

with a simple init method:

-(id)initWithFile:(NSString *)filename{
    if ((self = [super init])) {
        NSString* path = [[NSBundle mainBundle] pathForResource:filename ofType:@"json"];
        NSError *error;
        NSString* talksString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
        talks = [talksString JSONValue];
    }
    return self;
}

-(BOOL)hasData{
    return talks!=nil;
}

Unfortunately it doesn’t work :-( , because path is nil;
But here it isthe solution:
instead of using [NSBundle mainBundle], we should use the bundle associated with our class:

        NSString *path = [[NSBundle bundleForClass:[Conference class]] pathForResource:filename ofType:@"json"];

Simple and neat: thank you StackOverflow ;-)

Technorati Tags: , ,

Tags: , ,


Oct 21 2009

No more excuses: junit testing log messages

Category: java,tutorialgiordano scalzo @ 7:46 pm

Althought I’m a straight adept of Tdd, sometime I can’t resist the temptation to write some production code without a test, above all if I have to implement some cross cutting behaviours, as could be logging .

In project I worked on lately, a request was to manage some bad situations logging something at error level and go process next item; the temptation to implement it and check running the program was very appeliling, but my green wrist band and RailsConf 09 keynote by Uncle Bob I watched recentely, helped me resist.
So I started searching, tried somenthing, and, finally, I came up with a neat solution.

Given this simple object

package biz.scalzo.prod;

import org.apache.log4j.Logger;

public class LoggingObject {
	private static Logger log = Logger.getLogger(LoggingObject.class);

	public void starts() {
		log.info("I'm starting");
	}
}

we want to test if it writes log.
To achieve this, we can use a simple custom appender, that records all messages in a list:

package biz.scalzo.test;

import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.LoggingEvent;

public class RecordingAppender extends AppenderSkeleton {
	private static List<String> messages = new ArrayList<String>();
	private static RecordingAppender appender = new RecordingAppender();

	private RecordingAppender() {
		super();
	}

	public static RecordingAppender appender(PatternLayout patternLayout) {
		appender.setLayout(patternLayout);
		appender.clear();
		return appender;
	}

	protected void append(LoggingEvent event) {
		messages.add(layout.format(event));
	}

	public void close() {
	}

	public boolean requiresLayout() {
		return true;
	}

	public static String[] messages() {
		return (String[]) messages.toArray(new String[messages.size()]);
	}

	private void clear() {
		messages.clear();
	}
}

With that, writing our test is a piece of cake:

package biz.scalzo.test;

import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;

import biz.scalzo.prod.LoggingObject;

public class ALoggingObject {

	private LoggingObject loggingObj;

	@Before
	public void setUp() {
		loggingObj = new LoggingObject();
		configureLog();
	}

	private boolean logContains(String expected) {
		String actual[] = RecordingAppender.messages();
		for (String log : actual) {
			if (log.contains(expected))
				return true;
		}
		return false;
	}

	private void configureLog() {
		Logger rootLogger = Logger.getRootLogger();
		rootLogger.removeAllAppenders();
		rootLogger.setLevel(Level.INFO);
		rootLogger.addAppender(new ConsoleAppender(new PatternLayout(
				"%d [%t] %-5p %c{1} - %m%n")));
		rootLogger.addAppender(RecordingAppender.appender(new PatternLayout(
				"%-5p - %m%n")));
	}

	@Test
	public void shouldLogWhenStarts() {
		loggingObj.starts();
		assertTrue(logContains("I'm starting"));
	}

}

Neat, simple and clear: no more excuses to not test logging!

Technorati Tags: , ,

Tags: , ,


Sep 09 2009

Infinitest: an autotest for Eclipse

Category: agile,bdd,javagiordano scalzo @ 7:00 pm

In my experimental trips in Ruby world, other than the elegance of the language, the Bdd as default and the lot of new exciting things created by the community, a thing I liked a lot was autotest , a little gem that launches our testsuite when we change a source file.
It could seem a silly utility, but I can assure it’s a really time saver and can take us in a high productive mental flow: I really missed it in Java world.

Of course, I’ve heard about Junit Max, the Kent Beck’s attempt to create a product, but my laziness delayed me to try it, until Kent got bored and dismiss the project :-( .

Today while reading distractedly the Twitterverse, I bumped into Infinitest, that seems exactly what I was looking for.
Infinitest isn’t open source, but for personal use it should be possible get a free of charge individual license.

The installation is straightforward as usual, just add http://update.improvingworks.com to Eclipse’s software updates, and we are ready to start!

Infinitest stay in the right bottom of Eclipse, waiting far some changes:

waiting for changes

When we save some file Infinitest starts and show the results of all test it founds in the project:

red test

A nice feature is the yellow bar when there is some error in the workspace and tests can’t run:

yellow bar

That’s all!
I have to try it more, but it seems very promising and useful.

Technorati Tags: , , , ,

Tags: , , , ,