Saturday, April 30, 2011

Having an opinion

In this blog post I will explain why having an opinion is important.

At my first job as a software developer there was a legendary senior developer. Hey called himself a technocrati. He had a vast amount of experience, a no-nonsense way of communicating and openness towards the inexperienced. although he could program circles around me while being blindfolded and with one arm tied behind his back, he always took the time to explain things to me if I had a question.

Although I learned a lot from him, he gave me one pivotal piece of advice: "Have an opinion".

Like all sayings of masters, one should reflect on the meaning.

I am certain that having a opinion, means have a well founded opinion. Having an opinion without a clear reason is void of meaning. It could come around with the sleightest amount of suggestion.

If the advice "Have an opinion" actually means "Have a well founded opinion" the meaning becomes clear to me. Study relentlessly. So I did, and I am still doing that.

An other interpretation of the advice I gleaned from the behavior of "the master" is this. "Have an opinion, and voice it".

It is nice to have a well founded opinion, but it is a waste if you hold it back. By giving your opinion on a certain topic, you are effectively spreading knowledge. For me this was enticing. It was not uncommon to have to following thoughts after a meeting with the master. Why does someone have this "outrageous" opinion? He seems a knowledgeable person, maybe his ideas have merit. Let's just look into them just to be sure.

I would like to conclude this blog post with my narrated version of his advice. Have a well founded opinion, and voice it.

Thursday, April 7, 2011

Launch Configurations in Eclipse

In this post I point out where Eclipse is storing the launch configurations.

After a fresh install of my laptop I wanted to restore the launch configurations of Eclipse. After some searching I finally found the location. I am reporting it here for future reference.

The eclipse launch configurations can be found in your workspace at


.metadata/.plugins/org.eclipse.debug.core/.launches

Sunday, February 6, 2011

Parametrized Junit Tests: Postscript

In two earlier blog posts I commented on parametrized junit tests. This blog post will complement these post with an example of a piece of code.

Because all the important points are made in the other posts I will only present the Junit runner I created. A Maven project demonstrating this technique can be found code at my minimal examples repository

Without further ado: the Junit runner.

package org.junit.runners;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.junit.runner.Runner;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.Parameterized.Parameters;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;
import org.junit.runners.model.TestClass;

public class ParameterizedWithBuilder extends Suite
{
        private class TestClassRunnerForParametersWithBuilder extends BlockJUnit4ClassRunner
        {
                private final int fParameterSetNumber;

                private final List<Object> fParameterList;

                TestClassRunnerForParametersWithBuilder(Class<?> type, List<Object> parametersList, int i)
                        throws InitializationError
                {
                        super(type);
                        fParameterList = parametersList;
                        fParameterSetNumber = i;
                }

                @Override
                public Object createTest() throws Exception
                {
                        return getTestClass().getOnlyConstructor().newInstance(computeParams());
                }

                private Object computeParams() throws Exception
                {
                        try
                        {
                                return fParameterList.get(fParameterSetNumber);
                        }
                        catch (ClassCastException e)
                        {
                                throw new Exception(String.format("%s.%s() must return a Collection of objects.", getTestClass()
                                        .getName(), getParametersMethod(getTestClass()).getName()));
                        }
                }

                @Override
                protected String getName()
                {
                        return String.format("[%s]", fParameterSetNumber);
                }

                @Override
                protected String testName(final FrameworkMethod method)
                {
                        return String.format("%s[%s]", method.getName(), fParameterSetNumber);
                }

                @Override
                protected void validateConstructor(List<Throwable> errors)
                {
                        validateOnlyOneConstructor(errors);
                }

                @Override
                protected Statement classBlock(RunNotifier notifier)
                {
                        return childrenInvoker(notifier);
                }
        }

        private List<Runner> runners = new ArrayList<Runner>();

