Why does JUnit force you to have test() and setUp() methods that don’t have any
parameters?

Because there is no easy way in Java 1.4 and under to specify the values for
these parameters.

As a consequence to this shortcoming, various JUnit add-ons have added the
possibility to look up property files in your setUp() method which are then
initialized inside your test method (and incidentally, will be initialized over
and over again for each invocation of the test method, as I reported in an
earlier JUnit bug report).

A better way to address this problem is to use annotations as a bridge
between your Java code and a property file.  I just added support for this
in TestNG, and here is how it works (excerpt from the new TestNG documentation).

Parameters

Test methods don’t have to be parameterless.  You can use an arbitrary
number of parameters on each of your test method, and you instruct TestNG to
pass you the correct parameters with the parameters method on the @Test
annotation.  For example:

@Test(parameters = { "first-name" })
public void testSingleString(String firstName) {
System.out.println("Invoked testString " + firstName);
assert "Cedric".equals(firstName);
}

In this code, we specify that the Java parameter "firstName" of your Java method
should receive the value of the property called first-name.  This
property is defined in the testng.properties that you used to invoke this test:

#testng.properties
first-name = Cedric

The same technique can be used for the
@Configuration annotations:

@Configuration(beforeTestMethod = true,
parameters = {"datasource", "jdbc-driver")
public void beforeTest(String ds, String jdbcDriver) {
m_dataSource = ...;  // look up the value of datasource
}

This time, the two Java parameter ds
and driver will receive the value given to the properties datasource
and jdbc-driver respectively.  Note that the properties are mapped to the
Java parameters in the same order as they are found in the annotation, and TestNG will
issue an error if the numbers don’t match.

This system allows for a flexible configuration of the runtime configuration of your
tests and allow you to arbitrarily define how granular this configuration will
be (configuration method or test method).