Making Good Software

A blog by Alberto G (Alberto Gutierrez)

Archive for November, 2009

Continuous integration, going beyond continuous compilation.

with 5 comments

Continuous integration is in my opinion the most important practice to successfully deliver good software. Continuous integration should go beyond a simple set of practices and tools to build your source code every now and then; doing so is continuous compilation, not continuous integration.

Continuous integration should drive the way the software gets build and how the different actors from the project interact with each other.

The five main characteristics of continuous integration

In my opinion these following five characteristics are the main characteristics of an effective continuous integration.

1.- QA and development work together.

Having QA and development working together mainly means two things:

  1. There are no handovers between development and testing. Coding and testing are not two separate processes, they are performed in parallel, and one can’t be completed without the other one and vice versa.
  2. Developers and Testers have a common goal, they don’t perform different activities, developers are not just focused on developing and testers in testing. They share a common goal, produce quality software in coordination with the product owner expectations.

2.- QA act as a business representative for the developers.

The integration with the business requirements is critical to successfully develop quality software, failing to do so can have catastrophic consequences. QA should take special care special of the integration with the business requirements, they should make sure at every time that all the tests and developments are aligned with the business requirements.

3.- The build is the most important asset in a software development.

The build is the image of all the previous activities; it contains the software which is already been developed.

  1. The build should never be broken
  2. If the build breaks, fixing the build is everyone’s top priority

4.- Continuous feedback and inspection.

Knowing at every time what is the status of the project is also critical, there are a few things to be considered:

  1. Automatically check the build every time someone checks code in.
  2. Run full regression tests every few hours.
  3. Every time a build runs, automatically generate reports including, code coverage, code quality metrics, new lines of code…

5.- Communication is king

Everything is about communication, developers talking to testers and business, and testers doing the same. An important rule of thumb for communication is called “power of three”, in every single important discussion there should be at least, a developer, a tester and a representative from the business, if all the rest works, but communication doesn’t, the project is doomed to fail.

Top recommended actions to improve your continuous integration.

1. For every story, first, do a high level design of what needs to be tested. Prepare this design with QA, development and the product owner. Drive your development with that test design.

2. Only consider two states for your stories: “in process” or “completed”. Don’t use intermediary states as “in QA” or “60% completed”. If you do so you will never have QA and development working together, but against each other.

3. Have testers pairing with developers every now and them. This will enhance the communication between them, and will help to understand what needs to be tested.

4. Make QA people work very close with the product owner. Make sure they keep him well informed of what is going on in the sprint and show him if possible any progress in the stories.

5. Make developers responsible for breaking the build. Developers should perform two steps before committing any code:

  1. Update all source code.
  2. Build locally the whole application. (If the complete build takes too much time, split it and make the developers run all the unit tests before committing any code).

6. Make your CI continuous integration server to run the build every time someone checks in any code into your CSM. This will make sure that no one checks in broken code.

7. Run full regression tests as many times as possible during the day. All your tests should be automated, hook them if with the build which gets trigger when anyone commits code, if they take too much time, schedule them to run as many times during the day as possible.

8. Add a few visual devices in the office to tell when the build is broken. There are many visual devices that can be configured with almost any continuous integration server, place them in the office strategically, so whenever they turn on, everyone will realize that the build is broken, some examples of this devices are: traffic lights, a red light, a lava lamp…

9. Include an inspection report for every build. In modern continuous integration servers is easy to add different plug-ins so for each build you can obtain additional information, as test code coverage, compliance with coding standards, lines of code duplicated…

Written by Alberto Gutierrez

November 29th, 2009 at 3:19 pm

TDD is not about testing!!!

with 12 comments

Lots of people confuse “test first methodologies” with TDD, it is very common to listen comments like “TDD is just about writing your tests first”, which are completely wrong, these kind of affirmations are not describing TDD at all, they are talking about test first development.

The main reason for confusing TDD and test first development is its own name: “test driven development”. If someone that doesn’t know about TDD would had to guess based on the name what TDD is, would probably guess that is just a test first methodology. But is not!

TDD as invented by Kent Beck, (who also invented Xtreme programming and Junit), goes beyond that. In the core of TDD there is a process to follow, which makes it already different from a simple test first approach.

Test-driven_development

Image source: Wikipedia

This is also known as red (make your test fail), green (make it pass) and refactor . Where this may be seen as a small difference from a test first approach, if combined with some other agile engineering practices and development philosophies, makes TDD quite different from any other test first approach, it actually switches the focus from testing to design.

TDD is a design practice, is more related with emergent design than with testing. TDD looses much of its potential if it is not combined with other agile engineering practices, or agile philosophies as YAGNI and KISS, in TDD having a large set of tests is a nice side effect, not just its purpose.

To know if you are doing TDD the right way, look at your code, TDD code should look simple and lean, TDD also usually generates more testing code than production code, and you should feel that it helps you to design your code.

So, next time you say you are doing TDD make sure you don’t mean that you are doing test first development.

Written by Alberto Gutierrez

November 21st, 2009 at 12:01 pm

How to create services in Java

with 6 comments

Creating services is quite an abstract subject, everyone has his own ideas and preconceptions, so is worth clarifying what I mean by services in this article. A service is a component that holds some business logic which can be easily reused anywhere else in the application no matter where the service is located, or what the communication mechanism is used between the client and the service. The following code samples detail my own personal approach on how to implement services in Java.

First thing is to design the service itself through its interface

public interface ServiceA {
	public void doThis();
	public void doThat();
}

Next step is writing the implementation of the service. Is also important to remind that the implementation should just read business logic, it shouldn’t be aware of if is going to be called through a web service, jms…

public class ServiceAImp implements ServiceA{

	protected ServiceAImp (){};