        public ParameterizedWithBuilder(Class<?> klass) throws Throwable
        {
                super(klass, Collections.<Runner> emptyList());
                List<Object> parametersList = getParametersList(getTestClass());
                for (int i = 0; i < parametersList.size(); i++)
                        runners.add(new TestClassRunnerForParametersWithBuilder(getTestClass().getJavaClass(), parametersList, i));

        }

        @Override
        protected List<Runner> getChildren()
        {
                return runners;
        }

        @SuppressWarnings("unchecked")
        private List<Object> getParametersList(TestClass testClass) throws Throwable
        {
                return (List<Object>) getParametersMethod(testClass).invokeExplosively(null);
        }

        private FrameworkMethod getParametersMethod(TestClass testClass) throws Exception
        {
                List<FrameworkMethod> methods = testClass.getAnnotatedMethods(Parameters.class);
                for (FrameworkMethod each : methods)
                {
                        int modifiers = each.getMethod().getModifiers();
                        if (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))
                                return each;
                }

                throw new Exception("No public static parameters method on class " + testClass.getName());
        }

}

Tuesday, February 1, 2011

Sexism in Language

In this blog I will point out a an examples of sexism in language.

As I pointed out in an earlier post I adapted my wife's name after we married. Although this is legally possible since the year 1998, not everybody adapted accordingly.

There are a lot of forms in which you have to fill out your name. It is often the case that the name should be the same name as found in your passport i.e. your birth name. But the forms ask to fill in your maiden name. Well the last time I checked, I never was a maiden. Furthermore, I have no intention of ever becoming one. So I regard this as a strange question.

The origins of the use of this language are clear to me. A long time ago only women could take on an other name. So if someone wanted to know your birth name she could reason as follows:

  1. Males can be asked for their name, regardless of their marital status.
  2. Females can be asked for their name, unless they are married. Then they should be asked for their maiden name.

But since the 1998 this rule does not apply any more. And if you want to know my birth name ask for it. It is been twelve years, everybody had enough time change their forms. I regard this as a very sexist use of language.

Sunday, January 30, 2011

Parametrized JUnit Tests Revisited

In the Parametrized JUnit Tests blog post I explained how to create a parametrized junit test. In this blog post I will discuss the reaction of one of my colleagues.

After reading my blog post about parametrized junit tests a colleague expressed his objections with this way of testing. He was a bit disappointed with one thing in particular. The signature of the public static method that is used to construct the test.

@Parameters
public static Collection<Object[]> data()

Is returns a collection of Object arrays. One Object array for each set of parameters. The reason this should be an Object array becomes clear from it's usage.

List<Object[]> data = new ArrayList<Object[]>();
data.add(new Object[] { 2, new Integer[] { 2 } });
return data;

Because the parameters used are of different type, in this case an Integer and an Integer array, they only super-type they have in common is Object.

The objection of my colleague was that is berefts the compiler of the oppertunity to detect type errors at compile time. The compiler would happily compile the following code. But it would blow up at run time.

List<Object[]> data = new ArrayList<Object[]>();
data.add(new Object[] { 2, new Integer[] { 2 } });
data.add(new Object[] { 2, new Double[] { 2.0 } });
return data;

After some discussion with my colleague we came up with the following solution. Instead of using a lot of parameters in the constructor, use only one. By using the builder pattern one retains the type information. Furthermore because now only one parameter is needed, the nearest super-type of all the parameters is the type of the parameter itself.

The code that follows show the same test as in the previous blog post. The change is reflected in the use of the builder pattern. Note that a fluent interface is used to easily construct a builder for the test.
One could still object that the array is now superfluous. They are correct. One way to deal with their objections is to write an custom runner.

@RunWith(Parameterized.class)
public class FactorizationTest
{
    private int number;

    private List<Integer> expectedResult;

    public FactorizationTest(FactorizationTestBuilder builder)
    {
        this.number = builder.getNumber();
        this.expectedResult = builder.getExpectedResult();
    }

    @Test
    public void factorize()
    {
        assertEquals(expectedResult, Factorization.factor(number));
    }

