In the last tutorial, we started our discussion by diving into the basic project outline and distinct components of the framework. We delved into how “excels” could be utilized as a data source for accumulating testing data and handling Excel files. Moreover, we examined techniques and tools that can boost our framework’s efficiency.
In this installment of the Selenium Training Series, we’ll address more sophisticated topics. We’ll cover two key aspects that heighten the sophistication of a framework in this understanding – the implementation of generics and the value of reusability, alongside examining the creation and relevance of test suites.
Recommended IPTV Service Providers
- IPTVGREAT – Rating 4.8/5 ( 600+ Reviews )
- IPTVRESALE – Rating 5/5 ( 200+ Reviews )
- IPTVGANG – Rating 4.7/5 ( 1200+ Reviews )
- IPTVUNLOCK – Rating 5/5 ( 65 Reviews )
- IPTVFOLLOW -Rating 5/5 ( 48 Reviews )
- IPTVTOPS – Rating 5/5 ( 43 Reviews )
Throughout our discussion, we’ll supplement with applicable examples and sample code for better comprehension.
<
div id=”toc_container” class=”no_bullets”>
What You’ll Gain:
- Generics
- Varieties of Generics
- Crafting a Generic Class
- Test Suites
- Code Excerpt
- Code Explanation
- Closing Thoughts
What You’ll Learn:
Generics
In the simplest terms, generics signify something that characterizes a complete group or category.
When automating application tasks, we frequently encounter scenarios that comprise multiple small functionalities. A significant portion of these functionalities can be reused in multiple test scripts with slight or no alterations.
Instead of replicating the same code in each script, it is advised to build generic functions in a separate class that can be utilized across multiple test scripts.
Creating reusable generics can decrease the time spent on development, reduce the occurrence of errors and bugs, and lessen maintenance effort.
Types of Generics
#1) Application Exclusive
Any functionality that is specific to an application under testing can be integrated into an application-specific generic. Consider a login functionality, which is often used in numerous test scripts. Rather than duplicating the login code in each script, we can shape a generic method in a class and invoke it whenever necessary.
#2) Framework Exclusive
Beyond application-specific generics, we may possess general methods that don’t directly pertain to the application under testing but are a part of the chosen framework. For instance, in a Test Data Driven Framework, we might need to fetch data from Excel files. Instead of rewrite the code to extract Excel files in each test script, we can shape a generic method in a class and utilize it as needed.
Creating a Generic Class
A user is free to generate as many generic classes as they need, based on the required modularity.
To understand the concept of generics, let’s go through the process of creating one.
Step 1: Formulate a fresh Java class titled “CommonMethods.java”. This will operate as a generic class, containing common methods. It is suggested to put this class in a distinctive package, separate from the test scripts.
Step 2: Copy and insert the following code into the “CommonMethods.java” class. This class can contain multiple common methods. As an example, the code snippet below illustrates a login functionality:
/** * Log into the application under test * * @param username * @param password */ public void login(String username, String password) { try { // Input User Name WebElement userName = driver.findElement(By.id("loginID")); userName.clear(); userName.sendKeys(username); // Input Password WebElement passWord = driver.findElement(By.id("Password")); passWord.clear(); passWord.sendKeys(password); // Click on the Sign-in Button WebElement signin = driver.findElement(By.id("SignIn_button")); signin.click(); driver.manage().window().maximize(); } catch (Exception e) { e.printStackTrace(); } }
The method accepts parameters, enabling it to be re-used to test the login functionality with diverse sets of test data.
Step 3: Invoke the common method within the test script. This is a two-step process. Initially, create an instance of the generic class within the test class. Then, call the common method on the created instance, passing the necessary arguments. The code fragment below demonstrates how to establish an instance of the “TestScript1” class and invoke the login() method to log in to the application:
// Instantiate the generic class Tools toolsObj = new Tools(); // Sign into the application under test by invoking the shared method toolsObj.login("username", "password");
The above code can be positioned anywhere within the test class. Users can place it in a setup() method or a test() method according to their needs.
Test Suites
A test suite can be described as a compilation of numerous test scripts arranged together for execution. It enables us to implement multiple test scripts automatically. Users need to supply the class name of the test script (in its compiled form with the “.class” extension) within the test suite to include a test script.
Here’s an example of a test suite formed in Java: It’s important to note that a test suite is a Java class that employs JUnit annotations.
Code Excerpt
package com.axway.webliv.tests; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.RunWith; import org.junit.runner.notification.Failure; import org.junit.runners.Suite; import com.axway.webliv.tests.MetaData.*; @RunWith(Suite.class) @Suite.SuiteClasses({ ChangeStatusBinarySphereTest.class, ChangeStatusRestrictionTest.class, ChangeStatusDocSphereTest.class, }) public class TestSuite { /** * Setup method to define system properties */ @BeforeClass public static void Setup() { } /** * @param args */ public static void main(String[] args) { Result result = JUnitCore.runClasses(TestSuite.class); System.out.println("RUN TEST CASES: " + result.getRunCount()); System.out.println("FAILED TEST CASES: " + result.getFailureCount()); for (Failure failure : result.getFailures()) { System.out.println("nTEST IDENTIFIER: " + failure.getTestHeader()); System.out.println("nERROR: " + failure.getMessage() + "n"); System.out.println(failure.getTrace()); System.exit(1); } } /** * Present test results */ @AfterClass public static void TearDown() { } }
Code Explanation
A test suite is fundamentally a JUnit class that incorporates setup() and teardown() methods, as we’ve addressed in earlier tutorials. Nevertheless, its distinguishing feature is its capacity to execute numerous test scripts simultaneously.
Import Declarations
import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.RunWith; import org.junit.runner.notification.Failure; import org.junit.runners.Suite;
These import declarations enable the exploitation of various annotations provided by JUnit.
import org.junit.runner.JUnitCore;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
Such statements deliver the requisite infrastructure for the execution of a test suite comprising multiple test classes.
import org.junit.runner.Result;
This import statement grants the user the ability to store and manipulate the execution statuses of tests.
import org.junit.AfterClass;
import org.junit.BeforeClass;
These import statements are utilized to identify and annotate the setup() and teardown() methods. The setup() method, annotated with BeforeClass, runs preceding each test script execution, and the teardown() method, annotated with AfterClass, is executed following each test script.
Class Entry
@RunWith(Suite.class) @Suite.SuiteClasses({ ChangeStatusBinarySphereTest.class, ChangeStatusRestrictionTest.class, ChangeStatusDocSphereTest.class, })
In this partition, we list the entries of the test scripts to be carried out. The listings consist of the class names of the test scripts (notated in their compiled form including the “.class” extension).
Execution – main()
public static void main(String[] args) { Result result = JUnitCore.runClasses(TestSuite.class); System.out.println("RUN TEST CASES: " + result.getRunCount()); System.out.println("FAILED TEST CASES: " + result.getFailureCount()); for (Failure failure : result.getFailures()) { System.out.println("nTEST TITLE: " + failure.getTestHeader()); System.out.println("nERROR: " + failure.getMessage() + "n"); System.out.println(failure.getTrace()); System.exit(1); } }
This code block manages the execution procedure, commencing from the main() method.
The runClasses() function of the JUnitCore class is employed to execute the test suite. Users can utilize the Result class and its methods to ascertain the execution status of each test case (whether successful or failed).
Users can alter the test suite class to conform to their specific necessities.
Wrap-up
In this tutorial, we’ve introduced the idea of generics and shared methods. We’ve looked into the advantages of generics, particularly in context of reusability. We’ve also offered practical strategies for crafting generics and implementing them in test scripts.
Main points drawn from this article:
- Generics are classes containing methods that can be disseminated across multiple test classes, fostering reusability.
- Generics can be classified as being application-centric or framework-centric.
- Shape a distinct Java class to operate as a generic class and implement shared methods within it.
- Invoke the shared methods by generating an instance of the generic class inside the test script.
- A test suite is a compilation of numerous test scripts organized together for execution.
- A test suite is a simple JUnit class that includes setup() and teardown() methods, facilitating the implementation of multiple test scripts.
Next Tutorial #23: In the subsequent tutorial, we’ll look into another tool for automating the entire build process – “Ant”. We’ll deliberate on the benefits of employing a build tool in test automation, outline project dependencies, and craft the build.xml file.
A Note for Readers: Since we have covered the most salient features of the framework in this and past tutorials, readers can now practice these principles and modify their own frameworks.