JUnit Testing Multiple Values Against Same Function Best Practice

  Kiến thức lập trình

Say I have various input strings that are passed into the same function and returns output strings that are compared against their expected results. For example, periods should be transformed to dashes and vice versa.

class SomeClassUnitTest {

  private val someClass = SomeClass()

  @Test
  fun exampleTest_SomeInput_ReturnsCorrectOuput() {
      val input = "..."
      val output = someClass.someFunction(input)
      val expected = "---"

      assertEquals(expected, output)
  }

  @Test
  fun exampleTest_SomeInput_ReturnsCorrectOuput() {
      val input = "---"
      val output = someClass.someFunction(input)
      val expected = "..."

      assertEquals(expected, output)
  }

}

I have a couple questions about the best practice and practicality of another way to structure this unit test. First being, if I’m testing the same function with similar inputs and outputs, I can structure the unit test like the above code or like so:

  @Test
  fun exampleTest_SomeInputs_ReturnsCorrectOuputs() {
      val input = listOf{ "...", "---" }
      val output = listOf<String>()
      input.forEach { output += someClass.someFunction(input) }
      val expected = listOf{ "---", "..." }

      assertEquals(expected, output)
  }

But SHOULD I structure the test like this? I figure this would make the unit test class more concise and readable so in case there’s other functions in SomeClass to test then the test can be added into this file with another list of values to test against.

I can accept if it’s wrong to develop a unit test like this. We do lose out on the convenience of the test function name describing how the function’s unit test is failing. And I suppose the unit test can be over-engineered to tell the developer what specific value is failing the test. What are your thoughts?

Another aspect I want to ask is about unit test efficiency? Could the more concise unit test be more performant than individual tests for each input?

I know it wouldn’t be apparent from the examples I’ve provided, so what if the function took a bit of time to complete? I’m thinking the list of values could all be initiated asynchronously and once all responses are complete then the comparison against the expected result is performed. Thus the method of a unit test for individual inputs as O(k*n) (where k is the amount of tests and n is the processing time) is reduced to O(n) which is determined now by the longest processing time of the list of values.

I’m mostly curious about what the community has found in their own experience. I could test these myself, but I’m concerned with the first question, “should I structure the test like this?” and the second is more of a bonus granted it’s possible to perform asynchronous operations in unit tests.

LEAVE A COMMENT