    @Parameters
    public static Collection<FactorizationTestBuilder[]> data()
    {
        List<FactorizationTestBuilder[]> data = new ArrayList<FactorizationTestBuilder[]>();
        data.add(new FactorizationTestBuilder[] { FactorizationTestBuilder.withNumber(2).expect(2) });
        data.add(new FactorizationTestBuilder[] { FactorizationTestBuilder.withNumber(8).expect(2, 2, 2) });
        data.add(new FactorizationTestBuilder[] { FactorizationTestBuilder.withNumber(9).expect(3, 3) });
        data.add(new FactorizationTestBuilder[] { FactorizationTestBuilder.withNumber(72).expect(2, 2, 2, 3, 3) });
        return data;
      }
}

class FactorizationTestBuilder
{
    private int number;

    private List<Integer> expectedResult = new ArrayList<Integer>();

    public static FactorizationTestBuilder withNumber(int number)
    {
        return new FactorizationTestBuilder(number);
    }

    private FactorizationTestBuilder(int number)
    {
        this.number = number;
    }

    public FactorizationTestBuilder expect(Integer... expectedResult)
    {
        this.expectedResult = Arrays.asList(expectedResult);
        return this;
    }

    public int getNumber()
    {
        return number;
    }

    public List<Integer> getExpectedResult()
    {
        return expectedResult;
    }
}

In this blog post I described the objections of a colleague on the previous Parametrized Junit Test blog. I have shown had to meet these objections by using the builder pattern.

Wednesday, January 26, 2011

Updated old post

In this blog post I announced that I switched to using Mathjax. But I hadn't got to the point of rewriting my old post, with this new interface.

Coming this spring I set out to rectify this point and now all posts are using Mathjax as Latex rendering engine.

The only thing I noticed that not every post is using proper html. So probably I have to go back and change that to.

Saturday, January 15, 2011

Parametrized JUnit tests

In this post I will examine parametrized JUnit tests.

With the introduction of Junit 4, a lot has changed for testing Java software with Junit. One of the more esoteric additions are parametrized tests. It allows a developer to run a great deal of test which differ only in a set of parameters. Without further ado I will show you a parametrized test.

@RunWith(Parameterized.class)
public class FactorizationTest
{
    private int number;

    private List expectedResult;

    public FactorizationTest(int number, Integer[] result)
    {
        this.number = number;
        this.expectedResult = Arrays.asList(result);
    }

    @Test
    public void factorize()
    {
        assertEquals(expectedResult, Factorization.factor(number));
    }

    @Parameters
    public static Collection<Object[]> data()  
    {   
        List<Object[]> data = new ArrayList<Object[]>();
        data.add(new Object[] { 2, new Integer[] { 2 } });
        data.add(new Object[] { 8, new Integer[] { 2, 2, 2 } });
        data.add(new Object[] { 9, new Integer[] { 3, 3 } });
        data.add(new Object[] { 72, new Integer[] { 2, 2, 2, 3, 3 } });   
        return data;
    }
} 

Lets focus on line 17 of the method annotated with @Test. This method asserts that the expectedResult is returned by the static method Factorization.factor(int) which is called with parameter number. Both expectedResult and number are private fields of the class FactorizationTest. The fields are assigned in the constructor.

By annotating the class with the @RunWith(Parameterized.class) we are telling Junit to run this class with the Parameterized Runner. By implementing a Runner you can specify how to run the tests.

For the Parameterized this means the following. (The following section is paraphrased. See https://github.com/KentBeck/junit for the details.)

  1. Get an Collection of Object-arrays.
  2. Repeat for every Object-array in the collection:
    1. Construct an instance of FactorizationTest passing as parameters the various elements in the Object-array.
    2. Run all methods annotated with @Test.

The collection mentioned in step 1 is obtained by calling a method annotated with @Parameters. So in this example the following facts will be asserted.

numberfactors
22
82, 2, 2
93, 3
722, 2, 2, 3, 3

In this blog post I made clear how to use parameterized test in the Junit test framework.