Designing base setup classes

When the Selenium page object classes were designed, we created an abstract base class to derive all the common components and methods for each subclass in the framework. This provided a way to reduce the number of elements and code being written, and a way to share common methods among pages.

Now we are dealing with the other side of things: the test classes and data. In this case, we want to design a common setup class using the TestNG annotations for methods, which will perform common setup and teardown for all the classes in a suite. Up to now, we've seen how each test class can create its own setup and teardown methods. Another layer of setup and teardown can precede the test class ones very easily.

Here are some examples:

  • If the user wants to run a set of test classes as part of a <test> section in their suite file, then they would want to invoke and close the browser or mobile application before and after each set of tests execute. You wouldn't want to do this at the test class level. This would be done using the @BeforeTest and @AfterTest methods defined in a common setup class.
  • However, if the user wanted to run a set of test classes in parallel as part of a <test> section in their suite file, then they would want to invoke and close the browser or mobile application before and after each class executes, since they are running on different threads. This can be done using the @BeforeClass and @AfterClass methods defined in the common setup class.

Here are a couple of coding examples:

/**
* Test Setup Base Class
* (JavaDoc Intentionally left out)
*
* @author Name
*
*/
public abstract class MyCommonSetup {

// abstract methods
protected abstract void testClassSetup(ITestContext context)
throws Exception;
protected abstract void testClassTeardown(ITestContext context)
throws Exception;
protected abstract void testMethodSetup(ITestResult result)
throws Exception;
protected abstract void testMethodTeardown(ITestResult result)
throws Exception;

@BeforeSuite(alwaysRun=true, enabled=true)
protected void suiteSetup(ITestContext context) throws Exception {
}

@AfterSuite(alwaysRun=true, enabled=true)
protected void suiteTeardown(ITestContext context) throws
Exception {
}

@BeforeTest(alwaysRun=true, enabled=true)
protected void testSetup(ITestContext context) throws Exception {
CreateDriver.getInstance().setDriver(Global_VARS.DEF_BROWSER,
Global_VARS.DEF_PLATFORM,

Global_VARS.DEF_ENVIRONMENT);
}

@AfterTest(alwaysRun=true, enabled=true)
protected void testTeardown(ITestContext context) throws
Exception {
CreateDriver.getInstance().closeDriver();
}

@BeforeClass(alwaysRun=true, enabled=true)
protected void classSetup(ITestContext context) throws
Exception {
}

@AfterClass(alwaysRun=true, enabled=true)
protected void classTeardown(ITestContext context) throws
Exception {
}

@BeforeMethod(alwaysRun=true, enabled=true)
protected void methodSetup(ITestResult result) throws Exception {
}

@AfterMethod(alwaysRun=true,enabled=true)
protected void methodTeardown(ITestResult result) throws
Exception {
}
}

In this common setup class, the driver is started in @BeforeTest and closed in @AfterTest methods. This allows the user the ability to run all the classes contained in the <test> sections of the suite XML file in parallel.

Now, those calls could have been put in @BeforeSuite and @AfterSuite, but that would have restricted the use of parallel thread runs (TestNG does not allow suite files to be run in parallel).

Again, if the user wants to run each class in parallel, then the start and close of the driver needs to be done in the @BeforeClass and @AfterClass methods.

Here is how the test class inherits these methods:

/**
* Test Class Method
*
* @author Name
*
*/
public class MyAppTest extends MyCommonSetup {

// implemented abstract methods
@Override
@BeforeClass( alwaysRun = true, enabled = true )
protected void testClassSetup(ITestContext ctxt) throws Exception {
}

@Override
@AfterClass( alwaysRun = true, enabled = true )
protected void testClassTeardown(ITestContext ctxt) throws
Exception {
}

@Override
@BeforeMethod( alwaysRun = true, enabled = true )
protected void testMethodSetup(ITestResult rslt) throws Exception {
}

@Override
@AfterMethod( alwaysRun = true, enabled = true )
protected void testMethodTeardown(ITestResult rslt) throws
Exception {
}

// these methods override the Superclass methods
@Override
@BeforeClass(alwaysRun=true,enabled=true)
protected void classSetup(ITestContext ctxt) throws Exception {
}

@Override
@AfterClass(alwaysRun=true,enabled=true)
protected void classTeardown(ITestContext ctxt) throws Exception {
}

@Override
@BeforeMethod(alwaysRun=true,enabled=true)
protected void methodSetup(ITestResult rslt) throws Exception {
}

@Override
@AfterMethod(alwaysRun=true,enabled=true)
protected void methodTeardown(ITestResult rslt) throws Exception {
}
}

This is a simple test class example outlining how to use a common setup base class to perform common setup and teardown actions for all classes in a suite, implement abstract setup and teardown methods, and use local setup and teardown methods in a test class.

As mentioned earlier, any of the inherited methods can be overridden by using the @Override annotation and the same method name.

The order of execution precedence in this example is the following:

  • @BeforeSuite (superclass)
  • @BeforeTest (superclass)
  • @BeforeClass (superclass)
  • @BeforeClass (subclass)
  • @BeforeMethod (superclass)
  • @BeforeMethod (subclass)
  • @AfterMethod (subclass)
  • @AfterMethod (superclass)
  • @AfterClass (subclass)
  • @AfterClass (superclass)
  • @AfterTest (superclass)
  • @AfterSuite (superclass)
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.174.95