	@Override
	public void doThat() {
		System.out.println("do that");
	}

	@Override
	public void doThis() {
		System.out.println("do this");
	}

}

Now it comes the tricky part, I like to make the services look as if they were local to whoever is using them, it makes them easier to use and because the communication code is hidden and doesn’t need to be written every time a service is invoked they are also less prone to bugs. For this purpose I like to use the proxy pattern.

public class ServiceAProxy implements ServiceA {
	ServiceA implementation;

	protected ServiceAProxy(ServiceA imp) {
		this.implementation = imp;
	}

	public void doThat() {
		implementation.doThat();
	}

	public void doThis() {
		implementation.doThis();
	}
}

Next thing is to deal with the communication issue, now we have a proxy that makes the service look as local to the client, but there isn’t an implementation of a communication mechanism between the client and the service, to do so, we create as many different “stubs” as communication mechanisms we want to implement. For this example, we are going to support a remote WebService call, and a remote JMS call.

The WebService stub.

public class ServiceAWebServiceClient implements ServiceA{
	ServiceA webService;
	public ServiceAWebServiceClient() {
		//webService = code to get the reference to Service A from the webservice call
	}

	@Override
	public void doThat() {
		webService.doThat();
	}

	@Override
	public void doThis() {
		webService.doThis();
	}
}

The WebService implementation could be something like:

@WebService
public class ServiceAWebService implements ServiceA{
	ServiceA imp = new ServiceAImp();

	@Override
	public void doThat() {
		imp.doThat();
	}

	@Override
	public void doThis() {
		imp.doThis();
	}
}

The JMS stub

public class ServiceAJmsClient implements ServiceA{
	ServiceA jmsObject;

	public ServiceAJmsClient() {
		//jmsObject = code to get the reference to Service A from the jms call
	}

	@Override
	public void doThat() {
		jmsObject.doThat();
	}

	@Override
	public void doThis() {
		jmsObject.doThis();
	}
}

Now the service is almost ready, everything is kept separated so changes to the business logic are only done in the ServiceAImp, and changes to the actual transportation mechanism are implemented in their own stub, also we provide with a proxy so that whoever is using the service will use it transparently, the only problem left we have, which is a big one, is that this is quite a collection of classes we are asking our clients to understand in order to use our service, to fix this, I like to use a factory.

public class ServiceAFactory {
	private ServiceAFactory() {}

	public static ServiceA getLocalService(){
		return new ServiceAImp ();
	}

	public static ServiceA getRemoteServiceUsingJms(){
		return new ServiceAProxy (new ServiceAJmsClient());
	}

	public static ServiceA getRemoteServiceUsingWebService(){
		return new ServiceAProxy (new ServiceAWebServiceClient());
	}
}

The previous factory is the only thing our customers need to know about us! To put all the pieces together, let’s look at how a client code using our service will look like.

public class MainClass {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//Calling doThis with a local instance of the ServiceA, very useful for testing!!!!
		ServiceA serviceA1 = ServiceAFactory.getLocalService();
		serviceA1.doThis();
		//Calling doThis with a remote instance of the ServiceA using Web services.
		ServiceA serviceA2 = ServiceAFactory.getRemoteServiceUsingWebService();
		serviceA2.doThis();
		//Calling doThis with a remote instance of the ServiceA using Web services.
		ServiceA serviceA3 = ServiceAFactory.getRemoteServiceUsingJms();
		serviceA3.doThis();
	}

}

[EDIT] Now you can make the client even less aware of the service location, you can use a dependency injection framework as Spring to set the implementation of your service.

`
public class MainClassUsingSpring {	
	public static void main(String[] args) {
		ServiceA serviceA = loadFromSpring();
		serviceA.doThis();
	}

	private static ServiceA loadFromSpring() {
		ApplicationContext context = new ClassPathXmlApplicationContext ("beans.xml");
		return (ServiceA) context.getBean("serviceAProxy");
	}

}

Then you can have a spring file configuration similar to this.


		
			
			
		

By changing your spring configuration file now you are able to change the implementation of your service and its location without even changing your source code!

Written by Alberto Gutierrez

November 17th, 2009 at 6:34 pm

The four golden rules to be a better software developer.

with 15 comments

The research to become a better software developer is core to any good software developer. Being a better software developer reflects directly in the code you produce, the better software developer you are, the less bugs, easier to read and easier to maintain code you will produce.

What follow are the four rules I use on my day to day work to help me become a better software developer.

Rule number 1:  My code is crap.

All code is crap, and that includes yours, (and mine, of course). No matter how brilliant a piece of code you think it is, there will be always better ways to implement it, and several programmers who will hate it.

Even if you are sure your code happens to be good, force yourself into “my code is crap” mode, and ask around about improvements, be open minded and you will see soon how you will find issues in your code that you never have thought about.

Rule number 2: Even if it’s crap, I care about my code.

It is not about creating the best code upfront, is about making it better every time you visit it. When you finish some functionality, you are not done, I haven’t met any programmer that produces acceptable code on their first attempt, you need to polish it. Refactoring is then one of the main activities you should be performing.

Rule number 3: My opinion about my own code is wrong.

We are so egocentric that we end up believing that what we have produced, no matter how bad it is, is the best solution as possible. Never trust your own opinion, show your code to as much developers as possible and listen to them.

Rule number 4: My manager doesn’t care about my code, and he pays me.

This rule regulates the other three, it is easy to forget that you actually get paid to get things done, your manager should also care about the code, but he is more focused in completing things on time with an acceptable quality, so be careful not to expend too much time just making sure your code is not that crap. The key is being able to balance getting things done and their quality.

Bonus: A few tips to help you with these rules.

Written by Alberto Gutierrez

November 9th, 2009 at 5:42 am