Dev
Dev

Reputation: 13753

Code reusability in Junit Test cases

public abstract class BaseTest {

  protected static HiveTable hiveTable1 = null;
  protected static HiveTable hiveTable2 = null;

  @Test
  public void testHiveMetadata() throws DataConnectorException {
      Assert.assertFalse(hiveTable1.exists());
      hiveTable1.create();
      Assert.assertTrue(hiveTable1.exists());
      putRecords(hiveTable1);
      Assert.assertEquals(3, hiveTable1.getRecordCount());

      Assert.assertFalse(hiveTable2.exists());
      hiveTable2.create();
      Assert.assertTrue(hiveTable2.exists());
      Assert.assertEquals(0, hiveTable2.getRecordCount()); 

      //more code    
  }
}


public class SomeTest1 extends BaseTest {

    @BeforeClass
    public static void setUpBeforeClass() throws DataConnectorException {

        hiveTable1 = HiveDatasources.getLocalHiveTable1();
        hiveTable2 = HiveDatasources.getLocalHiveTable2();
    }
}

Basically, abstract class BaseTest has core testing logic and other classes like SomeTest1 are populating objects needed in abstract class.

There are SomeTest2, SomeTest3 and some other classes which test with different types of hiveTable objects (like hive table with different file formats).

As per my understanding when I mvn clean install my project only test cases of concrete classes will run.

Is this right approach to solve the problem like this?

Upvotes: 2

Views: 361

Answers (1)

GhostCat
GhostCat

Reputation: 140427

My advise is rather different: consider to be really careful about using inheritance here to avoid code duplication.

You see, the essential point of unit tests is: they should help you to quickly identify the root cause of bugs in your production code (listen here for some thoughts around that topic).

This means: the core quality of a unit test is that you get from a fail message to the core of the problem as fast as possible. Any additional layer of abstraction ... slows you down. Meaning: in your setup, when a test fails, you have to understand that

  1. Ups, there is actually no @Test method in the class you were told about a failing test
  2. So you have to figure: ah, it is defined in some base class
  3. Then you start reading there ... to figure: "oh, and how are things setup?!
  4. To come back to your failing test class

Maybe that isnt a problem for the first two weeks after creating this code. But what happens in 2 years, when new people are on your team; and you are out; and then one of those tests fails?!

My thought here: instead of using inheritance, use composition. Meaning: create a helper class that provides "test helper" methods; and then allow for a bit of code duplication and give all your SomeTest classes the fields in order and test methods to do the test work.

And finally the one thing you should definitely change: you have multiple asserts in your one test method. Better roll that out and have multiple tests, each one doing at max one assert.

Upvotes: 1

Related Questions