3

In C#, it is possible to specify parameters for the same unit test method. Example:

[DataTestMethod]
[DataRow(12,3,4)]
[DataRow(12,2,6)]
public void DivideTest(int n, int d, int q)
{
   Assert.AreEqual( q, n / d );
}

Is it possible to do the same in Java? I have read Parametrized runner but this solution is not as easy to use.

4
  • Related Commented Jul 1, 2017 at 20:31
  • Have you had a look at parameterized tests in JUnit 5? Commented Jul 1, 2017 at 20:39
  • This is not a Java feature but a framework feature. I particularly like the way that Spock handles it, but both JUnit and TestNG have support, too. Commented Jul 1, 2017 at 20:59
  • I read TestNG is no more maintained. It is true? Commented Jul 1, 2017 at 21:01

4 Answers 4

4

With JUnit 5, parameterized tests are really more straight and natural to use as with JUnit 4.

In your case, to provide multiple parameters as input, you could use the @CsvSource annotation.

Here are the required dependencies (maven declaration way) :

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.0.0-M4</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-params</artifactId>
    <version>5.0.0-M4</version>
    <scope>test</scope>
</dependency>

And here is a sample code (with required imports) :

import org.junit.Assert;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

public class YourTestClass{

    @ParameterizedTest
    @CsvSource({ "12,3,4", "12,2,6" })
    public void divideTest(int n, int d, int q) {
       Assert.assertEquals(q, n / d);
    }

}
Sign up to request clarification or add additional context in comments.

Comments

3

The Spock Framewok offers Data Driven Testing for Java and Groovy.

The Tests are (unfortunately?) written in Groovy:

class MathSpec extends Specification {
  def "maximum of two numbers"() {
    expect:
    Math.max(a, b) == c

    where:
    a | b || c
    1 | 3 || 3
    7 | 4 || 7
    0 | 0 || 0
  }
}

Comments

1

You cannot achieve this so simple with JUnit out of the box, but you can use 3rd party JUnitParams:

@RunWith(JUnitParamsRunner.class)
public class PersonTest {

  @Test
  @Parameters({"17, false", 
               "22, true" })
  public void personIsAdult(int age, boolean valid) throws Exception {
    assertThat(new Person(age).isAdult(), is(valid));
  }

  @Test
  public void lookNoParams() {
    etc
  }
}

3 Comments

Thanks Ivan. Much better. Since Java8, annotations could be repeatable. Do you know if the same solution exists by repeating @Parameters?
You mean, will it work for several annotated methods? Yes, it will.
@Ivan Pronin +1 as nice alternative before Junit 5.
0

yes, eg. JUnit has parameterized tests

https://github.com/junit-team/junit4/wiki/parameterized-tests

The only drawback is that all test methods in the class will be executed for each parameter (row).

1 Comment

Thanks Timothy, but as I said, I don't like this solution. The reason is parameters and testing methods are too distinct. That is why I think it is not as easy to use than C# solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.