Automation Pre
Automation Pre
General:
• Tell me about yourself?
• What is your Role and Responsibilities?
• Architecture of your current application?
• Which Automation framework you are using in your organization can you tell me the
folder structure and flow of your framework?
Java:
• Why string is immutable in java?
• what is static in java?
• what is final in java?
• can we create the object for the abstract classes?
• can we create constructor of abstract class?
• can constructor be overloaded. Explain why?
• can main method be overloaded?
• can we override static method?
• can i execute multiple catch blocks without try will it give me compile time error?
• if we declare the main method as private what will happen?
• how to check whether the array is empty and null?
• what is the use of constructor in java?
• what is hashmap? Can we store objects in hashmap and how to retrieve them?
• access modifiers in java and its scope?
• what is meant by thread?
• what is singleton class in java?
• what is the difference between static binding and dynamic binding?
• what is polymorphism?
• how and when to use interface?
• where do you use polymorphism in java?
• design pattern in java.
• how to prevent the override method in java?
• what is the difference between list and set?
• why do we use finally and how it differs from the final keyword?
• Can we use multiple catches? When can we use multiple catches?
• Different between POI and JXL jar?
• Why is the main method static?
• What is the use of static variables?
• Can we instantiate an interface?
• Can we override constructor?
• What is the system.out.println? and use of it?
Selenium:
3 https://www.linkedin.com/in/manas-jha/ sel java program
LinkedIn Telegram WhatsApp 9145735668
• Do you use the property file in your framework? If yes, then which java concept gets
utilize here? (Java Collection)
• On a web page, there are several Pop-up, but we don’t when the pop-up will appear,
in this case how we will handle the Pop- up using Selenium WebDriver (Java)
• Started automation test suite execution and few test cases are failed in a test run.
How can you execute only failed test cases at once (with one click) what design pattern
do we use when we trigger different browsers?
• What are approached to handle dynamic WebElement?
• Click last option in the dropdown (Last drop-down changes dynamically)
• How to calculate links on a page? (Answer with HTML tag)
• Write the code to read the value from the excel sheet.
• What is Page Factory in POM Design pattern?
• Suppose you have 10 pages in your application then how to achieve POM. What you
will do?
• Annotation used in Page Object Model?
• Ways to find broken links in Selenium?
• How to handle frame in Selenium?
• How to handle Alerts in Selenium?
• Different types of Navigation Commands?
• Difference between assert and verify?
• How to download a file using Selenium?
• How do you manage a set of Data Tables in Selenium?
• How do you automate localization testing -diff language in UI?
• How to avoid NoSuchElementException without using try/catch block and with
try/catch block?
• How to handle web tables whose values change dynamically?
• How to check whether web element is enabled or Disabled without using isEnabled
method?
• Why is CSS locator faster than Xpath?
• Even though CSS is faster than Xpath ,why do 95% of the companies use XPath ?
• Error is throwing as Element not found but when I go and check that element is
available in the web page? The element is not hidden so no need to use Java script
executor? How do you solve this?
• How do you execute using headless mode?
• In Selenium, how to get text value from text-box if gettext() is not working?
• If we are using correct locator but still getting element not found error then how you
will resolve this error?
• In Page object model once you create loginpage.java class what is the first thing you
start with writing initially. How are you initiating writing something into a page class?
• What if Windows popup occurs during test execution and due to that can't execute
automated tests, how u will resolve this error?
• Different ways to handle hidden elements?
• What is the difference between click() function in webelement interface and click()
function in Actions class?
• Is it possible to change the behavior of a test at runtime?
• Describe how to handle the below items using selenium -iframe -windows -table -
Alerts
• How to click right click of mouse?
• How to scroll down a page?
• What will driver.getWindowHandels() return?
• How will you automate Windows based application?
• In cucumber, in which class you have gluecode, how many classes for gluecode and
what was the program line limit for class?
Java Program:
• Swap string without 3rd variable?
• WAP to find 2nd highest number in an array
• Duplicates in a String?
• How to find the length of the string without using length?
• Largest Number in an Array?
• Reverse string without using reverse function
• Write code to print the Fibonacci series?
• Write code to print only the even numbers from an array.
• Write code to find special character, number, capital and small letter in a given string.
• Write code to check if a number is palindrome?
• Write a Java code to identify, if the pair of strings are an Anagram or not?
TestNG:
• What is the importance of the testng framework?
• Why we use TestNG in your framework
• What is the purpose of testing XML
• Explain the purpose of listeners? is it the selenium concept of TestNG?
• Case Scenario: How to run the same method 100 times in TestNG with the same
data?
• What is the reporting tool in your framework? and why?
• Some questions in TestNG XML?
• What are different testng annotations?
7 https://www.linkedin.com/in/manas-jha/ sel java program
LinkedIn Telegram WhatsApp 9145735668
Maven:
• Lifecycle of Maven
• Use of Maven surfire plugin. If yes, where and why?
• What is the use of pom.xml?
• CI / CD tools
• What is Jenkins?
• How will you handle dependencies in Maven at run time?
• Today we have executed some tests using maven, but tomorrow when you see that
someone deleted all dependencies from .pom file then in that case will you be able to
execute tests or not.
• Consider you have to write test/suite for different environments(qa, preproduction,
production) and pass different set of data for each environment. How will you do it
using maven file(Pom.xml)?
• Can you give some basic commands used in maven project?
• How will you configure Jenkins job?
• What are two components Jenkins is integrated with?
• How you will schedule the deployments?
• What is the purpose of version control tool?
• What are the git commands you have used?
• What is difference between group id and artefact id?
• How and when is Jenkins is used in your Automation?
Webservices:
• Difference between REST and SOAPUI.
• Method in REST.
• Difference between PUT and PATCH call
• How to integrate postman to project?
• How will you handle dynamic payloads in API?
• How do you capture specific responses value and pass to another request?
• What challenges you faced in API testing?
• What is difference between Authorization and Authentication?
• What are the API status codes, you have come across?
• What is difference between OAuth1.0 and OAuth2.O ,When and where do you use
and how. Can you write a sample code?
• How you get the response from one api and send to another api?
Functional Testing:
• What is Test Plan?
• Explain the bug life cycle?
• Difference between smoke and sanity tests?
• Difference between regression and retesting?
• Difference between functional and regression testing?
• Difference between severity and priority?
• Difference between Test Plan and Test Strategy?
• Difference between boundary value analysis and equivalence partitioning?
• Difference between white box and black box testing?
• If we are having 1000 test cases, what type of testing carried for automation testing?
Can we write a method that returns two or more values? If then, how?
• Bug Life Cycle?
• Bug Triage?
• What is exploratory testing?
• What is adhoc testing?
• What is build acceptance testing?
• What is difference between Validation and Verification?
• Explain severity and priority and High severity with low priority, low severity and high
priority?
• Given the test cases having priority of -1,0,1,2 tell me the sequence of execution.
• Explain inner join and outer join in SQL?
• Difference between DELETE,DROP & TRUNCATE?
• What are test design techniques?
• What is deferred bug?
• How you will decide what tests to automate?
• When you decide to stop the testing?
• If your test suite takes 1 and half to run, what you will do to reduce the time?
• How many test cases in your regression test suite? How much time it will take to
execute?
• How to cover character keyboard operation from the context menu utilizing user-
defined keyword?
• What is most important things to define in a bug?
• Can tell about any achievements you have done in automation?
• Can you tell me the difference between bdd and tdd?
• What is a test plan and what are the steps to create a test plan?
• What are the inbound and outbound for testing?
• What is smoke, regression and sanity testing?
• What is the next step to be taken, if developer rejects the Open defect?
• Explain the test metrices?
• How would you priorities Tests?
• How do you perform Automation Code Review/ Walk Through in your project?
• There are 250 manual test cases , how will you segregate (on what basis) the
regression , sanity , smoke suite?
• When Regression ,Sanity , smoke test scripts are executed ?
• How will you decide that this test case is feasible or good candidate for automation?
Agile:
• What is an agile methodology?
• What is the scrum and who is your scrum master?
Managerial round:
• How you will be an asset to the team?
• Why you are looking for a change?
• How soon you can join?
• Suppose if we give manual testing for six months or one year what will you do?
• How interested are you in learning new technologies?
• Failures in your work life.
• As Lead, how do you define quality of product before releases?
• Suppose you are the leam QA and 1 new member join your team and at the same
time you have a deadline to meet in next 2 or 3 days so how will you involve that new
member in team so that you can utilise him/her to meet deadlines?
• As a QA, where do you see yourself after 3 years?
• What are your strengths and Weakness?
• What are some best practices you learnt and how much difference it made in testing
career? Explain before and after situations
• After you have run a full regression test, and find new regression bugs, which bugs
would you prioritize. Bugs that suggest that functionality has regressed, or bugs that
appear in new features?
1. Security: String immutability prevents any accidental or malicious change to the value of the string. Since
strings are often used to store sensitive information such as passwords, making them immutable adds an extra
layer of security.
2. Thread safety: Immutable objects in Java, including strings, are inherently thread-safe. This means that
multiple threads can access the string object, and there is no risk of data corruption or inconsistency.
3. Caching: String literals are cached by the Java Virtual Machine (JVM), which means that if two String objects
contain the same value, they actually point to the same location in memory. This reduces memory usage and
improves performance.
Example:
Both str1 and str2 point to the same location in memory because they have the same value. If we modify str1
to ""Hello World"", a new object will be created in memory, and str1 will point to that object, leaving the
original object containing ""Hello"" unchanged. This ensures that the value of the string remains constant
throughout the program's execution.
For example, let's say we have a class called ""Car"" with a static variable ""numberOfCars"". This variable will
hold the total number of cars that have been created, regardless of which instance of the ""Car"" class is
accessing it.
To access the static variable, we can simply use the class name followed by the variable name, like this:
Car.numberOfCars += 1;
This increases the total number of cars every time a new instance of the ""Car"" class is created , without
needing to create a new object for that variable.
Example:
Once the variable MAX_NUMBER is assigned the value 100, it cannot be changed.
The ""final"" keyword before the method signature means that this method cannot be overridden by a
subclass.
The ""final"" keyword before the class name means that this class cannot be subclassed.
In this example, ""this.name"" refers to the instance variable ""name"" of the Person class, while ""name""
alone refers to the local variable passed in as a parameter.
In this example, `Animal` is an abstract class with an abstract method `makeSound()`. The `Dog` class extends
the `Animal` class and defines the implementation of the `makeSound()` method. We create an object of `Dog`
class and call its `makeSound()` method to get the output `'Bark'`.
Here, we have defined a constructor that takes two integer parameters x and y. This constructor is called from
the concrete subclass which extends the Shape class.
In this example, the Circle class extends the Shape class and calls the constructor of the Shape class using the
super() keyword.
For example, consider the following Java class with overloaded constructors:
public ExampleClass() {
num1 = 0;
num2 = 0;
}
public ExampleClass(int x) {
num1 = x;
num2 = 0;
}
In the above example, we have three constructors with different parameter lists - no arguments, one integer
argument, and two integer arguments. Each constructor initializes the member variables of the class in a
different way.
Constructor overloading provides flexibility in object initialization and makes the code more readable and
maintainable.
Example:
In this example, we have two main methods with different parameters. One takes an array of Strings as an
argument and the other takes two individual String arguments. When the program is executed, it will print
""Hello World!"" from the first main method. However, if we pass two String arguments when running the
program (`java MainMethodOverload argument1 argument2`), it will execute the second main method that
prints the arguments instead.
Example:
Explantion -2
Overriding is the concept of providing a new implementation for a method in a subclass, which has the same
name, return type, and parameters as the method in the superclass. However, it's not possible to override a
static method because static methods belong to the class and not to the instances of the class. Therefore,
when a subclass defines a static method with the same name, return type, and parameters as the static
method in the superclass, it's not considered as overriding, but rather it's considered as hiding the static
method in the superclass.
class Superclass {
static void printMessage() {
System.out.println("Hello, I am a static method in the Superclass");
}
}
class MyClass {
static void printMessage() {
System.out.println("Hello, I am a static method with no parameters");
}
}
}
Syntax:
try {
//Code block that may throw an exception
}
catch (ExceptionType e) {
//Code block to handle the exception
}
finally {
//Code block to be executed irrespective of whether an exception is thrown or not
}
In the above syntax, the try block contains the code that may throw an exception. The catch block catches the
exception and handles it. The finally block contains the code that will be executed after the try block,
irrespective of whether an exception was thrown or not.
The finally block is often used to perform tasks like closing resources, such as files or database connections,
that were opened in the try block. This ensures that the resources are always released, even if an exception
occurs during the execution of the try block.
Example:
try {
//Code block that may throw an exception
FileInputStream file = new FileInputStream(""file.txt"");
//...
}
catch (FileNotFoundException e) {
//Code block to handle the exception
In the above example, the try block opens a file input stream, which may throw a FileNotFoundException. The
catch block handles this exception by printing an appropriate message. The finally block closes the file input
stream, ensuring that the resource is always released.
Autoboxing refers to the automatic conversion of primitive data types to their corresponding wrapper class
objects. For example, when an int value is assigned to an Integer object, autoboxing will automatically take
place.
Example:
Unboxing refers to the automatic conversion of wrapper class objects to their corresponding primitive data
types. For example, when an Integer object is assigned to an int variable, unboxing will automatically take
place.
Example:
Autoboxing and unboxing can make code more concise and readable, but they can also have a performance
impact if used excessively in high-performance applications.
Java provides a mechanism called Object Serialization to serialize and deserialize objects. An object can be
serialized by implementing the java.io.Serializable interface. This interface has no methods and is used to
identify the class implementing it as being serializable.
import java.io.*;
try {
FileOutputStream fileOut = new FileOutputStream(""student.ser"");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(student);
out.close();
fileOut.close();
System.out.println(""Serialized data is saved in student.ser"");
} catch (IOException i) {
i.printStackTrace();
}
}
}
Deserialization is the process of converting a serialized object back into an object in memory. Java
provides ObjectInputStream class to deserialize an object. Here is an example code for deserialization:
import java.io.*;
try {
FileInputStream fileIn = new FileInputStream(""student.ser"");
ObjectInputStream in = new ObjectInputStream(fileIn);
student = (Student) in.readObject();
in.close();
fileIn.close();
} catch (IOException i) {
i.printStackTrace();
return;
} catch (ClassNotFoundException c) {
System.out.println(""Student class not found"");
c.printStackTrace();
return;
}
System.out.println(""Deserialized Student..."");
System.out.println(""Name: "" + student.name);
System.out.println(""Roll no: "" + student.rollNo);
}
}
Explanation 2
Serialization in Java is the process of converting an object into a byte stream so that it can be easily
stored in a file, sent over a network, or persisted in a database. Deserialization is the reverse process,
where the byte stream is converted back into an object. Java provides the java.io.Serializable
interface, and objects of a class that implements this interface can be serialized.
import java.io.*;
// Constructor
public Student(String name, int rollNumber) {
this.name = name;
this.rollNumber = rollNumber;
}
// Getter methods
public String getName() {
return name;
}
// Serialization
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("student.ser"))) {
oos.writeObject(student);
System.out.println("Serialization completed. Object saved to student.ser");
} catch (IOException e) {
e.printStackTrace();
}
// Deserialization
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("student.ser"))) {
Student deserializedStudent = (Student) ois.readObject();
System.out.println("Deserialization completed. Object details:");
System.out.println("Name: " + deserializedStudent.getName());
System.out.println("Roll Number: " + deserializedStudent.getRollNumber());
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
In this example:
1. The Student class implements the Serializable interface.
2. An object of the Student class is created and serialized to a file named "student.ser" using
ObjectOutputStream.
3. The same object is deserialized from the file using ObjectInputStream.
4. The details of the deserialized object are then printed.
5. Make sure to handle exceptions appropriately in a production environment. Also, note the use of
serialVersionUID to control the version of the class during deserialization. This helps prevent issues when
the class structure changes between serialization and deserialization.
Call by value means that a copy of the value of the variable is passed to the method, and any modifications
made to the variable inside the method do not affect the original variable. Here's an example:
In this example, we pass the variable `num` to the `changeValue` method, which changes the value of `x` to
10. However, when we print out `num` in the main method, it still has the value of 5, because the
`changeValue` method was only modifying a copy of the value.
Call by reference means that a reference to the original variable is passed to the method, and any
modifications made to the variable inside the method affect the original variable as well. However, Java
does not support call by reference. Instead, it simulates call by reference using object
references. Here's an example:
In this example, we pass the array `nums` to the `changeValue` method, which changes the value of the first
element in the array to 10. Since `nums` is an object reference to the array, and the `changeValue` method
also has a reference to the same array, the change made inside the method affects the original variable.
1. boolean
2. byte
3. char
4. short
5. int
6. long
7. float
8. double
String is a non-primitive data type in Java. It is an object that represents a sequence of characters.
Here's an example of declaring and initializing primitive and non-primitive variables in Java:
java
// declaring and initializing primitive variables
boolean isTrue = true;
byte byteVal = 10;
char charVal = 'A';
Note that the variables of primitive data types are initialized to default values (e.g. 0 for numeric types, false
for boolean), while non-primitive variables are initialized to null by default.
For example, suppose we have a class called Calculator with the following two methods:
Both methods are named add and accept two parameters, but the first method accepts two integers while the
second method accepts two doubles. If we call the add method with two integers, the first method will be
called. If we call it with two doubles, the second method will be called.
In this example, the add method is overloaded because it has two different versions that accept different types
of parameters.
method, but don’t override hashCode(), then the comparison of two objects will not work as expected,
because the hash codes of the two objects may not be equal.
In the above example, the Person class has been defined with two properties, name and age. The equals()
method has been overridden to compare two Person objects based on their name and age properties. The
hashCode() method has been overridden to return the hash code value of the name and age properties using
the Objects.hash() method, which returns a hash value based on the hash code values of the input objects.
This ensures that two Person objects that are equal will have the same hash code value.
Abstract class:
- An abstract class is a class that cannot be instantiated. It provides a common implementation for its
subclasses, which extends the abstract class.
Shape(String color) {
this.color = color;
}
//abstract method
abstract double area();
//non-abstract method
void getColor() {
System.out.println(""The color of the shape is "" + color);
}
}
class Test {
public static void main(String[] args) {
Shape s = new Circle(""Red"", 3);// type casting
s.getColor();
System.out.println(""The area of circle is "" + s.area());
}
}
Interface:
- An interface is a collection of abstract methods that are implemented by its implementing class.
- It cannot implement any method nor declare any variable or constructor.
- All of its methods are public abstract by default.
interface Shape {
double area();
}
Circle(double radius) {
this.radius = radius;
}
class Test {
public static void main(String[] args) {
Shape s1 = new Circle(3);
System.out.println(""The area of circle is "" + s1.area());
Shape s2 = new Rectangle(4, 5);
System.out.println(""The area of rectangle is "" + s2.area());
}
}
In Java, Strings are immutable objects, which means that once a String object is created, its value cannot be
changed. However, if we need to modify a String object, we can use either String Builder or String Buffer. Both
of these classes provide a similar functionality of appending, inserting, and deleting Strings, but there is a
difference between them.
String Builder is a non-synchronized and more efficient version of String Buffer, which means that it can be
faster in most cases. They both provide similar methods, but StringBuffer is synchronized which makes it
slower in multi-threaded environments.
Here is an example Java code that demonstrates the use of String Builder and String Buffer:
// using StringBuilder
StringBuilder sb = new StringBuilder(""Hello"");
sb.append("" World"");
String str1 = sb.toString();
// using StringBuffer
StringBuffer sbf = new StringBuffer(""Hello"");
sbf.append("" World"");
String str2 = sbf.toString();
In the above code, we create a StringBuilder and StringBuffer object and append the value "" World"" to the
existing ""Hello"" string. Finally, we convert the StringBuilder and StringBuffer objects to strings using the
toString() method.
Note that while both StringBuilder and StringBuffer can be used interchangeably in most cases, it's important
to use StringBuffer in multi-threaded environments as it is synchronized and thread-safe.
This code creates an ArrayList of integers, adds elements to the array, prints the elements of the array, gets
the size of the array, accesses an element of the array, and removes an element from the array.
In Java, you can call the default method of an interface by creating an instance of a
class that implements the interface and then calling the method on that instance.
For example, consider the following interface with a default method:
Note that if a class implements multiple interfaces that have default methods with the same name, the class
must override the default method and provide its own implementation. If the class wants to call the original
implementation of the default method, it can do so using the syntax InterfaceName.super.methodName().
In this example, we have two static methods named `print`. One takes no parameters, while the other takes
an `int` parameter. We can call either method from the `main` method, and they will behave differently based
on their parameter list.
Yes, it is possible to override a default method in an interface in Java. When a class implements an interface
that has a default method, the class can provide its own implementation for the method, effectively overriding
the default implementation provided by the interface.
When you create an instance of MyClass and call myDefaultMethod(), the custom implementation in MyClass
will be called instead of the default implementation in MyInterface.
void abstractMethod();
In this example, the interface has an abstract method, a default method, and a static method. The abstract
method does not have an implementation, while the default and static methods have their own
implementation.
However, there are ways to indirectly execute code without a main method by using alternative entry points
like static initializers, constructors, or static blocks. But these methods are not recommended as they violate
the standard Java programming conventions and can make the code difficult to understand and maintain.
Here is an example of how to execute code without a main method using a static initializer:
In this example, the static initializer block is used as an alternative entry point to execute code without the
main method. When the class is loaded into the JVM, the static block is executed first before any other code
in the class.
1. ArrayList
2. LinkedList
3. Vector (deprecated)
4. Stack (deprecated)
Can I execute multiple catch blocks without try will it give me compile time error?
No, it is not possible to execute multiple catch blocks without a try block. This will lead to a syntax error during
compilation as the catch statement is meant to handle exceptions thrown by the try block. Here's an example
of how to use try-catch block in Java:
try {
//some code that potentially throws an exception
} catch (ExceptionType1 e) {
//code to handle ExceptionType1
} catch (ExceptionType2 e) {
//code to handle ExceptionType2
} finally {
//code that is executed regardless of whether an exception was thrown or not
}
In this example, the try block contains the code that may throw an exception. If an exception of type
ExceptionType1 is thrown, the first catch block will execute to handle it. If instead, an exception of type
ExceptionType2 is thrown, the second catch block will execute. The finally block will always execute regardless
of whether an exception was thrown or not.
This code won't compile because the main method is declared as private. To fix this, we need to declare it as
public.
if(arr.length == 0) {
System.out.println(""Array is empty"");
}
To check if the array is null, we can simply check if the array reference itself is null. Here's an example:
if(arr == null) {
System.out.println(""Array is null"");
}
Here we have defined a constructor that takes in two parameters, 'name' and 'age'. When an object of the
Person class is created, the constructor will be called and the 'name' and 'age' fields will be initialized with the
values passed in.
Here the constructor is called with the arguments ""John"" and 30, and the fields 'name' and 'age' are
initialized with these values.
In summary, constructors are used to initialize the variables and objects of a class when they are created, and
they ensure that the object is in a valid state before it is used.
What is Hashmap? Can we store objects in Hashmap and how to retrieve them?
Hashmap is a data structure in Java that helps store and access key-value pairs. It provides constant time
complexity O(1) for both retrieving and storing values.
Yes, we can store objects in Hashmap. The objects can be stored as values and can be retrieved using their
corresponding keys. To retrieve an object from the Hashmap, we need to first get the value associated with
the key.
Example:
In this example, we will use a Hashmap to store employee information. Here, the keys will be the employee
IDs and the values will be custom `Employee` objects.
import java.util.HashMap;
Output:
In the above example, we store three employees in a Hashmap using their IDs as keys. We then retrieve the
employee with ID 1 using the `get()` method and access its properties using the `getName()` and `getAge()`
methods.
Where did you use HashMap in your project and also oops concepts in your
Automation Framework?
HashMap is a useful data structure that can be used in Selenium automation projects to store and retrieve
data in a key-value format.
Here are some examples of how HashMap can be used in Selenium automation:
Storing WebElements: You can use a HashMap to store WebElements by assigning a unique key to each
WebElement, such as the WebElement's ID or a custom identifier. This allows you to easily retrieve the
WebElement later by using the key as a reference. For example:
Storing test data: You can use a HashMap to store test data such as usernames, passwords, URLs, etc. by
assigning a unique key to each data item. This makes it easy to retrieve the data later in your test scripts. For
example:
Storing configuration settings: You can use a HashMap to store configuration settings for your automation
project, such as browser type, timeouts, etc. This allows you to easily modify the settings in one place and
have the changes reflected throughout your test scripts. For example:
In summary, HashMap can be used in Selenium automation projects to store and retrieve data in a key-value
format, making it easy to organize and access data in your test scripts.
1. Private: Private access modifier restricts the visibility of variables, methods, and constructors within the
same class.
Example:
2. Default: If no access modifier is specified then it is considered as default access modifier. This restricts the
visibility of variables, methods, and constructors within the same package.
Example:
class Example {
int value;
3. Protected: Protected access modifier restricts the visibility of variables, methods, and constructors within
the same package and subclasses in other packages.
Example:
4. Public: Public access modifier has full visibility. It can be accessed from anywhere in the project.
Example:
In this example, we create a class called MyThread that extends the Thread class provided by Java. We then
override the run() method to specify the code that should be executed when the thread starts. In the main
method, we create an instance of MyThread and start it by calling the start() method. The output will be
""Thread is running"".
In the above example, the class has a private constructor, ensuring that it cannot be instantiated directly. The
getInstance() method is used to retrieve the instance of the class and creates one if it doesn't exist already.
The static keyword ensures that the method is available on the class level without the need for an instance of
the class.
Static binding refers to the process of linking a function call to the function definition at the compile-time. It
occurs at the time of compilation and is used for method overloading. When you overload a method in Java,
the method call is resolved at compile-time. The decision which overloaded method to call is based on the
parameters passed during the method call.
Dynamic binding, also known as late binding, refers to the process of linking a function call to the function
definition at runtime. It occurs at the time of execution and is used for method overriding. When you override
a method in Java, the method call is resolved at runtime based on the actual class of the object on which the
method is called.
In summary, static binding is used for method overloading, while dynamic binding is used for method
overriding.
What is polymorphism?
Polymorphism is a concept in object-oriented programming that allows objects of different types to be treated
as if they are of the same type. This means that a single interface or method can be used to represent multiple
different classes. There are two types of polymorphism: compile-time polymorphism, which is achieved
through method overloading, and runtime polymorphism, which is achieved through method overriding.
For example, let's say we have a Animal class and Lion and Dog subclasses that inherit from it. We can create
an array of Animal objects that can hold both Lion and Dog objects, and call the same method on all of them:
In this example, the makeSound() method is overridden in the Lion and Dog subclasses, so it will output
different sounds depending on the class of the object that is calling it. This is an example of runtime
polymorphism.
1. Multiple inheritances - Since Java doesn't support multiple inheritance, an interface can be used to provide
the functionality of multiple inheritance.
2. Loose coupling - Interfaces make use of contract programming which in turn enables loose coupling between
different parts of the program.
3. Frameworks - Interfaces are very useful when creating frameworks, libraries or APIs. By defining an
interface, developers can ensure that users can easily integrate with their code.
In the example above, we have an interface called 'Animal' that defines the methods 'eat' and 'sleep'. We have
also created a class called 'Dog' that implements the 'Animal' interface. The 'Dog' class then overrides the
methods defined in the interface and provides its own implementation.
By using interfaces, we have ensured that any class that implements the 'Animal' interface must provide an
implementation of the 'eat' and 'sleep' methods. This provides a contract for other developers to follow and
ensures that different parts of the program can easily integrate.
1. Method overloading - Defining multiple methods with the same name but different parameters. For
example:
2. Method overriding - Overriding the implementation of an inherited superclass method in a subclass. For
example:
class Animal {
void makeSound() {
System.out.println(""Animal is making a sound"");
}
}
3. Object typecasting - Converting an object of one class to another class by explicitly stating the type of object.
For example:
In this case, we use polymorphism to treat the Dog object as an Animal object, but also to access the specific
methods and properties of the Dog class.
Why do we use finally and how it differs from the final keyword?
Finally is a block of code that is used to execute a set of statements regardless of whether an exception is
thrown or not in a try block. It is mainly used to release resources acquired in a try block. On the other hand,
the final keyword is used to declare a constant variable in Java. Once a variable is declared as final, its value
cannot be changed.
try {
//code block
} catch (Exception e) {
//exception handling
} finally {
//code that needs to be executed regardless of whether an exception occurs or not.
}
We can use multiple catch blocks when we need to handle different types of exceptions separately. For
example, if we are reading data from a file, we may need to handle FileNotFoundException if the file is not
found, and IOException if there is an error while reading the data from the file.
Here is an example code that demonstrates the use of multiple catch blocks in Java:
try {
// code that may throw exceptions
} catch (FileNotFoundException e) {
// handle FileNotFoundException here
} catch (IOException e) {
// handle IOException here
} catch (Exception e) {
// handle any other exception here
}
In this example, the first catch block will handle FileNotFoundException, the second catch block will handle
IOException, and the third catch block will handle any other exception that may occur. The order of the catch
blocks matters, and we should always catch the more specific exceptions before the more general ones.
POI:
Apache POI (Poor Obfuscation Implementation) is a Java library used for working with Microsoft Office
documents such as Excel, Word, and PowerPoint. It provides APIs to read and write Office documents with
Java programs. POI supports a variety of file formats, including XLS, XLSX, DOC, DOCX, PPTX, and many others.
To use POI for reading/writing Excel files, you need to add the following Maven dependency to your project:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
try {
FileInputStream file = new FileInputStream(new File(""data.xlsx""));
Workbook workbook = new XSSFWorkbook(file);
Sheet sheet = workbook.getSheetAt(0);
Iterator<Row> rowIterator = sheet.iterator();
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
switch (cell.getCellType()) {
case Cell.CELL_TYPE_NUMERIC:
System.out.print(cell.getNumericCellValue() + ""t"");
break;
case Cell.CELL_TYPE_STRING:
System.out.print(cell.getStringCellValue() + ""t"");
break;
}
}
System.out.println("""");
}
file.close();
} catch (Exception e) {
e.printStackTrace();
}
JXL:
JXL is a Java library used for reading/writing Excel files in the XLS format. It provides APIs to create, read, and
modify Excel files with Java programs. JXL is lightweight and easy to use but does not provide support for
newer file formats such as XLSX.
To use JXL for reading/writing Excel files, you need to add the following Maven dependency to your project:
<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6.12</version>
</dependency>
try {
Workbook workbook = Workbook.getWorkbook(new File(""data.xls""));
Sheet sheet = workbook.getSheet(0);
for (int i = 0; i < sheet.getRows(); i++) {
for (int j = 0; j < sheet.getColumns(); j++) {
Cell cell = sheet.getCell(j, i);
System.out.print(cell.getContents() + ""t"");
}
System.out.println("""");
}
workbook.close();
} catch (Exception e) {
e.printStackTrace();
}
In summary, POI and JXL are both useful Java libraries for working with Excel files. POI supports a wider range
of file formats and provides more features than JXL, while JXL is lightweight and easier to use but only supports
XLS files.
java
public class Main {
public static void main(String[] args) {
// Program execution starts from here
System.out.println(""Hello, world!"");
}
}
In the above example, the main method is declared as static, which means it can be called without creating an
instance of the Main class. The JVM calls this method at the start of the program to begin execution.
If the main method were not declared as static, the JVM would need to create an instance of the class before
it could execute the method. This would unnecessarily increase the complexity of the program's execution and
could cause issues with class loading and initialization.
1. Holding constant values that are used across the entire program.
2. Keeping track of the number of objects created from a class.
3. Storing configuration values that are used by all instances of a class.
4. Sharing data between different parts of a program.
In this example, the static variable ""myStaticVariable"" is declared at the class level, meaning it is shared
across all instances of the class. The ""myMethod"" method increments the value of the static variable each
time it is called, allowing all instances of the class to access and modify the same value.
However, we can create a concrete class that implements the interface and then instantiate the concrete class.
In this example, we first created a concrete class `MyClass` that implements the interface `MyInterface`. We
then instantiated `MyClass` and assigned it to the interface variable `obj`. Finally, we called the `myMethod()`
method through the `obj` variable, and the output was printed to the console.
However, a subclass can call a superclass constructor using the `super()` keyword, which allows it to use the
constructor of the superclass. This can be used to modify or enhance the functionality of the superclass.
For example:
In this example, the `Subclass` extends the `Superclass` and calls its constructor using `super(num)`. This allows
the `Subclass` to perform additional operations before or after the construction of the `Superclass`.
In the above example, we have declared three variables (name, age, and height) and use System.out.println
to print out their values to the console output. This will produce the following output:
Name: John
Age: 25
Height: 1.75
1. By making the method final: This will prevent any subclass from overriding the method.
Example:
2. By making the class final: This will prevent any subclass from extending the class and overriding the methods.
Example:
Both of these approaches ensure that the method cannot be overridden by any subclass, hence preventing
the override method in Java.
List is an ordered collection that allows duplicate elements. Elements are stored in the same order as they are
added to the collection. Lists are typically used when order of elements is important.
Example:
Set is an unordered collection that does not allow duplicate elements. Elements are stored in an undefined
order. Sets are typically used when uniqueness of elements is important.
Example:
fruits.add(""banana"");
fruits.add("range"");
1. Singleton Pattern: This pattern ensures that a class has only one instance and provides a global point of
access to that instance.
Example code:
private SingletonDemo(){}
2. Observer Pattern: This pattern defines a one-to-many relationship between objects so that when one object
changes state, all its dependents are notified and updated automatically.
Example code:
new HexaDecimalObserver(subject);
new OctalObserver(subject);
new BinaryObserver(subject);
3. Factory Pattern: This pattern provides a way to create objects without exposing the creation logic to the
client and refers to the newly created object through a common interface.
Example code:
interface Animal{
void makeSound();
}
class AnimalFactory{
Code example:
The output of this code will be ""Two"", which is the value stored under the key 2.
class A have 3 method, class B have 2 method, class B inherited class A, how do you
call method of class A by creating object of class B?
To call a method of class A from class B, you need to create an object of class B and call the method of class A
using super keyword. Here's an example code in Java:
class A{
public void method1(){
System.out.println(""Method 1 of class A"");
}
public void method2(){
System.out.println(""Method 2 of class A"");
}
}
class B extends A{
public void method3(){
System.out.println(""Method 3 of class B"");
}
public void method4(){
System.out.println(""Method 4 of class B"");
}
public void callSuperMethod(){
super.method1(); // calling method1 of class A
super.method2(); // calling method2 of class A
}
}
In the above example, we have two classes A and B. Class B inherits class A. Class A has two methods - method1
and method2. Class B has two additional methods - method3 and method4. In the method callSuperMethod
of class B, we are calling the methods of class A using the super keyword. When we run the main method, it
will call the method callSuperMethod of class B which in turn will call the methods of class A. Output of the
program will be:
Method 1 of class A
Method 2 of class A
class AnotherClass {
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.myMethod(); // Accessing default method from package1
}
}
And here's an example of accessing a protected class from a different package:
package package1;
class MyClass {
protected void myMethod() {
System.out.println(""This is a protected method."");
}
}
package package2;
import package1.*;
class AnotherClass extends MyClass {
public static void main(String[] args) {
AnotherClass obj = new AnotherClass();
obj.myMethod(); // Accessing protected method from package1
}
}
No, it is not possible to extend a final class in Java as the final keyword in the class declaration indicates that
the class cannot be subclassed. If an attempt is made to extend a final class, a compile-time error will occur.
Here's an example code snippet to demonstrate this:
final class FinalClass {
// class implementation
}
// Attempt to extend FinalClass
class SubClass extends FinalClass {
// Error: Cannot extend final class 'FinalClass'
}
Here, the variable MY_CONSTANT is a constant and can be accessed by implementing classes as
MyInterface.MY_CONSTANT. However, this variable cannot be initialized or changed by any implementing
class.
}
In the above code, we are trying to divide an integer by zero, which will cause an ArithmeticException. We
catch this exception in the catch block and handle it by printing an error message. Finally, we print a message
indicating that the program executed successfully.
Overriding, on the other hand, refers to the ability to define a method in a child class that has the same name
and signature as a method in the parent class. This method in the child class ""overrides"" the method in the
parent class, providing a new implementation of that method.
Here's an example:
java
public class Animal {
public void makeSound() {
System.out.println(""Animal is making a sound"");
}
}
public class Dog extends Animal {
@Override
public void makeSound() {
System.out.println(""Dog is barking"");
}
}
In this code, we have defined two classes: `Animal` and `Dog`. The `Animal` class has a method `makeSound`
that prints a generic message, while the `Dog` class overrides this method with a new implementation that
specifically says that a dog is barking.
To summarize, the key difference between overloading and overriding is that overloading is used to define
multiple methods in a class with the same name but different parameters, while overriding is used to provide
a new implementation of a method in a child class that has the same name and signature as a method in the
parent class.
return ownerName;
}
public void setOwnerName(String ownerName) {
this.ownerName = ownerName;
}
}
In the above example, we can see that Encapsulation is achieved by marking the fields (balance,
accountNumber, and ownerName) as private. The getter and setter methods are used to get and set the values
of these fields from outside the class.
Abstraction Example:
public abstract class Shape {
protected int x;
protected int y;
//constructor
public Shape(int x, int y) {
this.x = x;
this.y = y;
}
//abstract method
public abstract void draw();
}
In the above example, we can see that Abstraction is achieved by marking the class as abstract and defining
an abstract method (draw()) without providing any implementation. This indicates that any class that extends
the Shape class must implement the draw() method.
To summarize, Encapsulation is used to hide implementation details, while Abstraction is used to provide a
simplified view of an entity. Both concepts are important in Object-Oriented Programming and are used
extensively in Java.
Difference between Arraylist and Linked List, In which situation they are used?
ArrayList and LinkedList are data structures in Java with different implementations and usage scenarios. The
main differences between them are:
1. Implementation: ArrayList is implemented as a resizable dynamic array, while LinkedList is implemented as
a doubly linked list.
2. Performance: ArrayList can be faster than LinkedList for random access and iteration, while LinkedList is
more efficient than ArrayList for insertions and deletions at the beginning or in the middle.
3. Memory usage: ArrayList uses more memory than LinkedList, as it needs to allocate a certain amount of
space for its elements, while LinkedList only needs to allocate memory for each element and the pointers.
Here are examples of how to create and use ArrayList and LinkedList in Java:
ArrayList<String> arrayList = new ArrayList<>();
// add elements to the end of the list
arrayList.add(""element1"");
arrayList.add(""element2"");
arrayList.add(""element3"");
// access elements by index
String element = arrayList.get(1);
// remove elements by index
arrayList.remove(2);
// iterate over elements
for (String e : arrayList) {
System.out.println(e);
}
LinkedList<String> linkedList = new LinkedList<>();
// add elements to the end of the list
linkedList.add(""element1"");
linkedList.add(""element2"");
linkedList.add(""element3"");
// add elements to the beginning of the list
linkedList.addFirst(""element0"");
// access elements by index
String element = linkedList.get(1);
// remove elements by index
linkedList.remove(2);
// iterate over elements
for (String e : linkedList) {
System.out.println(e);
}
In general, ArrayList is more suitable for scenarios where random access and iteration over the elements are
frequent, while LinkedList is better for scenarios where insertions and deletions at the beginning or in the
middle are common. However, the actual performance may depend on the specific use case and the amount
of data involved.
Suppose you have class and abstract class in class there is a user defined constructor
and main method which one will get executed first?
The user-defined constructor will get executed first before the main method in Java.
Here is an example code to demonstrate it:
abstract class AbstractExample {
public AbstractExample() {
System.out.println(""Abstract constructor has been called"");
}
public abstract void abstractMethod();
}
public class Example extends AbstractExample {
public Example() {
super();
System.out.println(""User-defined constructor has been called"");
}
public static void main(String[] args) {
Example example = new Example();
example.abstractMethod();
}
@Override
public void abstractMethod() {
System.out.println(""Abstract method implementation"");
}
}
In the above code, we have an abstract class `AbstractExample` with a user-defined constructor and an
abstract method. The `Example` class extends the `AbstractExample` class and has its own user-defined
constructor and `main` method.
When we create an instance of the `Example` class in the `main` method, the constructor of the `Example`
class is called first, which in turn calls the constructor of the `AbstractExample` class. Finally, the
`abstractMethod` is called and its implementation is printed to the console.
Therefore, we can conclude that the user-defined constructor is executed first in Java.
In this class, we have declared three private instance variables and created constructors, getters, and setters
to access and modify the values of these variables. This class can be used to represent customers in a system,
without any framework-specific code or dependencies.
myList.add(2);
myList.add(3);
myList.add(4);
myList.add(5);
One of the main differences between arrays and ArrayLists is that arrays are fixed in size, while ArrayLists can
change in size dynamically. This means that if you need to add more elements to an array, you would need to
create a new array with a larger size and copy the elements from the old array to the new array. With an
ArrayList, you can simply use the `.add()` method to add more elements.
Another difference is that arrays can store primitive data types (such as int or char), while ArrayLists can
only store objects. To store a primitive data type in an ArrayList, you would need to use a wrapper class (such
as Integer or Character).
LIST DECLARATION?
import java.util.List;
import java.util.ArrayList;
Here, Type specifies the type of elements that the List will contain, and listName is the name of the List
variable. The implementation class used to create the List is ArrayList, which is a commonly used
implementation of the List interface.
You can use other implementations of the List interface, such as LinkedList or Vector, depending on
your specific requirements. The basic syntax for declaring a List remains the same, you just need to
replace the implementation class with the desired one
Removing duplicates: Set doesn't allow duplicate values, so you can use it to remove duplicates from a list of
elements.
Storing unique elements: If you need to store a collection of unique elements, you can use a Set.
Testing: You can use a Set to store the elements you need to test, and use its methods to check if an element
is present in the Set or not.
Performance Optimization: Set has fast lookup performance, so it's a good choice if you need to check if an
element is present in a large collection of elements frequently.
These are some of the common uses of Set in automation. However, the specific use case may vary based on
the requirements of the automation project.
I HAVE A TABLE AND WANT TO STORE ALL TABLE DATA THEN WHICH COLLECTION
SHOULD BE USE AND WHY?
The best collection to store table data in Java depends on the specific requirements of your
application.
If you have a table with fixed number of columns and rows, it is best to use a 2D array.
If you have a dynamic number of columns and rows, then ArrayList of ArrayList or HashMap of HashMap can
be used.
If you need to access the data using keys, then a HashMap is a good choice. You can store the data in key-
value pairs where the key is a unique identifier and the value is the data you want to store.
If you need to maintain the order of the data, you can use a LinkedHashMap.
If you need a thread-safe data structure, you can use a Hashtable.
Ultimately, the best collection to use will depend on your specific requirements, including the size of the
data, the type of data, and the operations you need to perform on the data.
For example:
HashMap<String, Integer> map = new HashMap<>();
map.put("A", 1);
map.put("B", 2);
map.put("C", 3);
System.out.println(map.get("A")); // Outputs 1
System.out.println(map.get("D")); // Outputs null
It's important to note that the keys in a HashMap must be unique, otherwise, the last value associated with a
duplicate key will overwrite the previous value
DO YOU KNOW OOPS CONCEPTS AND IN FRAMEWORK WHERE AND HOW YOU HAVE
IMPLEMENTED IT?
Java Object-Oriented Concepts in Selenium Automation Framework
INTERFACE
An interface in the Java programming language is an abstract type that is used to specify a behaviour
that classes must implement. An interface also contains methods and variables just like the class but
the methods declared in the interface are by default abstract.
To understand this the very basic statement we write in Selenium
In this case, WebDriver itself is an Interface. So based on this statement, WebDriver driver = new
Chromedriver(); we are initializing chrome browser using Selenium WebDriver. It means we are
creating a reference variable (driver) of the interface (WebDriver) and creating an Object. Here
WebDriver is an Interface as mentioned earlier and Chromedriver is a class.
ABSTRACTION
As we are aware, Abstraction is a process of hiding the implementation details from the user and
showing only relevant details to them. It also helps to reduce programming complexity and effort.
package Page_Object;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
public class login_page_object extends BaseClass{
@FindBy(how=How.XPATH, using="//input[@id='passwd']")
public static WebElement pswdTxtBox;
@FindBy(how=How.XPATH, using="//button[@id='SubmitLogin']//span")
public static WebElement submitBtn;
In our Automation Framework whenever we Use the Page object Model, we write all the locators in
the page class and use this locator in our test it means we are hiding our implementation from the
user this is a simple example of using abstraction in the framework.
INHERITANCE
The process by which one class acquires the properties (instance variables) and functionalities of another
class are called inheritance.
When We create a Base Class in our automation Framework to initialize WebDriver interface, waits, loggers,
reports, etc., and when we extend this Base Class in other classes such as Tests and Utility Class. In this case,
extending one class into another class is an example of implementing Inheritance.
package Page_Object;
import org.openqa.selenium.WebDriver;
package Page_Object;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
super(driver);
@FindBy(how=How.XPATH, using="//input[@id='passwd']")
public static WebElement pswdTxtBox;
@FindBy(how=How.XPATH, using="//button[@id='SubmitLogin']//span")
public static WebElement submitBtn;
}
POLYMORPHISM
Polymorphism means having many forms. Polymorphism allows us to perform a single action in
different ways. In Java polymorphism can be achieved in two ways:
METHOD OVERLOADING
If a class has multiple methods having the same name but different in parameters, it is known
as Method Overloading.
In Implicit wait when we use different time stamps such as SECONDS, MINUTES, HOURS, etc is one
of the possible examples of method overloading.
@BeforeMethod
public void setUp() throws Exception {
driver = new FirefoxDriver();
baseUrl = "http://www.google.com";
//Method Overloading any one of the below Mentioned implicitlyWait can be used
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.MINUTES);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.HOURS);
}
METHOD OVERRIDING
If the subclass or child class has the same method as declared in the parent class, it is known as
method overriding in Java.
Whenever we use a method that was already implemented/written in another class by changing its
parameters this is the example of method overriding.
class Display {
void display() {
// method invocation
object.display();
}
}
Output:
Outer class (Display) method called
Private inner class method called
Testimmutablestring.java
class Testimmutablestring{
public static void main(String args[]){
String s="Sachin";
s.concat(" Tendulkar");//concat() method appends the string at the end
System.out.println(s);//will print Sachin because strings are immutable objects
}
}
Output:
Sachin
Now it can be understood by the diagram given below. Here Sachin is not changed but a new object
is created with Sachin Tendulkar. That is why String is known as immutable.
As you can see in the above figure that two objects are created but s reference variable still refers to
"Sachin" not to "Sachin Tendulkar".
But if we explicitly assign it to the reference variable, it will refer to "Sachin Tendulkar" object.
For example:
Testimmutablestring1.java
class Testimmutablestring1{
public static void main(String args[]){
String s="Sachin";
s=s.concat(" Tendulkar");
System.out.println(s);
} }
Output:
Sachin Tendulkar
In such a case, s points to the "Sachin Tendulkar". Please notice that still Sachin object is not modified.
Why String objects are immutable in Java?
As Java uses the concept of String literal. Suppose there are 5 reference variables, all refer to one
object "Sachin". If one reference variable changes the value of the object, it will be affected by all the
reference variables. That is why String objects are immutable in Java.
Following are some features of String which makes String objects immutable.
1. ClassLoader:
A ClassLoader in Java uses a String object as an argument. Consider, if the String object is modifiable,
the value might be changed and the class that is supposed to be loaded might be different.
To avoid this kind of misinterpretation, String is immutable.
2. Thread Safe:
As the String object is immutable we don't have to take care of the synchronization that is required
while sharing an object across multiple threads.
3. Security:
As we have seen in class loading, immutable String objects avoid further errors by loading the correct
class. This leads to making the application program more secure. Consider an example of banking
software. The username and password cannot be modified by any intruder because String objects
are immutable. This can make the application program more secure.
4. Heap Space:
The immutability of String helps to minimize the usage in the heap memory. When we try to declare
a new String object, the JVM checks whether the value already exists in the String pool or not. If it
exists, the same value is assigned to the new object. This feature allows Java to use the heap space
efficiently.
package com.skilledmonster.examples.util.map;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* HashMap - Single Key and Multiple Values using List
*
**/
public class SingleKeyMultipleValueUsingList {
public static void main(String[] args) {
// create map to store
Map<String, List<String>> map = new HashMap<String, List<String>>();
// create list one and store values
List<String> valSetOne = new ArrayList<String>();
valSetOne.add("Apple");
valSetOne.add("Aeroplane");
// create list two and store values
List<String> valSetTwo = new ArrayList<String>();
valSetTwo.add("Bat");
valSetTwo.add("Banana");
// create list three and store values
List<String> valSetThree = new ArrayList<String>();
valSetThree.add("Cat");
valSetThree.add("Car");
// put values into map
map.put("A", valSetOne);
map.put("B", valSetTwo);
map.put("C", valSetThree);
// iterate and display values
System.out.println("Fetching Keys and corresponding [Multiple] Values n");
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
String key = entry.getKey();
List<String> values = entry.getValue();
Syntax:
StringBuffer s = new StringBuffer("Manas Jha automation classes");
StringBuilder:
The StringBuilder in Java represents a mutable sequence of characters. Since the String Class in Java
creates an immutable sequence of characters, the StringBuilder class provides an alternate to String
Class, as it creates a mutable sequence of characters.
Syntax:
StringBuilder str = new StringBuilder();
str.append("Manas jha");
Static keyword
In Java, the static keyword is used to create a class-level variable or method that can be accessed without
creating an instance of the class. When a member of a class is declared as static, it belongs to the class and
not to any particular instance of the class.
Static variables:
Static variables are shared among all instances of a class. They are initialized only once when the class is loaded
into memory and exist throughout the lifetime of the program. They can be accessed using the class name,
without the need for an instance of the class. For example:
class MyClass {
static int count = 0;
int id;
MyClass() {
id = count;
count++;
}
}
System.out.println(obj1.id); // Output: 0
System.out.println(obj2.id); // Output: 1
System.out.println(MyClass.count); // Output: 2
}
}
In the above example, we have a MyClass with a static variable count that is incremented each time a new
instance of the class is created. The id variable is assigned the current value of count when an instance is
created. We can access the count variable using the class name MyClass.count without creating any instances
of the class.
Static methods:
Static methods are associated with the class rather than any instance of the class. They can be called using the
class name and can access only static variables and other static methods. For example:
class MyClass {
static void printMessage() {
System.out.println("Hello, World!");
}
}
Static blocks:
Static blocks are used to initialize static variables or to perform any other static initialization tasks. They are
executed only once when the class is loaded into memory, before any static methods or variables are accessed.
For example:
class MyClass {
static int count;
static {
count = 10;
}
}
@FunctionalInterface
public interface MyFunctionalInterface {
void myMethod();
}
Optional methods: Interfaces can also define methods that are optional to implement. These methods are
marked with the @Deprecated annotation, which indicates that they may be removed in future versions of
the interface.
Example:
@Deprecated
void myOptionalMethod();
}
Overall, these updates to interfaces in Java 8 have made them much more versatile and powerful, allowing
developers to write more expressive and concise code.
This code sets an implicit wait of 10 seconds for the Chrome driver. If an element is not located within 10
seconds, the script will throw an error.
The Factory design pattern is used when you want to create objects without exposing the creation logic to the
client. In this pattern, we create an interface or abstract class for creating objects, and subclasses are
responsible for creating objects of their type. The client uses the interface to create objects, and then we can
change the implementation of subclasses without affecting the client code.
interface Animal {
void speak();
}
class AnimalFactory {
public static Animal createAnimal(String type) {
if (type.equalsIgnoreCase(""dog"")) {
return new Dog();
} else if (type.equalsIgnoreCase(""cat"")) {
return new Cat();
} else {
throw new IllegalArgumentException(""Animal type not supported."");
}
}
}
The Singleton pattern, on the other hand, is used when we need to restrict the creation of a class to only one
instance and provide global access to that instance. In this pattern, we make the constructor of the class
private and provide a static method to get the instance of the class.
class Singleton {
private static Singleton instance;
private Singleton() {
// Private constructor to prevent instantiation from outside the class
}
In short, the Factory pattern is used for creating objects, while the Singleton pattern is used for ensuring that
only one instance of a class exists.
For example, in a Selenium WebDriver framework, we can create a base class named ""BasePage"" that
contains common methods like "penPage"" and ""closePage"". Then we can create child classes like
""LoginPage"" and ""HomePage"" that inherit the methods from the ""BasePage"" class.
this.driver = driver;
}
In this example, the BasePage class contains the WebDriver instance and common methods like "penPage""
and ""closePage"". The LoginPage and HomePage classes inherit these methods and properties from the
BasePage class, and also contain methods specific to their respective pages.
java
// Assuming we have a WebDriver instance named driver
WebElement element = driver.findElement(By.id(""elementID""));
element.click(); // Click on the element
In this example, we are finding an element with the ID ""elementID"" using the By.id locator, and then
performing a click operation on it using the WebElement.click() method.
//*[@id='currentNode']/following-sibling::*
In Java, you can use the Selenium webdriver to locate elements using xpath. Here's an example of using xpath
to select a sibling element:
- get(): This method is used to load a new web page in the current browser window. It waits for the page to
load completely before returning the control to the test script.
Example:
WebDriver driver = new ChromeDriver();
driver.get(""https://www.google.com/"");
- navigate().to(): This method navigates the browser to a new web page but it does not wait for the page to
load completely before returning the control to the test script.
Example:
WebDriver driver = new ChromeDriver();
driver.navigate().to(""https://www.google.com/"");
For example, to find a single element by its id, we can use the following code:
To find multiple elements by their class name, we can use the following code:
StaleElementReferenceException is a type of Unchecked exception which is thrown when the web element
being interacted with is no longer attached to the DOM. This can happen when the page refreshes or changes
after the element is located but before it can be interacted with.
To handle StaleElementReferenceException, we can use the try-catch block. Here's an example code snippet:
try {
WebElement element = driver.findElement(By.xpath(""//input[@name='email']""));
element.sendKeys(""[email protected]"");
} catch (StaleElementReferenceException e) {
WebElement element = driver.findElement(By.xpath(""//input[@name='email']""));
element.sendKeys(""[email protected]"");
}
In the above code, we try to locate and interact with an element. If a StaleElementReferenceException is
thrown, the catch block will locate the element again and perform the desired action. This ensures that our
test doesn't fail due to an exception caused by a stale element.
In Selenium, one common exception that you may encounter is the StaleElementReferenceException. This
exception occurs when an element that was previously found by the WebDriver becomes stale, or no longer
exists in the DOM.
To handle the StaleElementReferenceException in Selenium, you can use one of the following methods:
Retry: You can try to find the element again by re-executing the same code that originally found the element.
This method can be useful if the element is likely to become available again quickly.
Wait: You can use an explicit wait to wait for the element to become available again. This can be done using
the "ExpectedConditions" class in Selenium, which provides a variety of conditions that can be used to wait
for an element to become visible, clickable, etc.
Refresh the page: You can try to refresh the page to reload the element. This can be done using the
WebDriver's "navigate().refresh()" method.
To avoid the StaleElementReferenceException in Selenium, you can use the following best practices:
Avoid caching elements: Do not store elements in variables and reuse them later. Instead, find the element
each time you need to interact with it.
Use explicit waits: Use explicit waits to wait for the element to become available before interacting with it.
This can help avoid the StaleElementReferenceException.
Avoid interacting with elements that may become stale: If you know that an element is likely to become stale,
try to interact with a different element or wait until the element becomes available again.
Use stable locators: Use locators that are unlikely to change, such as IDs or unique attributes, to find elements.
This can help avoid the StaleElementReferenceException caused by changes in the DOM.
In a web page, there are several Pop-up, but we don’t when the pop-up will appear,
in this case how we will handle the Pop-up using Selenium WebDriver (Java)
To handle Pop-ups using Selenium WebDriver (Java), you can use the Alert interface provided by WebDriver
API. You can use the following code to handle Pop-ups:
// Switch to Pop-up
Alert alert = driver.switchTo().alert();
In the above code, we first switch to the alert by using switchTo() method and Alert interface. Once we switch
to the alert, we can get alert text, dismiss or accept the alert, enter text in the alert input, or switch back to
the main window using methods provided by the Alert interface.
WebDriverWait is used to wait for the alert to appear on the screen if it is not already present. This will help
prevent exceptions and make our code more robust.
Other Way
How to handle file upload when type attribute does not file for upload web element.
In order to handle file upload when the type attribute does not specify a file upload web element, we can use
the sendKeys() method of the WebElement class. This method allows us to send the path of the file we want
to upload to the corresponding input field.
Here’s an example of how to handle file upload using sendKeys() method in Java:
java
WebElement fileInput = driver.findElement(By.xpath(“//input[contains(@class,’file-upload’)]”));
fileInput.sendKeys(“C:\Users\Documents\example.csv”);
In this example, we first locate the input element that we want to use for file upload using the findElement()
method. Then, we use the sendKeys() method to send the path of the file we want to upload to this element.
It is important to note that the path we provide to sendKeys() should be a valid path to the file on our local
machine. Also, the input element should have the necessary permissions to access the file, and the file size
should not exceed any limits set by the server.
How to cover character keyboard operation from the context menu utilizing user-
defined keyword?
To cover character keyboard operation from the context menu utilizing user-defined keyword, we can use
Selenium with Java. Here is an example code:
In this method, we are using the `Actions` class to simulate keyboard operations. We first simulate typing the
required character using the `sendKeys()` method. Then, we simulate right-clicking on the element using the
`contextClick()` method. This should open the context menu. We then simulate navigating through the context
menu by pressing the arrow keys using the `sendKeys()` method again. Finally, we select the desired option
from the context menu by pressing the Enter key.
In this example, we are finding an input element and passing the character `a` to our user-defined keyword to
simulate right-clicking on the element and selecting the option to enter `a` in the input field.
Note: This is just one way to achieve this functionality. Depending on the webpage and its elements, the code
may need to be modified accordingly.
For example, let's say we have multiple button elements on a web page with similar attributes such as class
name, value, etc. Instead of writing separate code for each button element, we can create a generic method
that takes an argument for the specific button element and performs the required action. This approach allows
us to write more reusable and maintainable code.
Here's an example of how we could use dynamic polymorphism in Selenium WebDriver with Java:
example.clickButton(button1);
example.clickButton(button2);
}
}
In this example, we have a `clickButton()` method that takes a `WebElement` as an argument and performs
the `click()` action. We then use dynamic polymorphism to pass different button elements to the method and
perform the click action on each of them.
Element has an ID that changes every time the page is loaded” in it, then which of
the following will you use?
If an element’s ID changes every time the page is loaded, then using the element’s ID to locate it in automated
tests won’t work. In this case, we will use other locating strategies such as XPath, CSS Selector, or using other
attributes of the element to locate it.
This code will find a `<div>` element that has an ID attribute containing the text ‘somePartialId’. The
`contains()` function is used to match the partial ID value. This way, we can locate the element even if its
complete ID value changes every time.
@Test
public void testSignup() {
SignupPage signupPage = new SignupPage(driver);
// Enter data using PageObject methods
signupPage.enterUsername(""John"");
signupPage.enterPassword(""Password1"");
signupPage.clickSubmit();
// Assert signup success
// ...
}
commonly used class for taking screenshots is ""java.awt.Robot."" Here's an example of how to use this class
to take a screenshot in Java:
java
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
Note that the above example code creates a screenshot of the entire screen and saves it as a PNG file. You can
modify it to capture a specific area of the screen or to save the screenshot in a different image format if
required.
Selenium uses lots of third parties jars for scripting. Then why do we still go for
selenium?
Selenium is a powerful and widely-used automation tool in the software industry, despite its reliance on third-
party jars for scripting. The main reasons why Selenium is still preferred include:
1. Selenium has a huge support community: Due to its wide popularity, there is a vast community of
automation experts who use Selenium and contribute to its development. This means that there is an
abundance of resources available for learning and troubleshooting.
2. It supports multiple languages: Selenium is designed to support multiple languages, such as Java, Python,
and C#. This provides a lot of flexibility and allows automation engineers to work with the programming
language they are most comfortable with.
3. It integrates well with other tools: Selenium has a vast network of plugins and integrations that allow it to
work seamlessly with other tools in the developer's ecosystem, such as Continuous Integration tools (CI/CD).
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class OpenBrowser {
public static void main(String[] args) {
In summary, Selenium's widespread adoption, language flexibility, and integration capabilities justify its use
despite its reliance on third-party jars.
To switch from another window to the parent window in Selenium, we need to perform the following steps:
Step 1: Get the window handle of the current window using the WebDriver object's getWindowHandle()
method.
Step 2: Get all window handles of the opened windows using the WebDriver object's getWindowHandles()
method.
Step 3: Switch to the parent window handle by iterating over each window handle and comparing it with the
current window handle. Once the parent window handle is found, switch to it using the WebDriver object's
switchTo() method.
Here is an example code snippet in Java that switches from another window to the parent window using
Selenium:
1. Flexible test configurations: TestNG allows us to configure tests using annotations or XML files. We can
include or exclude specific test methods or groups, prioritize tests, and set up dependencies between tests.
2. Data-driven testing: TestNG allows us to perform data-driven testing using DataProvider annotations. We
can pass test data from external sources such as CSV files or databases.
3. Parallel test execution: TestNG allows us to run tests in parallel to improve test performance.
4. Enhanced reporting: TestNG provides more detailed and customizable HTML reports compared to JUnit.
@Test(dataProvider = ""testData"")
public void testMethod(String param1, int param2) {
//Test code
}
@DataProvider(name = ""testData"")
public Object[][] testData() {
return new Object[][] {{""value1"", 1}, {""value2"", 2}};
}
- Implicit wait is a global wait that is applied to all elements in the WebDriver instance. It sets a timeout value
for each element to be located or interacted with before throwing a NoSuchElementException. Implicit wait
is set using the WebDriver instance:
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
On the other hand, explicit wait is a condition-based wait that applies only to specific elements. It waits for a
particular condition to be met before proceeding to the next step. Some of the conditions include element
presence, clickable, visible, or invisible. Explicit wait is set using the WebDriverWait instance:
Here, the explicit wait will wait for the element with ID ""buttonID"" to be clickable for up to 10 seconds before
proceeding to the next step.
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
Here, we first create a File object with the path to our Excel file. Then, we create a FileInputStream object to
read data from the file. Next, we create a Workbook object using the XSSFWorkbook class for Excel files in
XLSX format. We can also use the HSSFWorkbook class for XLS format.
We then get the first sheet of the workbook using the getSheetAt() method, and the first row of the sheet
using the getRow() method. Finally, we get the value of the first cell in the row using the getCell() method, and
then get the string value using the getStringCellValue() method.
We can loop through the rows and cells to read all the data from the Excel file. And for counter-question, we
may need to handle exceptions such as IOException, NullPointerException, etc., which might occur during the
execution of the code.
By using Page Factory, the WebElements of a page are initialized only once, when the page object is created.
This reduces the time and resources needed to locate WebElements when executing test cases.
Example:
@FindBy(id = ""email"")
private WebElement emailField;
@FindBy(id = ""password"")
private WebElement passwordField;
@FindBy(id = ""login-button"")
private WebElement loginButton;
To use this Page Object in your test script, you simply initialize the LoginPage object and invoke the login()
method. The WebElements are initialized automatically using PageFactory.initElements().
In the above example, the web element fields (emailField, passwordField, and loginButton) are not initialized
using the traditional method of using ""FindElement"". Instead, PageFactory.initElements() is used to initialize
the fields automatically.
driver.get(""https://www.example.com/sample.pdf"");
Thread.sleep(5000);
driver.quit();
In the above example, we are using Firefox browser and setting the download folder location to
""C:\Downloads"". We are also setting the file type to be downloaded as ""application/pdf"". After locating
and clicking the download button/link, we are waiting for 5 seconds for the file to download before closing
the browser.
@Test
public void testLocalization() {
WebDriver driver = new ChromeDriver();
String[] languages = {""en"", ""fr"", ""es""};
for (String language : languages) {
// Change language
driver.get(""http://example.com/"" + language);
In this example, we use the Selenium WebDriver to launch the Chrome browser and navigate to the website
in different languages. We then verify that the UI elements, such as the header, are properly localized by
checking if the expected text, such as ""Welcome"", is present. Finally, we also verify that form validation
messages, such as the error message for an invalid email address, are properly localized.
Even though CSS is faster than Xpath ,why do 95% of the companies use XPath ?
Although CSS selectors are generally faster and more efficient than XPath, many companies still use XPath
because it allows for more complex and precise targeting of elements within the HTML document. XPath also
provides a more flexible and expressive syntax for selecting elements, which can be especially useful for test
automation scenarios where the target elements may be dynamically generated or have variable attributes.
For example, if we wanted to select all the links on a webpage that have the text ""Login"", using CSS selectors,
we could use the following code:
driver.findElements(By.cssSelector(""a:contains('Login')""));
However, this would only work if the ""Login"" text is always contained within an <a> tag. If the text is
sometimes contained within a <span> or <div>, for instance, then we would need to use a more complex CSS
selector or resort to XPath.
By contrast, using an XPath expression, we could target all elements on the page that contain the text ""Login""
using the following code:
driver.findElements(By.xpath(""//*[contains(text(),'Login')]""));
This XPath expression will match any element on the page that contains the text ""Login"", regardless of
whether it is contained within a link or some other element.
Ultimately, the choice of using CSS or XPath selectors will depend on the specific requirements of the test
scenario and the preferences of the test automation team.
In Selenium, how to get text value from text-box if gettext() is not working?
We can use the ""getAttribute()"" method to get the value of a text-box if the ""getText()"" method is not
working. This method retrieves the value of a specified attribute of an element.
For example:
Here, we retrieve the element using the ""findElement()"" method and then use the ""getAttribute()"" method
to get its value. The attribute used here is ""value"" which gives us the text value of the text-box.
In Page object model once you create loginpage.java class what is the first thing you
start with writing initially. How are you initiating writing something into a page class?
The first thing to do after creating a LoginPage.java class in the Page Object Model is to define the page
elements or web elements of the Login page. This is done using Java annotations such as @FindBy or @FindBys
for each element on the page.
For Example:
// LoginPage.java Class
public class LoginPage {
// Web Elements
@FindBy(id = ""username"")
private WebElement username;
@FindBy(id = ""password"")
private WebElement password;
@FindBy(id = ""loginButton"")
private WebElement loginButton;
// Constructor
public LoginPage(WebDriver driver) {
PageFactory.initElements(driver, this);
}
// Methods
public void enterUsername(String username) {
this.username.sendKeys(username);
}
In the above example, we have used @FindBy annotation to define web elements such as username,
password, and loginButton on the login page. We have also included a constructor method and other methods
to interact with these web elements.
After defining the page elements, we can start writing the test methods in our Test class to test the
functionality of the Login page.
To initiate writing something into a page class, we can use page factory's initElements() method from Selenium
to initialize the page elements of the page class.
// Test class
public class LoginPageTest {
// BeforeTest method to initialize the driver
@BeforeTest
public void setUp() {
WebDriver driver = new ChromeDriver();
// Maximize the browser window
driver.manage().window().maximize();
// Navigate to the login page
driver.get(""https://www.example.com/login"");
}
// Test method
@Test
public void testLogin() {
// Create an object of LoginPage
LoginPage loginPage = new LoginPage(driver);
// Enter the username
loginPage.enterUsername(""testuser"");
// Enter the password
loginPage.enterPassword(""testpassword"");
// Click the login button
loginPage.clickLoginButton();
// Assert that the user is logged in successfully
// assertion code goes here
}
In the above example, we have first initialized the driver and navigated it to the login page. Then, we have
created an object of the LoginPage class passing the driver instance as a parameter to the constructor. After
that, we have called the methods of LoginPage to interact with the web elements of the login page. Finally,
we have written the assertion code to assert whether the user is logged in successfully or not.
@Override
public void onException(Throwable throwable, WebDriver driver) {
// Handle exception and change test behavior accordingly
}
@Override
public void afterClickOn(WebElement element, WebDriver driver) {
// Change test behavior after a click event
}
We can then register this custom listener with the WebDriver instance, and it will be used during test
execution:
// Use the eventDriver in test code instead of the original driver instance
By using this approach, we can dynamically change the behavior of our tests based on certain events that
occur during test execution.
This code finds the element with the specified ""element-id"" and scrolls the page until the element is in view
at the top of the page.
If you want to scroll the page by a specific amount, you can use the following code snippet:
This code scrolls the page down by 500 pixels. You can adjust the amount of scrolling by changing the value of
the second parameter in the ""scrollBy"" method.
For example, to switch between different windows, we can use the getWindowHandles() method to get all the
window handles. Then we can iterate over this set to get the handle of each window and switch to that window
using the switchTo() method.
Code example:
One way to find the length of a string without using the length method is by looping through the string and
counting each character. Here is an example code snippet in Java:
Both of these methods may not be as efficient as using the length method, but they provide an alternative
solution to finding the length of a string.
Write a code to reverse the code, without using the built-in method.
Here is an example code in Java language to reverse a string without using the built-in method:
You can call this function and pass the string that you want to reverse as a parameter, for example:
Output:
Original: Hello World
Reversed: dlroW olleH
java
public class HighestNumberInArray {
public static void main(String args[]) {
int[] numbers = {10, 20, 30, 40, 50, 60, 70, 80, 90};
int highestNumber = numbers[0];
for(int i = 1; i < numbers.length; i++) {
if(numbers[i] > highestNumber) {
highestNumber = numbers[i];
}
}
System.out.println(""The highest number in the array is: "" + highestNumber);
}
}
In this code, we first define an array of numbers. We then set `highestNumber` to the first element in the
array. We then loop through the rest of the array, checking if each element is greater than our current
`highestNumber`. If it is, we update `highestNumber` to that value. Finally, we print out the highest number
that we found.
"To remove duplicates from a string in Java, we can use the LinkedHashSet as it maintains the order of
elements and also removes duplicates.
Example Code:
```
public static int getStringLength(String str) {
int count = 0;
for(char c : str.toCharArray()) {
count++;
if(c == '\0') {
break;
}
}
return count;
}
```
In this code, we first initialize a counter variable `count` to 0. Then, we iterate over the characters of the string
`str` using a for-each loop. In each iteration, we increment the counter by 1 and check if the current character
`c` is a null character (`'\0'`). If we encounter a null character, we break out of the loop. Finally, we return the
count as the length of the string."
To find the largest number in an array, you can iterate through the entire array and compare each element
with the current maximum value. Here is an example Java code:
This code starts by assuming the first element as the maximum value and then compares each element with
the current maximum using a for loop. If the current element is greater than the current maximum, it updates
the maximum value. Finally, it prints out the largest number in the array."
To reverse a string without using the reverse() function, we can loop through the string and append each
character to a new string in reverse order.
```java
public String reverseString(String str) {
String reversedStr = """";
for (int i = str.length() - 1; i >= 0; i--) {
reversedStr += str.charAt(i);
}
return reversedStr;
}
```
This function takes a string as input and returns the reversed string. It uses a for loop to iterate through the
characters in the string starting from the last character (i.e. str.length() - 1) and appending each character to
a new string in reverse order.
For example, if we call the function with the input string ""hello"", it will return the string ""olleh""."
"Sure, here is the Java code to print the Fibonacci series:
```
public static void printFibonacciSeries(int n) {
int first = 0, second = 1;
System.out.print(first + "" "" + second + "" "");
for (int i = 2; i < n; i++) {
int sum = first + second;
System.out.print(sum + "" "");
first = second;
second = sum;
}
}
// Example usage
int n = 10;
printFibonacciSeries(n);
```
This code will print the first `n` numbers in the Fibonacci series, where `n` is an integer passed as input to the
`printFibonacciSeries()` method. For example, calling `printFibonacciSeries(10)` will print the first 10 numbers
in the series: `0 1 1 2 3 5 8 13 21 34`."
"Sure, here's the Java code to print only the even numbers from an array:
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 == 0) {
System.out.println(arr[i]);
}
}
This code will loop through the array and check each element to see if it's divisible by 2 (i.e., is an even
number). If it is, it will print that number to the console. If you run this code, it will output:
2
4
6
8
10
```
public class FindSpecialCharNumCapsSmallLetters {
if(Character.isLetter(ch)) {
charCount++;
if(Character.isUpperCase(ch)) {
capCount++;
} else {
smallCount++;
}
} else if(Character.isDigit(ch)) {
numCount++;
} else {
specialCharCount++;
}
}
}
```
Output:
```
Number of Characters: 36
Number of Numbers: 1
Number of Capital Letters: 3
Number of Small Letters: 32
Number of Special Characters: 3
```"
```
public class PalindromeNumberExample {
public static void main(String args[]){
int num = 121, reversed=0, remainder, original = num;
while(num != 0){
remainder = num % 10;
reversed = reversed * 10 + remainder;
num /= 10;
}
if(original == reversed){
System.out.println(original + "" is a palindrome."");
}else{
System.out.println(original + "" is not a palindrome."");
}
}
}
```
In the above code, we first declare a variable num and set its value to 121, which needs to be checked if it's a
palindrome. We declare 3 more variables - reversed, remainder and original.
We calculate the reverse of the number using the while loop and check if the original number and the reversed
number are equal. If they are equal, then the number is a palindrome. Otherwise, it's not a palindrome."
"Sure, here's an example of how to write a code to reverse a string in Java without using any built-in methods:
```
public static String reverseString(String str) {
char[] strArr = str.toCharArray();
int len = strArr.length;
In this code, we convert the input string into a character array and then use a for loop to swap the characters
at opposite ends of the array until we have traversed half of it. Finally, we convert the reversed character array
back into a string and return it."
Jenkins, etc., making it easier to execute test cases as part of the Continuous Integration process using CI/CD
tools. The following are some of the reasons why we use TestNG in our testing framework:
1. Annotation Support - TestNG provides a variety of annotations that help to better control the test case
execution. Annotations allow test cases to be marked with Pre-conditions, Post-conditions, Test data setup,
Test data cleanup, etc.
2. Test Case Grouping - TestNG provides the ability to group test cases, allowing us to execute tests with similar
or related functionalities.
3. Parallel Test Execution - TestNG offers parallel execution of test cases, enabling faster and more efficient
testing.
4. Reporting - TestNG provides detailed test reports for each test case, which allows us to identify failed test
scenarios easily.
Example Code:
import org.testng.annotations.*;
In the above code example, we define a TestNG test class using annotations `@Test`, `@BeforeMethod` and
`@AfterMethod`. The `@Test` annotation indicates that the code following the annotation will be executed as
a test method. The `@BeforeMethod` annotation indicates that the code following the annotation will be
executed before each test method, and the `@AfterMethod` annotation indicates that the code following the
annotation will be executed after each test method. We can add multiple test methods inside this class with
different annotations to control test case execution.
Out of 50 testcases, how you will run only the failed testcases?
To run only the failed test cases, we can use testNG framework in Java. We can use the ""rerun"" feature of
testNG to re-run only the failed test cases.
Steps to follow:
2. After executing all the test cases, we can get the list of failed test cases using testNG 'ITestResult' interface.
3. Then, we can set the failed test cases in the testNG XML file using the ""FailedTestRetryAnalyzer"" class to
re-run only the failed test cases.
Sample code:
@Override
public boolean retry(ITestResult result) {
if (retryCount < MAX_RETRY_COUNT) {
retryCount++;
return true;
}
return false;
}
}
Types of Listeners?
In TestNG, there are several types of listeners that can be used to perform specific actions during different
stages of the test execution process.
1. ITestListener - This listener is used to perform actions before and after a test method is executed.
For example, you can use the following code to implement ITestListener in Java:
@Override
public void onTestSuccess(ITestResult result) {
System.out.println(""Test passed: "" + result.getName());
}
@Override
public void onTestFailure(ITestResult result) {
System.out.println(""Test failed: "" + result.getName());
}
//Other methods can also be implemented to perform actions on test skip or test finish
}
2. ISuiteListener - This listener is used to perform actions before and after a test suite is executed.
For example, you can use the following code to implement ISuiteListener in Java:
@Override
public void onFinish(ISuite suite) {
System.out.println(""Suite finished: "" + suite.getName());
}
}
3. IAnnotationTransformer - This listener is used to modify the annotations of a test or suite at runtime.
For example, you can use the following code to implement IAnnotationTransformer in Java:
4. IMethodInterceptor - This listener is used to modify the test methods that are executed within a test class.
For example, you can use the following code to implement IMethodInterceptor in Java:
How many suits can be there in testNG , what if I run all the suits?
In TestNG, we can create multiple test suites based on the requirements. The number of test suites that can
be created is not limited.
If we run all the test suites, then all the tests that are included in those suites will be executed accordingly.
The test cases will run one after another in the order specified in the suite file.
For example, if we have two test suites named ""LoginSuite"" and ""RegistrationSuite"", and if we run all the
suites, TestNG will execute all the tests that are included in these two suites. This process will continue until
all the tests have been executed.
java
import org.testng.TestNG;
import org.testng.xml.XmlSuite;
import java.util.ArrayList;
import java.util.List;
This code creates two test suites (Login Suite and Registration Suite) and includes the respective test classes
in those suites. Finally, it runs both the suites using TestNG.
@RunWith(Cucumber.class)
@CucumberOptions(
features = "src/test/resources/features", // Directory path of feature files
glue = {"stepDefinitions"}, // Directory path of step definitions
plugin = {"pretty", "html:target/cucumber-reports"}) // Optional: Reports plugin for generating test
reports
Cucumber tags? And how to run different combinations of tags when multiple tags
are present
Cucumber tags are used to attach metadata to each scenario in the feature file, allowing for easy organization
as well as specified execution of specific scenarios.
To run different combinations of tags, you can use the logical operators ""and"" and "r"". For example, if you
have tags like ""@login"" and ""@admin"", you can run only the scenarios with both of these tags using the
following command:
Alternatively, you can use the "r"" operator to run scenarios that have either tag using the following command:
@login
@regression
Scenario: User logs in successfully
Given the user is on the login page
When they enter valid credentials
Then they should be taken to the dashboard
@signup
@smoke
Scenario: User can sign up
Given the user is on the sign up page
When they enter valid details
Then they should receive a confirmation message
In this example, there are four tags: ""@login"", ""@regression"", ""@signup"", ""@smoke"". The logical
operators can be used to run specific scenarios based on the tag combination you need.
What is Jenkins?
Jenkins is a popular open-source continuous integration and continuous delivery (CI/CD) tool, which is used to
automate the building, testing, and deployment of software. It provides a number of useful features, such as
scheduling builds, sending notifications, managing plug-ins, managing source code, and much more. Jenkins is
widely used in agile development environments, where fast and frequent delivery of software is critical.
Example:
Suppose, you are working on a web application that requires frequent code changes and a fast turnaround
time. To automate the testing and deployment process, you can use Jenkins. You can set up Jenkins to
automatically build, test, and deploy your code every time you make a change, using a configuration file that
specifies the build and test steps. Once the build is complete, Jenkins can automatically deploy the new code
to a staging environment for further testing, and then to the production environment after it has been
thoroughly tested. This ensures that every code change is tested and deployed quickly and reliably, which
enables you to deliver new features faster and more efficiently.
Java code:
Below is the sample Jenkins pipeline script in Java language that performs Maven-based builds:
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'mvn clean package'
}
}
stage('Test') {
steps {
sh 'mvn test'
}
}
stage('Deploy') {
steps {
sh 'mvn deploy'
}
}
}
}
Note: This is just an example, and the actual script may vary depending on the application requirements.
Today we have executed some tests using maven, but tomorrow when you see that
someone deleted all dependencies from .pom file then in that case will you be able
to execute tests or not.
No, I won't be able to execute tests if someone has deleted all dependencies from .pom file as dependencies
are necessary for executing the tests. I will need to add the dependencies back to the .pom file for successful
test execution.
Example:
Suppose, we have a Selenium automated test script that requires dependencies like Selenium WebDriver,
TestNG, and Apache POI for data-driven testing. If someone accidentally removes these dependencies from
the .pom file, then the test script won't be executed as it will not be able to recognize the imported classes. In
this case, I will need to add the dependencies back to the .pom file to ensure successful test execution.
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
The group id is used to identify the project's group or organization. It provides a unique identifier for the
project's namespace. For example, com.mycompany or org.apache.
The artifact id, on the other hand, is used to uniquely identify the project or module within the group. It gives
the name of the module such as core or web.
<groupId>com.mycompany</groupId>
<artifactId>myproject-core</artifactId>
<version>1.0.0</version>
The group id is ""com.mycompany"" and the artifact id is ""myproject-core"". In this way, we can uniquely
identify this project in the repository.
Here is an example of how these two identifiers are used in a Java project using Maven.
<project xmlns=""http://maven.apache.org/POM/4.0.0""
xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""
xsi:schemaLocation=""http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd"">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>myproject-core</artifactId>
<version>1.0.0</version>
<dependencies>
<!-- Dependencies for the core module -->
</dependencies>
</project>
In this example, the group id is ""com.mycompany"", the artifact id is ""myproject-core"", and the version is
""1.0.0"". These Maven coordinates uniquely identify this project in the repository. The dependencies for this
module are also listed in the dependencies section.
On the other hand, SOAPUI (Simple Object Access Protocol User Interface) is an open-source tool used for
testing web services. It is a protocol-based testing tool that supports SOAP (Simple Object Access Protocol),
REST, and other web services protocols.
The main difference between REST and SOAPUI is their architectural approach. REST follows a resource-based
architectural style, whereas SOAPUI follows a message-based architectural style. REST uses HTTP status codes
to handle errors and exceptions, while SOAPUI has its own set of error codes.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
System.out.println(response.toString());
}
}
This code shows how to make a GET call to a REST API endpoint and fetch data.
Method in REST.
A Method in REST refers to the HTTP verb used to interact with a resource. REST stands for Representational
State Transfer, and it is an architectural style that allows communication over HTTP to exchange resources
between clients and servers. There are various HTTP methods, such as GET, POST, PUT, DELETE, OPTIONS,
HEAD, and PATCH.
- GET Method: It is used to retrieve information or data from a resource. For example, if we want to retrieve
a list of all users from a web application, we can use the HTTP GET method. Here's an example of how to
implement GET method in Java:
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;
- POST Method: It is used to create a new resource on the server. For example, if we want to create a new user
in a web application, we can use the HTTP POST method. Here's an example of how to implement POST
method in Java:
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
These are just a few examples of how HTTP methods can be used in REST API. Depending on the requirements
of the application, different methods can be used to interact with resources.
Can you tell us about your experience with Selenium and API testing?
What types of projects have you worked on and what was your role in
those projects?
In my 11 years of experience in the software testing field, I have worked extensively with both Selenium and
API testing. I have experience in automating test cases using Selenium WebDriver, working with different
browsers and their drivers, and integrating Selenium with testing frameworks such as JUnit or TestNG.
In terms of API testing, I have used tools like Postman and SoapUI to test the functionality of APIs. I have also
worked with RESTful APIs and have experience in testing for security vulnerabilities and performance issues.
In my previous projects, I have played the role of a test automation engineer and have been responsible for
designing, developing, and executing test cases. I have also been involved in the creation of test plans, test
strategies, and test data management.
Can you walk us through your testing methodology? How do you ensure
that the software you test is of high quality and meets customer
requirements?
My testing methodology involves several steps, including requirement analysis, test planning, test case design,
test execution, and test closure.
During the requirement analysis phase, I make sure to understand the customer requirements thoroughly and
identify any potential risks or areas that need to be tested.
In the test planning phase, I create a detailed test plan that outlines the objectives, scope, and resources
required for the testing effort.
During test case design, I design test cases that cover the requirements and identify any potential scenarios
that could occur during testing.
In the test execution phase, I execute the test cases and document any issues that are found. I also work with
the development team to resolve any issues that are identified.
Finally, in the test closure phase, I document the results of the testing effort and ensure that all necessary
documentation is completed.
To ensure that the software I test is of high quality, I follow industry standard testing processes and techniques
and make use of various testing tools and methodologies. I also make sure to perform thorough regression
testing after any changes are made to the software to ensure that it continues to meet customer requirements.
Can you give an example of a complex bug that you have encountered and
how you went about resolving it?
One example of a complex bug I encountered was while testing an e-commerce platform. The platform was
supposed to display the correct price of an item after discounts were applied, but the price was incorrect in
certain cases.
I went about resolving this issue by first reproducing the bug and then examining the code to identify the root
cause of the problem. I found that the issue was caused by a mistake in the logic that was used to calculate
the discounted price.
I worked with the development team to resolve the issue and, after the fix was made, I performed thorough
regression testing to ensure that the fix had not introduced any new issues.
In the end, the issue was resolved and the platform was able to correctly display the discounted price of items.
How do you stay up-to-date with the latest testing techniques and
technologies?
I stay up-to-date with the latest testing techniques and technologies by continuously learning and exploring
new tools and methodologies. I regularly attend industry conferences and events, read industry publications
and blogs, and participate in online communities and forums.
I also like to stay abreast of the latest advancements in software testing and make sure to continuously
improve my skills and knowledge in the field.
Can you tell us about a time when you had to work with a cross-functional team to resolve a challenging issue?
How did you communicate and coordinate with the different team members to reach a resolution?
Can you describe a testing project you have led and how you managed to deliver it on time and within budget?
Can you discuss your experience with creating and maintaining automated
test suites? How do you decide which tests to automate and which to
perform manually?
In my 11 years of experience, I have created and maintained many automated test suites. To decide which tests
to automate and which to perform manually, I follow a risk-based approach. I evaluate the test cases based on
factors such as the frequency of execution, the complexity of the test case, the criticality of the feature being
tested, and the likelihood of human error. If a test case is executed frequently, is highly critical, or is prone to
human error, it is a good candidate for automation. On the other hand, if a test case is simple, rarely executed,
or is not critical to the system, it may not be worth the effort to automate.
Can you tell us about a time when you had to make a trade-off between
time and quality? How did you handle that situation and what was the
outcome?
There have been several instances where I had to make a trade-off between time and quality. One example
that comes to mind is when we were testing a critical system that had to be released by a specific deadline. We
had a large number of test cases to execute, but we had limited time to complete the testing. We prioritized
the test cases based on their criticality and executed the high-priority tests first. We also leveraged automation
to speed up the testing process. However, as a result of the time constraint, we had to compromise on the
depth of testing, and we could not execute all the test cases we had planned. We communicated the risks and
the limitations of testing to the stakeholders and released the system with the identified risks. We continued to
monitor the system in production and addressed the identified issues in subsequent releases.
Can you discuss your experience with performance testing and how you
have used tools such as JMeter or Gatling to identify performance
bottlenecks?
I have extensive experience in performance testing and have used tools such as JMeter and Gatling to identify
performance bottlenecks. I use JMeter or Gatling to simulate realistic user traffic on the system under test and
capture performance metrics such as response time, throughput, and error rates. I analyze the metrics to
identify performance bottlenecks and potential scalability issues. I also use profiling tools such as Java Flight
Recorder or VisualVM to analyze the performance of the application at the code level. Based on the identified
bottlenecks, I collaborate with the development team to optimize the system's performance. This may involve
code changes, database optimizations, or infrastructure changes. Once the identified issues are addressed, I
rerun the performance tests to confirm the improvements.
Can you discuss your experience with API testing and how you have used
tools such as Postman or SoapUI to test API functionality?
Sure, I have extensive experience with API testing, and I have used tools such as Postman and SoapUI to test
API functionality. Here are some details about my experience:
API testing approach: I follow a structured approach to API testing that involves creating test cases based on
the API's specifications and requirements. I use a combination of manual and automated testing techniques to
ensure that the API functions as expected.
API testing types: I have experience testing different types of APIs, including RESTful APIs, SOAP APIs, and
microservices. For RESTful APIs, I use HTTP methods such as GET, POST, PUT, DELETE, etc., to test various
endpoints and payloads. For SOAP APIs, I use XML-based request and response messages to test the API
functionality.
API testing tools: I have used various API testing tools, including Postman and SoapUI. These tools provide a
user-friendly interface to create and execute API test cases, and they can also generate detailed test reports.
API testing scenarios: I have tested various scenarios in APIs, including positive and negative scenarios. I test for
input validation, boundary conditions, error handling, authentication and authorization, and other functional
aspects of the API.
API automation: I have automated API test cases using tools such as Postman and SoapUI. I create automated
scripts to test the API's functionality, and I also use assertions to validate the API's response. I have also
integrated API testing into the CI/CD pipeline using tools such as Jenkins and GitLab.
In summary, my experience with API testing includes testing various types of APIs using a structured approach,
using tools such as Postman and SoapUI, testing various scenarios, and automating API test cases using
different tools.
1. Understanding API documentation: Sometimes, the API documentation is not clear or outdated, which
makes it challenging to understand the appropriate request and response formats.
2. Dealing with authentication and authorization: APIs often require authentication and authorization to
access, so testing such APIs can be challenging. It may require setting up tokens, keys, or certificates to
authenticate and authorize requests.
3. Handling data validation and parsing: APIs return data in various formats, such as XML, JSON, or HTML,
making it crucial for automated tests to validate and parse them correctly.
4. Managing different API versions: When an API has released several versions, maintaining and testing
different versions becomes a challenge due to the number of variables involved.
One example of API testing challenges is handling SSL/TLS (Secure Sockets Layer/Transport Layer Security)
errors. When an API endpoint requires SSL/TLS, but the certificate is invalid, self-signed, or expired, an SSL/TLS
error can occur. It can create difficulties in testing, and the solution is to bypass or ignore these errors during
testing.
Here's an example showing how to ignore SSL/TLS errors using Java and RestAssured library:
// Validate response
response.then().statusCode(200);
// Authentication
String username = ""john"";
String password = ""123456"";
if (username.equals(""john"") && password.equals(""123456"")) {
System.out.println(""Authentication successful"");
} else {
System.out.println(""Authentication failed"");
}
// Authorization
public class User {
private String username;
private String role;
// Usage
User user = new User();
user.setUsername(""john"");
user.setRole(""user"");
if (user.canAccessResource(""read"")) {
// Grants access to read the resource
System.out.println(""Access granted"");
} else {
System.out.println(""Access denied"");
}
For example, if a login page is not functioning properly, it could be a severe issue as it prevents users from
accessing the system. However, if a minor spelling mistake is found on a less important page, it may have low
severity. But, if the typo is on the company's logo or tagline, it could have high priority as it affects the company
image.
Here is an example code snippet that shows how to assign priority and severity to a defect using TestNG
framework in Java:
In this code, priority has been assigned as 1 (highest) and severity as CRITICAL.
Boundary value analysis involves testing the boundary values of inputs, such as the maximum and minimum
values, to ensure that the software works correctly at the limits of its input range. For example, if a software
application accepts values between 1 and 100, then the boundary values could be 1 and 100. In this case, the
test cases would be designed to check the behavior of the software at these values.
Equivalence partitioning involves dividing the input domain into partitions or groups of input values that
behave in a similar way. The aim is to test a representative sample from each partition, as testing all values in
each partition is not practical. For example, if a software application accepts values between 1 and 100, then
the input values could be divided into three partitions: values less than 1, values between 1 and 100, and
values greater than 100. In this case, test cases would be designed to test representative values from each
partition.
Both boundary value analysis and equivalence partitioning can be used to design effective test cases that can
identify defects in software. However, boundary value analysis is useful when testing the edge conditions
where software often behaves in unpredictable ways. In contrast, equivalence partitioning is useful when
testing large ranges of input values, as it reduces the number of test cases required while still ensuring that a
representative sample is tested.
Suppose you are testing a login page that allows a user to enter a username and password. The login page
specifies that the username should be between 6 and 20 characters long. In this case, you can design test cases
as follows:
Suppose you are testing a search function that allows the user to search for products by price. The search
function specifies that the price should be between $10 and $100. For this scenario, you can divide the input
values into three partitions:
Black box testing (also known as functional testing) is a software testing technique that evaluates software
functionality without knowing the internal workings of the software. The aim of black box testing is to validate
the software from an end-user perspective. It is typically performed by QA testers.
Example of white box testing: Unit testing is a type of white box testing that tests individual units of code, such
as classes or methods. For example, a developer may write a unit test to ensure that a particular method of a
class is functioning correctly.
Example of black box testing: User acceptance testing (UAT) is a type of black box testing where end-users test
the software to verify if it meets the requirements and is suitable for use. For example, a QA tester could
conduct UAT by testing a website's functionality, such as filling out forms and logging in, without knowing how
the software was implemented.
This code tests the methods of the Calculator class using the JUnit testing framework. The testAdd() method
verifies that adding 6 and 4 using the add() method of the Calculator class equals 10. The testSubtract() method
verifies that subtracting 4 from 2 using the subtract() method of the Calculator class equals 2. This is an
example of white box testing because it tests the internal implementation of the code.
Bug Triage?
Bug triage is the process of prioritizing and categorizing bugs based on their severity, impact, and other factors.
This process helps to ensure that the most critical bugs are addressed first and that resources are allocated
effectively.
For example, in an Agile software development environment, the bug triage process may involve a cross-
functional team that includes developers, testers, and product owners. The team may use a tool or
spreadsheet to track bugs, and they may assign each bug a priority level based on its severity, impact on the
user experience, and other factors. They may also categorize bugs by type (e.g., functional, performance,
security) and assign them to specific team members for resolution.
If a bug is identified in an e-commerce website that is impacting the checkout process, it would be considered
a critical bug with a high priority. The following Java code can be used to set the priority level:
In this example, the bugType variable is used to identify that the bug is related to the checkout process, and
the bugSeverity variable indicates that the bug is critical. The code then sets the bugPriority variable to
""high"" based on these conditions.
Explain severity and priority and High severity with low priority, low severity and
high priority?
Severity and priority are important terms in software testing.
Severity- It refers to the degree of impact that a bug or issue will have on the system. In simple terms, it is the
seriousness of an issue. For example, if a bank software has a bug that leads to money being transferred into
the wrong account, it would be considered a severe issue.
Priority- It refers to the level of urgency in resolving an issue. It indicates how soon the bug or issue should be
resolved, based on its impact on the system. For instance, a high priority issue would require immediate
attention, while a low priority issue may be deferred or resolved at a later time.
An example of high severity and low priority issue could be the incorrect spelling of a few words in the user
interface of a system. While it is a significant problem, it may not be an issue that requires an immediate fix.
On the other hand, a low severity and high priority issue could be a UI element that is not aligned correctly. It
may not harm the system’s functionality, but it may take a lot of effort to fix it properly.
In the above code, we have declared a logger object and used different severity levels such as debug, info,
warning, error, and fatal. This will allow developers to prioritize issues based on their severity levels.
1. Sprint Planning - a meeting where team decides on what can be achieved during the sprint and how it will
be achieved.
Example: The team discusses and plans the tasks/challenges that need to be accomplished during the sprint.
2. Daily Stand-up - a brief meeting that happens once a day during the sprint to ensure that the team is on
track and aligned to utilize their time effectively.
Example: The team gathers together for a quick 15-minute meeting to discuss their progress updates, any
recent challenges or blockers and plans for the next 24 hours.
3. Sprint Review - a showcase or demo of the completed work during the sprint to the stakeholders.
Example: The team demonstrates the functionality of the product or software to the customers and important
stakeholders.
4. Sprint Retrospective - an opportunity for the team to reflect on their performance in the last sprint and
identify areas of improvement for upcoming sprints.
Example: The team review their performance in previous sprint, highlighting what went poorly and prioritizing
improvements for the upcoming sprint.
The decision of whether to automate in the current sprint or the next sprint depends on the specific project's
requirements and context. However, a general guideline is to automate in the same sprint as the development
work. This approach ensures that the team will complete the automated tests simultaneously with the
development work, which helps to identify and fix defects at an early stage.
Furthermore, if the team automates in the same sprint, they can get feedback on whether the automated
tests are working well for the features they are testing. If the automated tests show defects or do not provide
coverage for the expected user behavior, the team will have the entire sprint to refine the tests.
On the other hand, if the project has a tight schedule and the team cannot automate in the same sprint, they
should plan to automate in the next sprint. However, in such cases, the team should ensure that they have the
necessary resources, skills, and tools required for automation before starting the actual testing process.
Example: Suppose the team is working on developing a new feature that has complex business rules and a
large number of test cases. In such cases, it may not be possible to automate all the test cases in the same
sprint. In this situation, the team can split the test cases into high, medium, and low priority categories and
start by automating the high priority ones. Once the development work is complete, the team can start
automating the remaining test cases in the next sprint.
Velocity is calculated by adding up the effort estimates for all completed user stories in the previous sprints.
For example, if a team completes 5 user stories in a sprint, and each story is estimated at 8 points, then the
team's velocity for that sprint is 40 points.
The velocity metric helps the team to understand how much work they can realistically complete in each
sprint, which can be used to plan future sprints and make adjustments to the team's capacity and workload
accordingly. It can also be used to track the progress of the team's work against their overall goals.
Suppose if we give manual testing for six months or one year what will you do?
As an automation expert, I would suggest implementing automation testing to reduce the manual testing
efforts and improve efficiency. This would involve analyzing the manual test cases, creating test scripts, and
executing them using automation tools.
For example, if we have a regression test suite with over 500 manual test cases, we can use an automation
tool like Selenium WebDriver to automate the test cases. This would reduce the time and effort required to
execute the regression tests, and the tests can be run more frequently.
Additionally, I would also recommend introducing agile methodologies to enhance the testing process further.
This would involve breaking down the testing tasks into smaller, manageable chunks and working in iterations.
Agile testing would help to identify defects early on in the development cycle and allow for faster feedback
and bug fixes.
Overall, leveraging automation testing and agile methodologies would significantly improve the efficiency and
effectiveness of the testing process.
We can handle frames in Selenium using the switchTo() method. We can switch to the frame using the name,
id or index. Here is an example code in Java:
For example, to switch between different windows, we can use the getWindowHandles() method to get all the
window handles. Then we can iterate over this set to get the handle of each window and switch to that window
using the switchTo() method.
Code example:
Write a code to reverse the code, without using the built-in method.
Here is an example code in Java language to reverse a string without using the built-in method:
You can call this function and pass the string that you want to reverse as a parameter, for example:
Output:
Original: Hello World
Reversed: dlroW olleH
For example, a common use case of listeners is to capture screenshots or videos of test cases when they fail,
and attach them to the test report. This can help in identifying the root cause of a test failure, and provide
more context to the stakeholders.
Here’s an example code snippet of how to implement a TestNG listener to capture screenshots on test failure:
java
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;
@Override
public void onTestFailure(ITestResult tr) {
super.onTestFailure(tr);
WebDriver driver = TestBase.getDriver(); // Get the WebDriver instance
TakesScreenshot sc = (TakesScreenshot) driver;
byte[] screenshot = sc.getScreenshotAs(OutputType.BYTES); // Capture screenshot as bytes
tr.setAttribute(""screenshot"", screenshot); // Store the screenshot in ITestResult
}
In this example, we extend the TestListenerAdapter class from TestNG, and override the `onTestFailure()`
method to capture a screenshot using Selenium’s `TakesScreenshot` interface. We then store the screenshot
as a byte array in the `ITestResult` object, which can be accessed later by the reporting framework.
Types of Listeners?
In TestNG, there are several types of listeners that can be used to perform specific actions during different
stages of the test execution process.
1. ITestListener - This listener is used to perform actions before and after a test method is executed.
For example, you can use the following code to implement ITestListener in Java:
@Override
public void onTestSuccess(ITestResult result) {
System.out.println(""Test passed: "" + result.getName());
}
@Override
public void onTestFailure(ITestResult result) {
System.out.println(""Test failed: "" + result.getName());
}
//Other methods can also be implemented to perform actions on test skip or test finish
}
2. ISuiteListener - This listener is used to perform actions before and after a test suite is executed.
For example, you can use the following code to implement ISuiteListener in Java:
@Override
public void onFinish(ISuite suite) {
System.out.println(""Suite finished: "" + suite.getName());
}
}
3. IAnnotationTransformer - This listener is used to modify the annotations of a test or suite at runtime.
For example, you can use the following code to implement IAnnotationTransformer in Java:
4. IMethodInterceptor - This listener is used to modify the test methods that are executed within a test class.
For example, you can use the following code to implement IMethodInterceptor in Java:
- Compile-time dependencies: These are required for the project's source code to compile. They are
automatically included in the classpath during build time.
- Runtime dependencies: These are required for the application to run. Maven does not include these
dependencies in the classpath during build time. Instead, they are downloaded at runtime from the repository.
To handle runtime dependencies, Maven provides a plugin called the Maven Dependency Plugin. This plugin
allows you to list all the runtime dependencies of the project and download them to a specified location.
Example code for downloading runtime dependencies using Maven Dependency Plugin in Java:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.2</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/dependency-jars/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
mvn dependency:copy-dependencies
This will download all the runtime dependencies to the specified directory.
3. You can now add the downloaded JAR files to the classpath during runtime using the following command:
This will include all the runtime dependencies along with the project's compiled classes in the classpath.
Example:
Let's assume you want to create a Jenkins job for a Java application. You can follow the steps mentioned above
and configure the job as follows:
Now, every time there is a new commit to the Git repository, Jenkins will automatically trigger a build process
for the Java application, compile and package it using Maven.
On the other hand, SOAPUI (Simple Object Access Protocol User Interface) is an open-source tool used for
testing web services. It is a protocol-based testing tool that supports SOAP (Simple Object Access Protocol),
REST, and other web services protocols.
The main difference between REST and SOAPUI is their architectural approach. REST follows a resource-based
architectural style, whereas SOAPUI follows a message-based architectural style. REST uses HTTP status codes
to handle errors and exceptions, while SOAPUI has its own set of error codes.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
response.append(line);
} in .close();
System.out.println(response.toString());
}
}
This code shows how to make a GET call to a REST API endpoint and fetch data.
// Authentication
String username = ""john"";
String password = ""123456"";
if (username.equals(""john"") && password.equals(""123456"")) {
System.out.println(""Authentication successful"");
} else {
System.out.println(""Authentication failed"");
}
// Authorization
public class User {
private String username;
private String role;
}
}
return false;
}
}
// Usage
User user = new User();
user.setUsername(""john"");
user.setRole(""user"");
if (user.canAccessResource(""read"")) {
// Grants access to read the resource
System.out.println(""Access granted"");
} else {
System.out.println(""Access denied"");
}
For example, if a login page is not functioning properly, it could be a severe issue as it prevents users from
accessing the system. However, if a minor spelling mistake is found on a less important page, it may have low
severity. But, if the typo is on the company's logo or tagline, it could have high priority as it affects the company
image.
Here is an example code snippet that shows how to assign priority and severity to a defect using TestNG
framework in Java:
In this code, priority has been assigned as 1 (highest) and severity as CRITICAL.
Boundary value analysis involves testing the boundary values of inputs, such as the maximum and minimum
values, to ensure that the software works correctly at the limits of its input range. For example, if a software
application accepts values between 1 and 100, then the boundary values could be 1 and 100. In this case, the
test cases would be designed to check the behavior of the software at these values.
Equivalence partitioning involves dividing the input domain into partitions or groups of input values that
behave in a similar way. The aim is to test a representative sample from each partition, as testing all values in
each partition is not practical. For example, if a software application accepts values between 1 and 100, then
the input values could be divided into three partitions: values less than 1, values between 1 and 100, and
values greater than 100. In this case, test cases would be designed to test representative values from each
partition.
Both boundary value analysis and equivalence partitioning can be used to design effective test cases that can
identify defects in software. However, boundary value analysis is useful when testing the edge conditions
where software often behaves in unpredictable ways. In contrast, equivalence partitioning is useful when
testing large ranges of input values, as it reduces the number of test cases required while still ensuring that a
representative sample is tested.
Suppose you are testing a login page that allows a user to enter a username and password. The login page
specifies that the username should be between 6 and 20 characters long. In this case, you can design test cases
as follows:
Suppose you are testing a search function that allows the user to search for products by price. The search
function specifies that the price should be between $10 and $100. For this scenario, you can divide the input
values into three partitions:
Black box testing (also known as functional testing) is a software testing technique that evaluates software
functionality without knowing the internal workings of the software. The aim of black box testing is to validate
the software from an end-user perspective. It is typically performed by QA testers.
Example of white box testing: Unit testing is a type of white box testing that tests individual units of code, such
as classes or methods. For example, a developer may write a unit test to ensure that a particular method of a
class is functioning correctly.
Example of black box testing: User acceptance testing (UAT) is a type of black box testing where end-users test
the software to verify if it meets the requirements and is suitable for use. For example, a QA tester could
conduct UAT by testing a website's functionality, such as filling out forms and logging in, without knowing how
the software was implemented.
This code tests the methods of the Calculator class using the JUnit testing framework. The testAdd() method
verifies that adding 6 and 4 using the add() method of the Calculator class equals 10. The testSubtract() method
verifies that subtracting 4 from 2 using the subtract() method of the Calculator class equals 2. This is an
example of white box testing because it tests the internal implementation of the code.
Verification is the process of evaluating the software system or component to determine whether it meets
specified requirements and standards. It focuses on determining whether the software is built according to
the design specifications and requirements.
On the other hand, validation is the process of evaluating the software system or component to determine
whether it meets the expectations and requirements of the end user. It focuses on determining whether the
software meets the customer's needs and requirements.
An example of verification is testing the login functionality of a website to ensure that it meets the specified
requirements, such as verifying that the correct username and password are accepted, and incorrect ones are
rejected.
An example of validation is testing the usability of the website, such as ensuring that users can easily navigate
through the website and find the information they need.
Explain severity and priority and High severity with low priority, low severity and
high priority?
Severity and priority are important terms in software testing.
Severity- It refers to the degree of impact that a bug or issue will have on the system. In simple terms, it is the
seriousness of an issue. For example, if a bank software has a bug that leads to money being transferred into
the wrong account, it would be considered a severe issue.
Priority- It refers to the level of urgency in resolving an issue. It indicates how soon the bug or issue should be
resolved, based on its impact on the system. For instance, a high priority issue would require immediate
attention, while a low priority issue may be deferred or resolved at a later time.
An example of high severity and low priority issue could be the incorrect spelling of a few words in the user
interface of a system. While it is a significant problem, it may not be an issue that requires an immediate fix.
On the other hand, a low severity and high priority issue could be a UI element that is not aligned correctly. It
may not harm the system’s functionality, but it may take a lot of effort to fix it properly.
In the above code, we have declared a logger object and used different severity levels such as debug, info,
warning, error, and fatal. This will allow developers to prioritize issues based on their severity levels.
Here's an example of code to check if a certain number of test cases have passed:
Where 'numberOfPassingTests' is a variable tracking the number of test cases that have passed and
'stopTesting()' is a method to cease testing.
The decision of whether to automate in the current sprint or the next sprint depends on the specific project's
requirements and context. However, a general guideline is to automate in the same sprint as the development
work. This approach ensures that the team will complete the automated tests simultaneously with the
development work, which helps to identify and fix defects at an early stage.
Furthermore, if the team automates in the same sprint, they can get feedback on whether the automated
tests are working well for the features they are testing. If the automated tests show defects or do not provide
coverage for the expected user behavior, the team will have the entire sprint to refine the tests.
On the other hand, if the project has a tight schedule and the team cannot automate in the same sprint, they
should plan to automate in the next sprint. However, in such cases, the team should ensure that they have the
necessary resources, skills, and tools required for automation before starting the actual testing process.
Example: Suppose the team is working on developing a new feature that has complex business rules and a
large number of test cases. In such cases, it may not be possible to automate all the test cases in the same
sprint. In this situation, the team can split the test cases into high, medium, and low priority categories and
start by automating the high priority ones. Once the development work is complete, the team can start
automating the remaining test cases in the next sprint.
Backlog in Scrum methodology refers to a prioritized list of tasks or features that need to be completed in
order to achieve the project goals. It is a living document that is constantly updated by the product owner,
based on feedback from stakeholders and the development team.
The Scrum backlog typically consists of user stories, bugs, technical tasks, and other requirements that are
broken down into small, manageable chunks of work. These items are prioritized based on business value,
degree of complexity, and other factors that are important to the project.
For example, a backlog for a web application could consist of items such as ""Allow users to register and log
in,"" ""Implement a search functionality,"" or "optimize website speed."" Each item in the backlog is given a
priority score, which is used to determine the order in which the development team will work on them.
Suppose if we give manual testing for six months or one year what will you do?
As an automation expert, I would suggest implementing automation testing to reduce the manual testing
efforts and improve efficiency. This would involve analyzing the manual test cases, creating test scripts, and
executing them using automation tools.
For example, if we have a regression test suite with over 500 manual test cases, we can use an automation
tool like Selenium WebDriver to automate the test cases. This would reduce the time and effort required to
execute the regression tests, and the tests can be run more frequently.
Additionally, I would also recommend introducing agile methodologies to enhance the testing process further.
This would involve breaking down the testing tasks into smaller, manageable chunks and working in iterations.
Agile testing would help to identify defects early on in the development cycle and allow for faster feedback
and bug fixes.
Overall, leveraging automation testing and agile methodologies would significantly improve the efficiency and
effectiveness of the testing process.
Suppose you are the leam QA and 1 new member join your team and at the same
time you have a deadline to meet in next 2 or 3 days so how will you involve that
new member in team so that you can utilise him/her to meet deadlines?
As the lead QA, I will first introduce the new member to the team and provide an overview of the project and
its deadlines. I will assign the new member with smaller tasks that are crucial for the project and assist him/her
in understanding the project structure, requirements, and testing methodology. This will help the new
member to get acquainted with the project and be productive from the beginning.
Furthermore, I will create a checklist of tasks that need to be completed to meet the deadline and assign
different tasks to different team members including the new member. This will ensure that each team member
is aware of their responsibility and the project is progressing towards its completion.
For instance, if the project involves test automation, I will assign the new member with the task of preparing
test data or creating automation scripts for smaller modules. This will free up more time for experienced team
members to work on more complex scenarios or issues.
After you have run a full regression test, and find new regression bugs, which bugs
would you prioritize. Bugs that suggest that functionality has regressed, or bugs that
appear in new features?
As an automation expert, I would prioritize the bugs that suggest that functionality has regressed after a full
regression test. These bugs may indicate that previously working functionality has been affected by changes
made during development or maintenance. If these issues are not fixed, they can not only impact the existing
functionality but can also affect the system's overall stability.
On the other hand, bugs that appear in new features can also be critical, but they may not necessarily pose an
immediate threat to a system's stability. They can be addressed in subsequent releases or sprints, depending
on their severity and impact on the overall system.
For example, suppose a regression test identifies a critical bug in a payment processing feature that is affecting
the system's core functionality. In that case, it would be prioritized over a bug in a new feature such as a
reporting tool with a lower severity level.
// Switch to alert
Alert alert = driver.switchTo().alert();
// Click OK on alert
alert.accept();
In this example, we first switch to the alert using the `driver.switchTo().alert()` method. We can then get the
text of the alert using the `getText()` method. We can click on the OK button of the alert using the `accept()`
method, or cancel it using the `dismiss()` method. We can also enter text in a prompt alert using the
`sendKeys()` method.
1. Navigation to URL: This command is used for opening a web page or website by providing its URL. For
example:
driver.get(""https://www.example.com/"");
2. Navigation commands for forward and backward: These commands are used for navigating backward and
forward in the application. For example:
driver.navigate().back();
driver.navigate().forward();
3. Refresh command: This command is used to refresh the current web page. For example:
driver.navigate().refresh();
4. Navigation to specific element: This command is used to navigate to a certain web element on the page. For
example, let's say we want to navigate to a button with the ID of ""exampleButton"":
5. Navigation to specific frame: This command is used to navigate to a certain frame on the page. For example,
let's say we want to navigate to a frame with the ID of ""exampleFrame"":
driver.switchTo().frame(""exampleFrame"");
Assert: In assert, when a condition fails, the test is immediately aborted and marked as failed. It is used to
validate a condition, and the test case is considered failed if the assertion fails.
Example:
Here, if the actual title and expected title are not equal, the test will fail and the assertion will not allow the
execution of further steps.
Verify: In verify, when a condition fails, the test does not immediately abort. It is used to validate a condition,
and the test case continues to execute even if the verification fails.
Example:
Here, even if the actual title and expected title are not equal, the test will continue executing and allow the
execution of further steps.
One approach is to use testng data providers in Java. Testng is a testing framework that provides data providers
to feed data to test cases. Here’s an example code that uses data providers to manage data tables in Selenium:
driver.findElement(By.id(""lastName"")).sendKeys(lastName);
driver.findElement(By.id(""email"")).sendKeys(email);
driver.findElement(By.id(""password"")).sendKeys(password);
// Submit Form
driver.findElement(By.id(""submit"")).click();
// Assert Registration Success
Assert.assertEquals(driver.getCurrentUrl(), ""https://www.example.com/success"");
}
In this example, the `userData()` data provider returns an array of arrays that represent the data table. The
`registerUser()` tests uses the data provider to feed data to the test case. The test case opens the registration
page, fills the user registration form with the data provided by the data provider, submits the form, and asserts
if the registration was successful.
By using data providers, managing data tables in Selenium becomes much easier and more efficient.
Here is an example code snippet in Java using the WebDriverWait class to wait for a specific element in a
dynamic web table:
This code first finds the web table element and then creates a WebDriverWait instance with a timeout of 10
seconds. It then waits for the specified value ""dynamicValue"" to be present in the table using the
""textToBePresentInElement"" condition. Once the value is found, the code performs actions on the dynamic
web table such as finding a specific row and clicking on it.
CSS locator is faster than Xpath due to the way they are processed by the browser. CSS locators are processed
directly by the browser's engine and are optimized for speed, while Xpath locators require the browser to
search through the entire HTML DOM tree, which can be slow and resource-intensive.
html
<div class=""example"">
<h1>Title</h1>
<p>Paragraph</p>
</div>
One way to select the ""Title"" element using CSS locator would be:
css
.example > h1
In this case, the CSS locator would be faster, since it only needs to traverse one level of the DOM tree to find
the ""Title"" element, while the Xpath locator needs to traverse two levels.
Error is throwing as Element not found but when I go and check that element is
available in the web page? The element is not hidden so no need to use Java script
executor? How do you solve this?
This could be due to a timing issue where the element is not yet fully loaded at the time of the script execution.
You can try implementing a wait mechanism to allow the element to fully load before accessing it.
One example of using the explicit wait in Selenium WebDriver with Java:
This code will wait for a maximum of 10 seconds for the element with ID ""elementID"" to become visible on
the page. Once it is visible, the element is returned and can be interacted with.
To execute using headless mode in Selenium WebDriver with Java, you first need to create a new
ChromeOptions object and set the ""--headless"" option to true. Then, you need to pass this object to the
ChromeDriver constructor.
Here's an example:
This code will launch Chrome in headless mode, meaning the browser window won't be displayed. You can
then use the WebDriver methods to perform automated tasks in the headless browser.
If we are using correct locator but still getting element not found error then how you
will resolve this error?
There could be several reasons for the element not found error, even if we are using the correct locator. Some
possible solutions are:
1. Wait for the element: There might be a delay in page load or rendering the element. We can apply an explicit
wait using WebDriverWait class in Selenium to wait for the element to appear on the page.
Example:
2. Check if the element is present in the HTML DOM: Sometimes, the element might not be in the DOM yet or
might be present in an iframe. We can check if the element is present in the DOM by using
driver.getPageSource() method.
Example:
if(driver.getPageSource().contains(""elementId"")){
3. Verify the correctness of the locator: There might be a mistake in the locator or the element might have
changed its attribute values. We can verify the locator by using browser developer tools or some locator
validation tools like SelectorGadget.
Example:
if(element.isDisplayed()){
element.sendKeys(""username"");
If none of the above solutions work, we can also try to debug the issue by adding some logging or breakpoints
to locate where the issue is.
1. Using WebDriver's executeScript() method: This method allows you to execute JavaScript on the page and
manipulate the hidden element. For example:
2. Using Actions class: Actions class can be used to perform actions on the hidden element. For example:
3. Using FluentWait: FluentWait can be used to wait until the hidden element becomes visible. For example:
Note: It is important to note that manipulating hidden elements may not be ideal as they are hidden for a
reason and changes to them may adversely affect the functioning of the page.
In this code, ""elementId"" should be replaced with the ID of the element you want to click the right mouse
button on. The actions class is used to perform the contextClick method, which simulates a right-click on the
element.
Alternatively, we can use the Robot class from the Java AWT (Abstract Window Toolkit) package to perform a
right mouse click. Here's an example code:
import java.awt.Robot;
import java.awt.event.InputEvent;
In this code, the mousePress and mouseRelease methods simulate a right-click on the current mouse position.
However, this approach is not recommended for use with Selenium WebDriver as it does not interact with the
browser directly.
With Selenium, I would use the WebDriver API to locate and interact with elements within the application. For
example, to click a button I would use the following Java code:
To automate a Windows desktop application, I would use WinAppDriver. This allows me to use Selenium's
WebDriver API to interact with the desktop application's UI elements. For example, to click a button in a
desktop application I would use the following Java code:
// Before swapping
System.out.println(""String 1: "" + str1);
System.out.println(""String 2: "" + str2);
// After swapping
System.out.println(""String 1: "" + str1);
System.out.println(""String 2: "" + str2);
Output:
String 1: Hello
String 2: World
String 1: World
String 2: Hello
In the above code, we first concatenate both strings into str1. Then, we use substring() method to extract the
original values and assign them to str2 and str1 respectively.
In this code, we first initialize an empty string `reversedStr`. Then we iterate through each character in the
original string `str`, starting from the last character (i.e. index `str.length()-1`) and going backwards to the first
character (i.e. index `0`). For each character, we append it to the `reversedStr` using the `+=` operator, which
is shorthand for `reversedStr = reversedStr + str.charAt(i);`. Finally, we return the reversed string.
Here, we're passing an integer array as a parameter to the `printEvenNumbers` method. Inside the method,
we're using a for-each loop to iterate over each element of the array. For each element, we're checking if it's
divisible by 2 using the modulo operator. If the modulo result is 0, then it's an even number, so we're printing
it using the `System.out.print` method.
Example usage:
Write a Java code to identify, if the pair of strings are an Anagram or not?
An anagram is a word or phrase that can be formed by rearranging the letters of another word or phrase. To
identify if two strings are anagrams or not, we can check if they consist of the same set of characters, regardless
of their position.
Here's the Java code to check if two strings are anagrams or not:
import java.util.Arrays;
if (isAnagram(s1, s2)) {
System.out.println(s1 + "" and "" + s2 + "" are anagrams"");
} else {
System.out.println(s1 + "" and "" + s2 + "" are not anagrams"");
}
}
}
In this example, we first convert the input strings to lowercase characters and then sort them using the
`Arrays.sort()` method. We then compare the two sorted character arrays using the `Arrays.equals()` method.
For the input strings ""LISTEN"" and ""SILENT"", the method should return true because both strings consist
of the same set of characters.
Note that this implementation is case-insensitive, meaning that it will consider ""Listen"" and ""silent"" as
anagrams as well. If case sensitivity is desired, remove the `toLowerCase()` method calls.
1. Flexible Test Suite Configuration: TestNG allows the user to build and configure test suites in various ways,
allowing the user to run tests the way they want.
2. Parallel Test Execution: TestNG supports parallel test execution, enabling faster test execution times and
reduced test execution time.
3. Grouping and Prioritizing Tests: TestNG enables grouping and prioritizing tests to run first or at last,
providing better control over test execution.
4. Rich Annotation Support: TestNG provides rich annotation support, which allows developers to add
metadata to the test case, making it easy to understand the test results.
5. Easy Configuration: TestNG provides simple and easy test configuration and integration with third-party
tools like Maven.
Example:
@Test annotation is the core feature of the TestNG framework. It is used to identify the method as a test
method and run it as part of the test case. For example, consider the code below:
@Test
public void testMethod() {
// test code goes here
}
}
In the above example, the @Test annotation marks the method as a test method, and TestNG will execute the
code inside the method as part of the test case. This allows developers to easily identify which methods are
test methods, and which ones are not.
For example, using Java, we can write a unit test that checks if an XML file contains valid and expected data.
We can use the following code to read the XML file and validate its structure using an XML schema:
@Test
public void testXmlStructure() throws Exception {
// Load the XML file
InputStream xmlInput = getClass().getClassLoader().getResourceAsStream(""test.xml"");
This code reads an XML file called ""test.xml"" and validates its structure against an XML schema called
""test.xsd"". If the XML file does not match the schema, the XML validator will throw an exception, which will
cause the test to fail.
Case Scenario: How to run the same method 100 times in TestNG with the same
data?
To run the same method 100 times in TestNG with the same data, we can use the ""dataProvider"" attribute
of the TestNG framework. The dataProvider attribute allows us to pass the same data to the same test method
multiple times. Here's how we can do it:
1. Create a data provider method that returns the same data each time it is called. For example:
@DataProvider(name = ""myDataProvider"")
public Object[][] getData() {
Object[][] data = new Object[1][1];
data[0][0] = ""myTestData"";
return data;
}
2. In the test method, use the dataProvider attribute to specify the data provider method and the number of
times to repeat the test. For example:
In this example, the test method ""myTestMethod"" will be called 100 times, each time with the same test
data ""myTestData"". You can modify the data provider method to return different data if needed.
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@DataProvider(name = ""myDataProvider"")
public Object[][] getData() {
Object[][] data = new Object[1][1];
data[0][0] = ""myTestData"";
return data;
}
xml
<!DOCTYPE suite SYSTEM ""http://testng.org/testng-1.0.dtd"" >
<suite name=""MyTestSuite"" verbose=""1"">
<test name=""MyFirstTest"">
<classes>
<class name=""com.example.TestClass1"" />
</classes>
</test>
<test name=""MySecondTest"">
<classes>
<class name=""com.example.TestClass2"" />
</classes>
</test>
</suite>
java
@Test(dependsOnMethods = { ""loginTest"" })
public void homePageTest() {
// Test code
}
In this example, the homePageTest method depends on the loginTest method to be executed first.
xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
In this example, the surefire plugin is configured to execute the TestNG XML file located at
src/test/resources/testng.xml.
1. @Test: This is the main annotation that is used to identify a test method. It can also be used to set priority,
enable/disable the test method, and define expected exceptions.
Example:
@Test(priority=1)
public void loginTest() {
// Test code goes here
}
2. @BeforeTest: This annotation is used to execute a method before any of the test methods in a test class.
This is useful for setting up test data or performing any other necessary setup tasks.
Example:
@BeforeTest
public void setUp() {
// Test setup goes here
}
3. @AfterTest: This annotation is used to execute a method after all the test methods in a test class have been
run. This is useful for cleaning up any resources or data created during the test.
Example:
@AfterTest
public void tearDown() {
// Test cleanup goes here
}
4. @DataProvider: This annotation is used to provide test data to a test method. A method annotated with
@DataProvider must return a two-dimensional array of objects.
Example:
@DataProvider(name = ""testData"")
public Object[][] provideTestData() {
// Test data generation code goes here
}
5. @Parameters: This annotation is used to pass parameter values to a test method. The parameter values can
be obtained from testng.xml or from the command line.
Example:
@Test
@Parameters(""username"")
public void loginTest(String username) {
// Test code goes here
}
These are just a few of the many annotations available in TestNG. Other annotations include @BeforeMethod,
@AfterMethod, @BeforeClass, @AfterClass, @BeforeSuite, and @AfterSuite.
In this example, we have defined a suite named ""My Test Suite"" with a test named ""My Test"". The test
includes two classes, ""MyTestClass"" and ""MyOtherTestClass"", which contain the actual test methods.
You can also use various TestNG annotations to configure your tests, such as @Test, @BeforeTest, @AfterTest,
@BeforeClass, and @AfterClass. These annotations allow you to control the order in which tests are run, set
up test data, and clean up after tests.
@BeforeClass
public void setUp() {
// Set up test data and environment
}
@Test
public void testMethod() {
// Perform test actions and assertions
}
@AfterClass
public void tearDown() {
// Clean up test data and environment
}
}
What is @dataprovider?
@DataProvider is an annotation in TestNG framework that enables data-driven testing, i.e., executing the
same test method with different test data. It allows the tester to pass a set of parameters to the test method
as arguments. The values are provided through this annotation to the test method as arguments. Each set of
values is considered as a test case.
@DataProvider(name = ""testData"")
public Object[][] getData() {
return new Object[][] {
{ ""user1"", ""password1"" },
{ ""user2"", ""password2"" },
{ ""user3"", ""password3"" }
};
}
@Test(dataProvider = ""testData"")
public void loginTest(String username, String password) {
// Perform login operation using the provided credentials
// Assertion and other operations
}
In the above example, `getData()` method is annotated with @DataProvider and it returns a 2-D object array,
i.e., the set of test data. The `loginTest()` method is annotated with @Test and dataProvider attribute is set to
""testData"". This means `loginTest()` method will be executed for each set of data returned by the `getData()`
method. The test method takes two arguments, which are mapped with the values from the data provider.
@DataProvider is a method that is used to provide test data to test methods in a test class. It can return either
a two-dimensional array or an object array where each object array contains the test data for one test case.
For example:
@DataProvider
public Object[][] testData() {
return new Object[][] {
{ ""John"", 25 },
{ ""Jane"", 30 },
{ ""Mike"", 35 }
};
}
@Test(dataProvider = ""testData"")
public void testName(String name, int age) {
// Test code using name and age
@Factory, on the other hand, is used to create multiple instances of a test class, each with different data. It is
useful when you want to run the same test multiple times with different inputs. For example:
@Factory
public Object[] createTests() {
return new Object[] {
new TestClass(""John"", 25),
new TestClass(""Jane"", 30),
new TestClass(""Mike"", 35)
};
}
@Test
public void testName() {
// Test code using name and age
}
}
In summary, @DataProvider provides test data to test methods, whereas @Factory creates multiple instances
of a test class with different data.
@BeforeMethod: This annotation is used to set up the environment before each test method is executed. If
you have multiple test methods in your test class, the code inside this method will be executed before each
test method. For example, if you want to login to your application before executing each test case, you can
use the @BeforeMethod annotation.
@BeforeTest: This annotation is used to set up the environment before any test method in the test class is
executed. This means that the code inside this method will be executed only once, regardless of the number
of test methods in your test class. For example, if you want to launch the application and set up some global
configuration properties before executing any test case, you can use the @BeforeTest annotation.
@BeforeClass: This annotation is used to set up the environment before any test method in the test class is
executed, but it is executed only once for the entire test class. This means that the code inside this method is
executed only once, even if you have multiple test methods in your test class. For example, if you want to
initialize a database connection or load some data before executing any test case, you can use the
@BeforeClass annotation.
@BeforeClass
public void setUpClass(){
//initialize database connection or load some data
}
@BeforeTest
public void setUpTest(){
//launch the application and set up some global configuration properties
}
@BeforeMethod
public void setUpMethod(){
//login to your application
}
@Test
public void testMethod1(){
//test code
}
@Test
public void testMethod2(){
//test code
}
}
1. Test-Level Parallelism: This type of parallelism is achieved when multiple test methods are executed at the
same time. It can be implemented by setting the attribute parallel to “methods” in the <test> tag of the
testng.xml file. For example:
</suite>
2. Suite-Level Parallelism: This type of parallelism is achieved when multiple test classes are executed at the
same time. It can be implemented by setting the attribute parallel to “tests” in the <suite> tag of the testng.xml
file. For example:
In addition, TestNG also supports thread pooling to execute tests in parallel. This can be achieved by setting
the parameters thread-count and threadpool-size in the <suite> tag of the testng.xml file. For example:
This will create a thread pool of 2 threads which will be used to execute the tests in parallel.
For example, if we have a suite of test cases for a website, we can use the @BeforeSuite annotation to initialize
the browser and login into the website before running any test case. On the other hand, we can use the
@AfterSuite annotation to close the browser and logout from the website after completing all the test cases.
@BeforeSuite
public void beforeSuite() {
// Initialize browser and login into website
}
@AfterSuite
public void afterSuite() {
// Close browser and logout from website
}
Syntax to perform parallel testing in TestNG and what do you write in <suite tag>
also what do you mention in double quotes like parallel = “ ”
To perform parallel testing in TestNG, we need to follow the following syntax:
Here, the parallel attribute is set to ""tests,"" which means TestNG will run all the tests in the same suite in
parallel. The thread-count attribute specifies the maximum number of threads to be used for running the tests.
For example, if we have two test classes in our suite, Test1 and Test2, and we want to run them in parallel
with two threads, we can use the following code:
In this example, Test1 and Test2 classes will be executed in parallel using two threads.
Note: The thread-count attribute value should not exceed the number of tests in the suite.
For example, if we want to run all the test methods of a class in parallel, we can use:
In this example, all the test methods of Test1 class will be executed in parallel using two threads.
In testNG, do we have multiple suite in one XML file and what If I want to run all
suits?
Yes, it is possible to have multiple test suites in one TestNG XML file. To run all the suites in the file, you can
execute the XML file using the TestNG framework. Here is an example code snippet:
import org.testng.TestNG;
import java.util.ArrayList;
import java.util.List;
In this example, we are creating an object of the TestNG class and adding the name of the XML file that contains
multiple suites using the `setTestSuites()` method. Then we run the tests using the `run()` method.
This will execute all the test suites in the specified XML file.
For example, consider a test method that performs login to a website with different user credentials. We can
use the InvocationCount parameter to run this method multiple times with different user credentials.
@Test(invocationCount = 5)
public void loginTest() {
// Code to perform login
}
For example, let's say we have a feature file with multiple scenarios that require the user to be logged in before
they can perform any actions. We can define a background for the feature file that logs the user in and sets
up the necessary environment, like so:
In this example, the background defines the steps needed to log in the user, and is executed before every
scenario in the feature file. This saves us from having to repeat the login steps in each scenario, making our
tests more efficient and easier to maintain.
Scenario Outline is a template for defining multiple related scenarios, each of which can have different input
values and outcomes. It allows the same scenario to be executed with multiple sets of data. The different data
sets are defined using Examples section, which provide input value to the same scenario.
Examples:
| username | password |
| user1 | pass1 |
| user2 | pass2 |
In this example, the same scenario of user login is executed twice with different input data, hence the input
values for username and password are defined in the Examples table.
To use the retry analyzer in TestNG, we need to implement the IRetryAnalyzer interface and provide the
number of retries we want to perform in the constructor. Here is an example code:
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;
@Override
public boolean retry(ITestResult result) {
if (retryCount < maxRetryCount) {
retryCount++;
return true;
}
return false;
}
}
In this example, the RetryAnalyzer class implements the IRetryAnalyzer interface and overrides the retry()
method. We have set the maximum number of retries as 3 by declaring a constant variable 'maxRetryCount'.
The retry() method returns true if the number of retries is less than the maximum retry count, otherwise it
returns false.
We can use this retry analyzer by adding the @Test(retryAnalyzer = RetryAnalyzer.class) annotation to our test
method, as shown in the following example:
import org.testng.annotations.Test;
@Test(retryAnalyzer = RetryAnalyzer.class)
public void myTest() {
// Your Test Code Here
}
}
By adding this annotation, TestNG will automatically use the RetryAnalyzer class to retry the test method if it
fails.
Hooks are a way to execute code before or after a scenario, feature or step definition in the Cucumber test
run. They are essentially the code blocks that run automatically based on certain trigger events such as Before
or After. Hooks are typically used for setting up the test environment, establishing database connections,
initializing test data, and performing cleanup tasks. Here's an example of a hook in Java:
import cucumber.api.java.Before;
import cucumber.api.java.After;
@After
Tags, on the other hand, are a way to organize scenarios, features or step definitions in the Cucumber test
run. Tags are metadata labels that are used to mark a scenario or feature with a certain category or attribute.
Tags help testers to filter and group tests based on specific criteria and to run selective tests quickly. For
example, if a tester wants to run only a subset of tests that relate to a particular module or function, they can
use the --tags option in the command line to filter tests. Here’s an example of how tags are used in feature
file:
@smoke-test @homepage
Feature: Website Navigation
As a user, I want to navigate through web pages easily
@smoke-test @homepage
Scenario: Verify homepage links
Given user is on the homepage
When user clicks on each link
Then all links should work properly
The Surefire plugin is usually configured in the project's pom.xml file, specifying the test classes to run, the
type of test framework used (JUnit, TestNG, etc.), and any additional configurations.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
<parallel>methods</parallel>
<threadCount>5</threadCount>
</configuration>
</plugin>
</plugins>
</build>
In this example, we configure the Surefire plugin version to 2.22.2 and set some properties such as
""testFailureIgnore"", which ignores test failures, ""parallel"", which specifies to run tests in parallel, and
""threadCount"", which sets the number of threads to use.
Overall, the Maven Surefire plugin is useful for automating test runs and generating accurate test reports as
part of a continuous integration and delivery process.
Here is an example of a pom.xml file that sets the project version, dependencies, and plugins:
xml
<project xmlns=""http://maven.apache.org/POM/4.0.0""
xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""
xsi:schemaLocation=""http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd"">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>project-name</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>27.0-jre</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
The pom.xml file is commonly used in CI/CD (continuous integration/continuous deployment) pipelines to
automate the building, testing, and deployment of Java projects. When the project is built using Maven, the
pom.xml file is used to download the required dependencies and plugins, and configure the build process.
For example, in the below POM.XML file, we have defined two profiles - one for QA environment and the other
for Production environment. We have defined the properties with different values for each environment.
<profiles>
<profile>
<id>qa</id>
<properties>
<url>http://qa.example.com</url>
<username>qauser</username>
<password>qapassword</password>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<url>http://prod.example.com</url>
<username>produser</username>
<password>prodpassword</password>
</properties>
</profile>
</profiles>
We can then use these properties in our test code by accessing them using the Maven build system. For
example:
// Use the URL, username and password to log in to the application and perform tests
When we run the Maven build command, we can specify the profile we want to use. For example:
This will use the QA profile and pass the corresponding properties to the test code. Similarly, we can use the
'prod' profile for production environment.
1. mvn clean: This command is used to clean the project and remove any compiled output files.
2. mvn compile: This command is used to compile the Java code in the project.
3. mvn package: This command is used to package the compiled Java code into a Jar or War file.
4. mvn install: This command is used to install the packaged application into the local Maven repository.
5. mvn test: This command is used to run the unit tests in the project.
Example:
To compile and package a Java project using Maven, we can use the following command in the terminal:
This will first clean the project, then compile the Java code and finally package the compiled code into a
Jar/War file.
Another example,if we want to run the unit tests in the project, we can use the following command:
mvn test
This will execute all the unit tests in our project, and provide output on the results of each test.
1. Version Control Systems (VCS): Jenkins can easily integrate with VCS tools such as GitHub, GitLab, and
Bitbucket. This integration helps automate build triggers by detecting the changes in the code repositories.
2. Testing Tools: Jenkins can integrate with various testing tools such as Selenium, JUnit, TestNG, and
Cucumber to automate the testing process. Integration with these tools helps in generating test reports and
tracking the results of automated tests.
Example:
The following example demonstrates how Jenkins can be integrated with a VCS tool (GitHub) in Java.
1. Create a new Jenkins project by selecting ""New Item"" from the Jenkins dashboard.
3. In the ""Source Code Management"" section, select ""Git"" and provide the GitHub repository URL.
4. Configure the build triggers to automatically build the project whenever there is a new commit in the
repository.
6. Finally, run the Jenkins job to build and test the Java code.
Another way to schedule deployment is through tools like Kubernetes, Docker, or AWS Elastic Beanstalk, which
offer automated deployment services. These tools allow configuring deployment schedules according to the
needs of the team, including release cadence and firewall restrictions.
As an example, we can use Jenkins for scheduling deployment. Below is the code to create a pipeline using
Jenkins in the Jenkinsfile:
pipeline {
agent any
stages {
stage ('Clone Repository') {
steps {
git 'https://github.com/example/repo.git'
}
}
stage ('Build') {
steps {
sh 'mvn clean package'
}
}
stage ('Deploy') {
steps {
sh 'ansible-playbook deploy.yaml'
}
}
}
}
In this pipeline, the first stage clones the repository, the second stage builds the code, and the third stage
deploys the application using Ansible. This pipeline can be scheduled to run automatically every day or on a
specific date and time.
1. **git clone**: This command is used to create a copy of the repository on the local machine. For example,
`git clone https://github.com/username/repo.git`
2. **git add**: This command is used to stage changes before committing them. For example, `git add file.txt`
3. **git commit**: This command is used to save changes to the local repository. For example, `git commit -
m ""Updated README file""`
4. **git push**: This command is used to send the committed changes to the remote repository. For example,
`git push origin main`
5. **git pull**: This command is used to fetch the latest changes from the remote repository and merge them
with the local repository. For example, `git pull origin main`
6. **git branch**: This command is used to create or switch to a different branch. For example, `git branch
new-feature`
7. **git merge**: This command is used to merge changes from one branch to another. For example, `git
merge feature-branch`
Suppose you are working on a Java project and you need to add a new feature to the application. You can start
by creating a new branch for the feature using the `git branch` command:
Then, you make the necessary changes to the code and stage them using the `git add` command:
Next, you commit the changes to the local repository using the `git commit` command:
Once you have committed the changes, you can push them to the remote repository using the `git push`
command:
Finally, when the feature is complete and tested, you can merge the changes back into the main branch using
the `git merge` command:
Here's an example code snippet in Java to import a Postman API request file into your project:
import com.jayway.jsonpath.JsonPath;
import io.restassured.RestAssured;
import io.restassured.response.Response;
In this example, we're using RestAssured to make a GET request to an API endpoint. We're then using JsonPath
to extract the name of the first user from the response body. This is just one example of how you can integrate
Postman into your project.
{
""name"": ""John"",
""age"": 30,
""address"": {
""street"": ""123 Main St"",
""city"": ""Anytown"",
""state"": ""CA"",
""zip"": ""12345""
}
}
We can then use the Jackson library to parse the JSON payload and map it to the Person class:
We can now use the person object to perform any necessary operations. This approach allows us to handle
different payloads dynamically without needing to create separate classes for each payload.
What are the API status codes, you have come across?
As an automation expert, I have worked with various API status codes, some of the commonly used codes
include:
1. 200 OK - This status code indicates that the requested operation has been completed successfully.
Example: When a user requests to retrieve their profile information from a social media platform, the 200 OK
status code is returned when the information is successfully retrieved.
2. 201 Created - This status code indicates that a new resource has been created successfully.
Example: If a user creates a new post on a blogging website, the 201 Created status code is returned when the
post is successfully created and saved.
3. 400 Bad Request - This status code indicates that the request sent by the client is invalid or malformed.
Example: If a user tries to send a request without including a required parameter, the server responds with a
400 Bad Request status code.
4. 401 Unauthorized - This status code indicates that the client's authentication credentials are invalid or
missing.
Example: If a user tries to access a secured resource on a website without providing valid login credentials, the
server returns a 401 Unauthorized status code.
5. 403 Forbidden - This status code indicates that the client does not have access to the requested resource.
Example: If a user tries to access an admin-only section of a website, the server returns a 403 Forbidden status
code if the user is not authorized to access that section.
6. 404 Not Found - This status code indicates that the requested resource is not available on the server.
Example: If a user tries to access a page on a website that does not exist, the server returns a 404 Not Found
status code.
7. 500 Internal Server Error - This status code indicates that there was an error on the server-side while
processing the request.
Example: If the server encounters an unexpected error while processing a request, it returns a 500 Internal
Server Error status code.
In Java, we can handle these API status codes by using HTTP client libraries like Apache HttpClient or OkHttp.
We can also use frameworks like RestAssured to test and validate these status codes in automated test cases.
Here's an example code snippet for making an HTTP GET request and handling the response status codes using
OkHttp:
What is difference between OAuth1.0 and OAuth2.O, When and where do you use
and how. Can you write a sample code?
OAuth 1.0 and OAuth 2.0 are both authentication protocols used to secure APIs. However, the key difference
between the two lies in their security mechanisms.
OAuth 1.0 is a token-based protocol that uses signatures to validate requests. It involves three parties: the
user (resource owner), the client (consumer), and the server (service provider). In OAuth 1.0, the client needs
to provide the user's credentials to the server to access protected resources. This can be a security risk if the
client's credentials are compromised.
On the other hand, OAuth 2.0 is a more modern protocol that relies on SSL/TLS encryption to secure
communication between parties. It uses access tokens to authenticate requests and does not require the client
to provide the user's credentials to the server. Instead, the user authorizes the client to access protected
resources on their behalf.
OAuth 2.0 is widely used in modern applications and APIs due to its improved security compared to OAuth 1.0.
Here is sample code for implementing OAuth 2.0 authorization with the Google API using the Google OAuth2
library in Java:
import com.google.auth.oauth2.GoogleCredentials;
import com.google.auth.oauth2.UserCredentials;
import com.google.auth.oauth2.AccessToken;
import com.google.auth.oauth2.GoogleCredentials.Builder;
import java.io.FileInputStream;
import java.io.IOException;
In this example, the `client_secret.json` file contains the client configuration for the Google API. The
`GoogleCredentials.fromStream()` method is used to load the client configuration, while the
`UserCredentials.Builder` is used to construct the user credentials object. Finally,
`userCreds.refreshAccessToken()` is called to retrieve an access token to authenticate API requests.
How you get the response from one api and send to another api?
To get the response from one API and send it to another API, you can use the Java programming language and
the HTTP client libraries. Here is an example code in Java:
if (response.statusCode() == 200) {
// If the response is successful, extract the data and send it to the second API endpoint
String data = response.body();
This code first makes a GET request to the first API endpoint and checks if the response is successful. If so, it
extracts the data from the response body and sends it as a POST request to the second API endpoint. Finally,
it checks the response from the second API endpoint to ensure that the data was successfully sent.
For example, a Test Plan for a website may include objectives to verify the functionality of the site, the usability
of its interface, and its compatibility with various browsers. It would identify specific test cases to be executed,
such as entering and submitting a form, and document the expected results. The Test Plan would also outline
the hardware and software requirements, timelines, and resources needed to conduct testing on the website.
1. New: Initial stage when a bug is detected and reported for the first time.
2. Open: Once the bug is identified, it is assigned to the relevant team, and it becomes an open bug.
3. Assigned: Once the bug is assigned to the team, the team starts working on a resolution plan.
4. In-progress: At this stage, the development team starts working on the bug fix.
5. Resolved: Once the bug fix is completed, it undergoes testing to ensure it completely solves the problem.
6. Verified: After the bug fix is tested, the testing team will verify it to confirm it resolves the issue.
For example, suppose you're working on an automation project using Selenium. During the testing phase, you
identify that when you click on a button, it is redirecting to the wrong page. You log a bug report, and it goes
through the bug life cycle stages until it is resolved and verified by the testing team.
Smoke Testing:
Smoke Testing is performed to check the basic functionalities of the application. The main goal of Smoke
Testing is to ensure that the application or software is working as expected and there are no major issues.
Smoke Testing is performed after the software is developed, and it checks whether the software can perform
its primary functions.
Example:
Suppose a software application is developed with a login functionality where a user enters their username and
password. Smoke Testing would involve testing whether the login functionality is working correctly, like testing
whether the system recognizes the correct username and password, and whether the login process is
successful.
Sanity Testing:
Sanity testing is performed to check whether the new or modified features of the software have been
implemented correctly without affecting the existing functionalities of the application. The goal of Sanity
testing is to ensure that the application is stable enough for further testing.
Example:
Suppose an e-commerce website has a shopping cart feature that has been modified to add a discount coupon
feature. Sanity Testing would involve testing whether the new feature of the discount coupon has been
implemented correctly without affecting the existing shopping cart feature of the e-commerce website.
On the other hand, retesting is performed to verify that defects that were previously identified and fixed have
indeed been resolved. It typically involves running the same test cases that failed or exhibited issues before,
to ensure that the problem has been remediated.
For example, if a developer adds a new feature to a web application, regression testing would be used to
ensure that the new functionality does not break any existing features that were previously working correctly.
If a bug is found in the login functionality of the same application, retesting would be performed after the fix
to ensure that users can now log in successfully without any issues.
1. Test Plan: It is a formal document that defines the scope, objectives, methods, and approach to be used to
test the software. This document is usually prepared by the test lead or manager and outlines the entire testing
process, including the types of testing to be performed, the test environment, test schedule, and resources
required.
Example: A Test Plan for a web application may include the types of testing to be performed such as functional,
performance, load, usability, and security testing. It may also include the test approach, test environment, test
data, testing tools, test schedule, and roles and responsibilities of each team member.
2. Test Strategy: It is a high-level document that defines the testing approach to be used by the testing team.
This document is usually prepared by the project manager and outlines the overall testing objectives, testing
scope, and testing procedures that will be used to achieve those objectives.
Example: A Test Strategy for a project may incorporate various types of testing such as unit testing, integration
testing, system testing, and acceptance testing. It may also include the testing tools and techniques to be used,
the test environment, and the roles and responsibilities of each team member.
2. Reporting: The tester or end-user reports the bug with all necessary details such as the steps to reproduce,
screenshots, and environment details.
3. Triage: The bug is reviewed by the team and prioritized based on the impact, severity, and frequency.
4. Assigning: The bug is assigned to the developer who will be responsible for fixing it.
5. Fixing: The developer fixes the bug and prepares a patch or a new build.
6. Retesting: The tester verifies the fixed bug to make sure that it is indeed fixed and also to ensure that the
fix has not introduced new issues.
7. Closing: The bug is marked as resolved and the corresponding issue is closed.
1. A tester finds a bug that causes the application to crash on a particular screen if the user taps on the Cancel
button.
2. The tester reports the bug with all necessary details such as the steps to reproduce, screenshots, and
environment details.
3. The bug is triaged, and it is given a high severity as it causes the app to crash.
An example of exploratory testing would be testing a new feature on a web application. Instead of following
a set of scripted test cases, the tester would explore the feature from different angles and try to find different
ways to use it. The tester would then document any issues or defects found during the testing process.
In Java, exploratory testing can be achieved using tools like JUnit, TestNG, or Cucumber. These tools provide
the ability to create test scenarios on the fly as the tester is exploring an application. The tester can execute
these new scenarios immediately and verify the results.
For example, suppose we have a software application that allows users to create and edit documents. In an
ad-hoc testing approach, a tester may first explore the user interface and try to understand what each button
does. They may then try to create a document and check if all the basic functionalities like save, copy, and
paste are working as expected. After that, they may try to create different versions of the document, copy and
paste text from different documents to check the formatting, and see how the software behaves in various
scenarios. The tester would try to identify any issues they find during the process of exploring the software.
Given the test cases having priority of -1,0,1,2 tell me the sequence of execution.
The sequence of execution for test cases with priority -1, 0, 1, and 2 negative will run first.
Inner join: Inner join returns only the matching rows from both tables involved in the join. It includes the rows
that have common values in both tables. For example, consider two tables ‘Student’ and ‘Marksheet’, each
having a column ‘Roll no’. The following SQL query will give the inner join of these two tables:
SELECT *
FROM Student
INNER JOIN Marksheet
ON Student.Roll no = Marksheet.Roll no;
Outer join: Outer join returns all the rows of one table and the matching rows of another table involved in the
join. It includes the rows that do not have matching values in both tables. There are three types of outer joins:
- Left outer join: It returns all the rows of the left table and matching rows from the right table. For example,
consider the same tables as above. The following SQL query will give the left outer join of these two tables:
SELECT *
FROM Student
LEFT OUTER JOIN Marksheet
ON Student.Roll no = Marksheet.Roll no;
- Right outer join: It returns all the rows of the right table and matching rows from the left table. For example,
consider the same tables as above. The following SQL query will give the right outer join of these two tables:
SELECT *
FROM Student
RIGHT OUTER JOIN Marksheet
ON Student.Roll no = Marksheet.Roll no;
- Full outer join: It returns all the rows of both tables, including the ones without matching values. For example,
consider the same tables as above. The following SQL query will give the full outer join of these two tables:
SELECT *
FROM Student
FULL OUTER JOIN Marksheet
ON Student.Roll no = Marksheet.Roll no;
String sql = ""SELECT * FROM Student FULL OUTER JOIN Marksheet ""
+ "N Student.Roll no = Marksheet.Roll no"";
Connection conn = DriverManager.getConnection(url, username, password);
while (rs.next()) {
// process the data
}
For example, let's say during the testing of a mobile application, a minor issue of the misspelled word in the
navigation button is detected. As the priority is low and it does not affect the functionality of the application,
it can be marked as a deferred bug and addressed in the next release.
An example of this in practice would be a software development team using Scrum to develop an e-commerce
platform. The Scrum Master would be responsible for ensuring that sprints are planned, daily stand-up
meetings are conducted, sprint reviews are held, and the sprint retrospectives are conducted to identify areas
for improvement. Using Scrum, the team can deliver working increments of the e-commerce platform in a
timely and efficient manner.
In tight sprint schedule, if a new requirement is added, how will you handle this
situation?
I understand the importance of being flexible and adaptable to changes in requirements. In a tight sprint
schedule, if a new requirement is added, I would first assess the impact of the change on the current sprint
and project timeline.
If the change is critical and cannot wait, I would work with the product owner and team to prioritize it and
adjust the sprint backlog accordingly. This may involve re-prioritizing the current backlog items or adding the
new requirement as a separate task.
To ensure efficient testing, I would also assess the impact of the new requirement on the existing test cases
and update them accordingly. Automated tests can be utilized to help expedite the testing process and ensure
thorough coverage.
You have 30 + sprints in your release how will you design your test scripts and run
them?
I would recommend designing and running test scripts in each sprint. This will help in identifying defects at an
earlier stage and prevent them from becoming bigger issues. Here are the steps I would suggest:
1. Identify test scenarios and prioritize them in each sprint based on their criticality and impact on the
application.
3. Map the test cases to the user stories in the sprint backlog.
4. Create and maintain a test automation framework that supports both functional and non-functional testing.
5. Develop and execute automated test scripts for each identified scenario.
6. Integrate the test automation scripts with the continuous integration and delivery pipeline.
To illustrate, let's take an example of an e-commerce application. In one of the sprints, the user story is to
verify the payment gateway integration. Here is how I would design and run the test scripts:
1. Identify the test scenarios - Verify the payment gateway integration for positive and negative cases.
2. Design test cases - Create test cases for successful payment, payment with insufficient funds, payment with
invalid card details, etc.
3. Map test cases to user stories - Link the test cases to the user story in the sprint backlog for easier tracking.
4. Create a test automation framework - Develop a framework using Java, Selenium, and TestNG to automate
the identified test cases.
5. Develop and execute test scripts - Automate the payment scenarios and execute the scripts using the TestNG
test runner.
6. Integrate with the CI/CD pipeline - Integrate the test automation scripts with the pipeline to execute them
automatically whenever a new code is deployed.
7. Monitor and report defects - Analyze the test results and report any defects found during the payment
gateway integration testing.
Overall, this approach ensures that the test scripts are designed and executed efficiently in each sprint,
ensuring faster feedback and better quality of the application.
My expertise in Agile methodologies can also be valuable in ensuring that the team is following the best
practices for releasing high-quality software in a timely manner. I can assist in creating user stories, conducting
sprint planning, and defining acceptance criteria, among other things.
As a Java expert, I can help in developing and maintaining automated test scripts using various testing
frameworks such as JUnit, TestNG, Selenium, and Appium.
Suppose you are the leam QA and 1 new member join your team and at the same
time you have a deadline to meet in next 2 or 3 days so how will you involve that
new member in team so that you can utilise him/her to meet deadlines?
What are some best practices you learnt and how much difference it made in testing
career? Explain before and after situations
As an automation expert with extensive experience in manual testing, Agile methodology, and Java
programming, I have learned several best practices that have helped me improve my testing career. Here are
a few examples:
1. Continuous Integration and Deployment (CI/CD): Implementing CI/CD has made a significant difference in
my testing career. Before adopting this practice, we used to manually build, deploy and test the application,
which was time-consuming and error-prone. With CI/CD, we have automated the entire process, which has
reduced the overall testing time and helped us identify issues earlier in the development cycle. This has
resulted in faster releases, improved quality, and reduced costs.
2. Test Automation Framework: Developing a test automation framework has been another best practice that
has made a huge difference in my testing career. Before implementing the framework, we had several
automation scripts that were difficult to maintain, and it was hard to track the test results. With the
framework, we have a standard way of writing and executing automation tests, which has made the tests
more robust and maintainable. Additionally, the framework provides detailed reports that help us identify the
issues quickly and take corrective actions.
After you have run a full regression test, and find new regression bugs, which bugs would you prioritize. Bugs
that suggest that functionality has regressed, or bugs that appear in new features?
ExtentReports: ExtentReports is a widely used reporting library for creating interactive and detailed reports.
It supports frameworks like TestNG, JUnit, and Cucumber. ExtentReports provides rich visualizations, such as
charts, graphs, and test logs, to represent test execution results effectively.
Allure: Allure is a flexible reporting framework that supports various testing frameworks, including TestNG,
JUnit, and Cucumber. It generates visually appealing and interactive reports with detailed information about
test execution, including steps, attachments, and test history. Allure reports are easy to navigate and provide
insightful analytics.
Cucumber Reports: If you are using Cucumber for behavior-driven development (BDD) testing, Cucumber
provides built-in reporting options. Cucumber reports provide comprehensive information about feature files,
scenarios, and their execution status. These reports can be customized to include additional information and
can be integrated with other reporting tools as well.
ReportNG: ReportNG is an HTML reporting plugin for TestNG. It generates detailed and customizable HTML
reports with visual representations of test execution results. ReportNG provides various features like grouping
tests, test configuration details, and customization options for adding additional information to the reports.
TestNG-XSLT: TestNG-XSLT is an XSLT-based reporting tool for TestNG. It generates reports in various formats
like HTML, PDF, and Excel. It offers customizable report templates and provides detailed information about
test execution, including test configurations, logs, and screenshots.
Serenity BDD: Serenity BDD is a comprehensive reporting and test management tool that integrates with
popular testing frameworks like JUnit and TestNG. It generates HTML reports with test execution details,
including features, stories, and test steps. Serenity BDD reports provide rich visuals, including test coverage
and performance metrics.
These are just a few examples of reporting tools available in the testing ecosystem. The choice of reporting
tool depends on your specific requirements, testing framework, and the level of detail and customization you
need in your reports.
package CustomAnnotations;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface RetryCountIfFailed {
@Retention(RetentionPolicy.RUNTIME)
package Tests;
import org.testng.Assert;
import org.testng.annotations.Test;
import CustomAnnotations.RetryCountIfFailed;
@Test
@RetryCountIfFailed(10)
public void Test1()
{
Assert.assertEquals(false, true);
}
@Test
public void Test2()
{
Assert.assertEquals(false, true);
}
}
Pay attention to the the usage of the RetryCountIfFailed annotation. First, it is used just
like any other annotation by using the @ in front of the name (@RetryCountIfFailed).
Second a numeric value is passed to the annotation which specifies the number of times a
failed test needs to be rerun. So the actual usage of the annotation
becomes @RetryCountIfFailed(5), where 5 is the number of times you want this test to be
rerun in case of failure. This value can be Integer value.
1. Check if the Test method for which retry is called has RetryCountIfFailed annotation
2. Then compare current retry attempt with value of this annotation.
package Listeners;
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;
import CustomAnnotations.RetryCountIfFailed;
int counter = 0;
/*
* (non-Javadoc)
*
* @see org.testng.IRetryAnalyzer#retry(org.testng.ITestResult)
*
* This method decides how many times a test needs to be rerun. TestNg will
* call this method every time a test fails. So we can put some code in here
* to decide when to rerun the test.
*
* Note: This method will return true if a tests needs to be retried and
* false it not.
*
*/
@Override
public boolean retry(ITestResult result) {
Here you can see Test1 is run 10 times and Test2 is run just once.
1. ABSTRACTION
Abstraction is the methodology of hiding the implementation of internal details and showing
the functionality to the users.
Let’s see an example of data abstraction in Selenium Automation Framework.
In Page Object Model design pattern, we write locators (such as id, name, xpath etc.,) and
the methods in a Page Class. We utilize these locators in tests but we can’t see the
implementation of the methods. Literally we hide the implementations of the locators from
the tests.
Example : Login function of LMS portal
A page Class “LoginPage” was created to store all the objects or locators of LoginPage
Module .All functions performed on the UI of Login page are stored as methods in the same
Page.
2. INTERFACE
WebDriver is an Interface.
Here, we are initializing Chrome browser using Selenium WebDriver. It means we are
creating a reference variable (driver) of the interface (WebDriver) and creating an Object.
Here WebDriver is an Interface as mentioned earlier and Chromedriver is a class.
3. INHERITANCE
The mechanism in Java by which one class acquires the properties (instance variables) and
functionalities of another class is known as Inheritance.
We create a Base Class in the Automation Framework to initialize WebDriver interface,
WebDriver waits, Property files, Excels, etc., in the Base Class. We extend the Base Class
in other classes such Tests and Utility Class.
4. POLYMORPHISM
METHOD OVERLOADING
We use Implicit wait in Selenium. Implicit wait is an example of overloading. In Implicit wait
we use different time stamps such as SECONDS, MINUTES, HOURS etc.
METHOD OVERRIDING
We use a method which was already implemented in another class by changing its
parameters. To understand this you need to understand Overriding in Java.
Declaring a method in child class which is already present in the parent class is called
Method Overriding. Examples are get and navigate methods of different drivers in
Selenium.
5. ENCAPSULATION
All the classes in a framework are an example of Encapsulation.
In POM classes, we declare the data members using @FindBy and initialization of data
members will be done using Constructor to utilize those in methods. Encapsulation is a
mechanism of binding ode and data (variables) together in a single unit.
Programs
Nth Highest Number In an Array
Certainly! Let's check the program with the given input in Java:
package practiceSet2;
import java.util.Arrays;
// If the count is equal to the given N, store the index and break
the loop
if (count == n) {
index = i;
break;
}
}
//Integer.MIN_VALUE = -2147483648
int largest =Integer.MIN_VALUE;
int second_Largest = Integer.MIN_VALUE;
//{-1, 7, 1, 34, 18}
}
return second_Largest;
}
Fibonacci
public static void printFibonacciSeries(int n) {
int first = 0, second = 1;
System.out.print(first + " " + second + " ");
for (int i = 2; i < n; i++) {
int sum = first + second;
System.out.print(sum + " " );
first = second;
second = sum;
}
}