• +43 660 1453541
  • contact@germaniumhq.com

More Is Less in Tests


More Is Less in Tests

After the article from yesterday where we got to see some code where code duplication actually improved the tests, we’ll look at something similar today, but this time in unit tests, and why I’m not a big fan generally speaking of test parametrization.

So let’s assume we have this test:

@Test
public void testXPathFinding() {
    String document = "<nodes><node name='attribute content'>node content</node></nodes>";
    String xpath = "/nodes/node";

    String result = findByXpath(document, xpath);

    assertEquals("node content", result);
}

@Test
public void testXPathAttributeFinding() {
    String document = "<nodes><node name='attribute content'>node content</node></nodes>";
    String xpath = "/nodes/node/@name";

    String result = findByXpath(document, xpath);

    assertEquals("attribute content", result);
}

@Test
public void testXPathRecursiveContent() {
    String document = "<nodes><node name='attribute content'>node content</node></nodes>";
    String xpath = "//node/@name";

    String result = findByXpath(document, xpath);

    assertEquals("attribute content", result);
}

The code duplication is obvious. Still looking at the previous code, the clear code separation of Given/When/Then is also obvious. And having readable code is superior to having compact code. Imagine we’d refactor this code to:

@Test
public void testXPathFinding() {
    testXPath(
        "<nodes><node name='attribute content'>node content</node></nodes>",
        "/nodes/node",
        "node content");
}

@Test
public void testXPathAttributeFinding() {
    testXPath(
        "<nodes><node name='attribute content'>node content</node></nodes>",
        "/nodes/node/@name",
        "attribute content");
}

@Test
public void testXPathRecursiveContent() {
    testXPath(
        "<nodes><node name='attribute content'>node content</node></nodes>",
        "//node/@name",
        "attribute content");
}

private void testXPath(String document, String expression, String expected) {
    // ...
}

We lost almost all readability. We ended up with a bunch of data looking at us, and the only meaningful description of the expected test is now in the name of the method (!?). Even the variable names are gone, and the Given/When/Then structure vanished.

Despite the refactoring, the structure of the code became worse.

So here’s the conclusion: Optimize for human readability not Lines of Code. Sometimes code duplication is better.