Skip to content

Medium Automation Testing Interview Questions

221 medium questions with answers. Applied questions that check whether you can use the concepts on real work.

Topics in the medium set

Selenium WebDriver: 34 Core Java for Testers: 27 TestNG Framework: 23 Page Object Model: 22 REST Assured: 21 Git, Maven and Jenkins: 20 API Testing and CI/CD: 18 Cucumber and BDD: 18 Selenium Grid & Docker: 14
Solved — mediumStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
3 questions free Unlock the rest in seconds
01

POST vs PUT vs PATCH?

Save to ▾
Show answer
POST creates a resource, PUT replaces the whole resource (idempotent) and PATCH updates part of it.
02

How do you validate a JSON response in REST Assured?

Save to ▾
Show answer
Use then().statusCode(200).body("data.id", equalTo(5)), or extract() the response and assert fields with JsonPath.
03

What is a webhook and how do you test it?

Save to ▾
Show answer
A callback where one system sends an HTTP request to another when an event occurs. Test with a mock receiver or tools such as webhook.site and verify the payload.
04

What are try-with-resources and why use them?

Save to ▾
Show answer
A try block that automatically closes resources such as file readers or streams, preventing leaks without a finally block.
05

How do you handle a test that is flaky only in headless mode?

Save to ▾
Show answer
Set window size explicitly, use proper waits, check animations and viewport differences, and capture screenshots and logs to find timing issues.
06

What are the different types of waits in Selenium?

Save to ▾
Show answer
Implicit, explicit (WebDriverWait with ExpectedConditions) and fluent waits; avoid mixing implicit and explicit waits and never rely on Thread.sleep.
07

How do you run tests in parallel?

Save to ▾
Show answer
Use TestNG parallel="methods | classes | tests" with thread-count, keep WebDriver in a ThreadLocal, and use Selenium Grid or a cloud grid for multiple browsers.
08

What is method overriding and where is it useful in frameworks?

Save to ▾
Show answer
A subclass redefines a parent method. Frameworks use it to customise base behaviour, such as overriding a wait or click method in a base page class.
09

How do you verify that an element is displayed, enabled or selected?

Save to ▾
Show answer
Use isDisplayed(), isEnabled() and isSelected() on the WebElement before interacting or asserting.
10

How do you test an API that depends on another service that is down?

Save to ▾
Show answer
Use mocks or stubs such as WireMock to simulate the dependency and test your service in isolation.
11

What is Docker and how does it help tests?

Save to ▾
Show answer
Docker packages tools in containers so tests run identically everywhere; Selenium Grid and browsers can be started quickly in containers.
12

What is PageFactory?

Save to ▾
Show answer
A helper that initialises @FindBy elements lazily using initElements; some teams skip it in favour of plain By locators.
13

How do you take a screenshot on failure in TestNG?

Save to ▾
Show answer
Implement ITestListener.onTestFailure(): File src = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); then copy it into the reports folder.
14

What is a constructor and can it be overloaded?

Save to ▾
Show answer
A special method that initialises an object. It can be overloaded with different parameters, and testers use it to pass the WebDriver into page classes.
15

How do you verify response time and headers in REST Assured?

Save to ▾
Show answer
Use then().time(lessThan(2000L)) and then().header("Content-Type", containsString("json")) along with body assertions.
16

How do you handle StaleElementReferenceException?

Save to ▾
Show answer
Re-locate the element after the DOM refreshes, use explicit waits for the refreshed element, don't keep element references for long, or wrap the action in retry logic.
17

How do you handle a dropdown that is not a <select> tag?

Save to ▾
Show answer
Click to open the dropdown, then locate the option by its text, e.g. //li[text()='India'], and click it. Add an explicit wait for the animation.
18

What is OAuth 2.0 in API testing?

Save to ▾
Show answer
An authorisation framework where a client obtains an access token from an auth server and sends it as a Bearer token; tests fetch and reuse the token in setup.
19

What is CI/CD and why does automation need it?

Save to ▾
Show answer
Continuous Integration builds and tests every commit, and Continuous Delivery ships automatically. Automated tests give fast feedback and gate releases.
20

What is the use of the this and super keywords?

Save to ▾
Show answer
this refers to the current object; super refers to the parent class, used to call parent constructors and methods.
21

What is the difference between an array and an ArrayList?

Save to ▾
Show answer
Arrays have a fixed size and can hold primitives; ArrayList grows dynamically, holds objects and offers helper methods.
22

What are the advantages of version control for test code?

Save to ▾
Show answer
Git tracks changes, enables code review, branching and rollback and lets teams collaborate on the framework safely.
23

How do you handle environment-specific configuration?

Save to ▾
Show answer
Keep URLs and credentials in per-environment config files or variables, choose with a command-line parameter and never hard-code secrets.
24

How does HashMap work internally?

Save to ▾
Show answer
It uses the key's hashCode to find a bucket and equals to resolve collisions, giving O(1) average lookups; Java 8 converts long buckets into trees.
25

How do you pass parameters from testng.xml?

Save to ▾
Show answer
Define parameter name and value in the XML and read them with @Parameters in the test or configuration method.
26

What is data-driven testing?

Save to ▾
Show answer
Running the same test logic with multiple data sets from Excel, CSV, JSON or a database, so coverage increases without duplicating code.
27

What is the difference between Comparable and Comparator in Java?

Save to ▾
Show answer
Comparable defines the natural order inside the class (compareTo); Comparator defines custom orders externally (compare), useful for sorting test data in several ways.
28

How do you read data from Excel or properties files in Java?

Save to ▾
Show answer
Use Apache POI for Excel and the Properties class for config files, loaded in a utility class so tests read data instead of hard-coding it.
29

What is the use of Maven in automation projects?

Save to ▾
Show answer
It manages dependencies through pom.xml, builds the project, runs tests with Surefire and standardises structure across teams.
30

What is the difference between driver.close() and driver.quit()?

Save to ▾
Show answer
close() closes the current window; quit() closes all windows and ends the driver session.
31

What is Selenium Grid and why use it?

Save to ▾
Show answer
It runs tests in parallel across multiple machines and browsers using a hub and nodes, cutting execution time and increasing browser coverage.
32

What are relative locators in Selenium 4?

Save to ▾
Show answer
Locators such as above, below, toLeftOf and near that find elements by their position relative to another element.
33

How do you group tests?

Save to ▾
Show answer
Tag tests with groups = {"smoke","regression"} and include or exclude them in testng.xml to run chosen sets.
34

How do you upload a file with Selenium?

Save to ▾
Show answer
If the element is <input type="file">, use element.sendKeys("C:/path/file.pdf"). Use the Robot class or AutoIt only as a last resort for OS dialogs.
35

What is REST Assured?

Save to ▾
Show answer
A Java library that makes API tests readable using given-when-then, with easy request building, response validation and JSON path support.
36

What is contract testing?

Save to ▾
Show answer
Verifying that a provider and consumer agree on request and response formats, using tools like Pact, to catch breaking changes early.
37

How do you retry failed tests in TestNG?

Save to ▾
Show answer
Implement IRetryAnalyzer with a retry count and attach it through the test annotation or a listener to rerun flaky tests.
38

What is the Hybrid framework?

Save to ▾
Show answer
A framework combining data-driven, keyword-driven and POM approaches with reporting and utilities, giving flexibility and reuse.
39

What is the difference between throw and throws?

Save to ▾
Show answer
throw actually raises an exception object inside a method; throws declares in the method signature that it may pass an exception to the caller.
40

How do you run JavaScript in Selenium?

Save to ▾
Show answer
Cast the driver to JavascriptExecutor and use executeScript, for example to scroll into view or click hidden elements.
41

What are the Actions class use cases?

Save to ▾
Show answer
Mouse and keyboard actions such as hover, drag and drop, double click, right click and key combinations, built with moveToElement(...).perform().
42

What are Java 8 streams and lambdas?

Save to ▾
Show answer
Lambdas are short anonymous functions; streams process collections declaratively with filter, map and collect, for example filtering link text from a list of elements.
43

What are Java collections and which ones do testers use most?

Save to ▾
Show answer
ArrayList and LinkedList for lists, HashSet for unique values, HashMap for key-value test data, and Iterator for traversing them, for example collecting web elements in a list.
44

What new features came with Selenium 4?

Save to ▾
Show answer
Relative locators, improved Grid, W3C compliance, new window or tab creation, Chrome DevTools Protocol access and element-level screenshots.
45

Where do you use OOP concepts in your framework?

Save to ▾
Show answer
Encapsulation: private locators with public page methods. Inheritance: pages extend a BasePage. Polymorphism: the WebDriver interface for different browsers. Abstraction: utility layers hiding Selenium details.
46

How do you handle iframes?

Save to ▾
Show answer
switchTo().frame(index, name or element) enters the frame, and switchTo().defaultContent() returns to the main page.
47

How do you scroll a page in Selenium?

Save to ▾
Show answer
Use JavascriptExecutor with window.scrollTo or scrollIntoView, or the Actions class scroll methods in Selenium 4.
48

What does dependsOnMethods do?

Save to ▾
Show answer
It makes a test run only after specified tests pass, otherwise it is skipped. Use sparingly as it creates coupled tests.
49

How do you handle a web table in Selenium?

Save to ▾
Show answer
Locate rows and columns with XPath such as //table//tr and //td, loop through them to read or click cells, or build the XPath dynamically from the row text.
50

Write a GET test in REST Assured.

Save to ▾
Show answer
given().baseUri(url) .when().get("/users/1") .then().statusCode(200).body("id", equalTo(1));
51

What is polymorphism and how does it show up in Selenium?

Save to ▾
Show answer
One interface, many forms. WebDriver driver = new ChromeDriver() lets the same test code run on any browser class that implements WebDriver.
52

What is the difference between @BeforeTest and @BeforeMethod?

Save to ▾
Show answer
@BeforeTest runs once before all methods in a test tag of testng.xml; @BeforeMethod runs before every test method.
53

Difference between absolute and relative XPath?

Save to ▾
Show answer
Absolute starts from the root (/html/...) and breaks easily; relative starts anywhere with // and is more stable, for example //input[@id='email'].
54

How do you integrate Selenium tests with Jenkins?

Save to ▾
Show answer
Create a job or pipeline that checks out code, runs mvn test, publishes reports and triggers on commits or schedules.
55

What is a Jenkins pipeline?

Save to ▾
Show answer
A scripted or declarative Jenkinsfile that defines stages such as build, test and deploy as code stored with the project.
56

What is the difference between static and non-static members?

Save to ▾
Show answer
Static members belong to the class and are shared by all instances; non-static members belong to each object.
57

How does the DataProvider annotation work?

Save to ▾
Show answer
A method annotated with @DataProvider returns a 2D object array and the test with dataProvider = "name" runs once per row.
58

How do you switch between windows and tabs?

Save to ▾
Show answer
Get getWindowHandles(), loop to find the target, and call driver.switchTo().window(handle); switch back using the stored parent handle.
59

What is BDD and how does Cucumber work?

Save to ▾
Show answer
Behaviour-driven development writes scenarios in Given-When-Then Gherkin that map to step definitions in code, so business and QA share one language.
60

How do you manage test data in a framework?

Save to ▾
Show answer
Use external files or APIs and database setup scripts, generate unique data per run, and clean up afterwards so tests stay independent.
61

How do you handle multiple windows?

Save to ▾
Show answer
String parent = driver.getWindowHandle(); for (String h : driver.getWindowHandles()) if (!h.equals(parent)) driver.switchTo().window(h); // ...then switch back to parent
62

What are access modifiers in Java?

Save to ▾
Show answer
public (everywhere), protected (package and subclasses), default (package) and private (same class), used to control visibility of test utilities.
63

What is the difference between SOAP and REST?

Save to ▾
Show answer
SOAP is a strict XML protocol with WSDL and WS-Security; REST is a lighter architectural style using HTTP and usually JSON.
64

What is the difference between getText() and getAttribute()?

Save to ▾
Show answer
getText returns visible inner text; getAttribute returns an HTML attribute or property such as value, href or class.
65

How do you handle alerts and pop-ups?

Save to ▾
Show answer
driver.switchTo().alert() lets you accept, dismiss, read text or send keys. Browser windows are handled with window handles.
66

What is a DataProvider in TestNG?

Save to ▾
Show answer
@DataProvider returns Object[][]; a @Test(dataProvider = "name") method runs once per row — the basis of data-driven tests, often reading Excel or JSON.
67

How do you make WebDriver thread-safe for parallel runs?

Save to ▾
Show answer
Store each driver in a ThreadLocal so every thread gets its own instance and tests do not interfere.
68

How do you handle dynamic elements whose ids change?

Save to ▾
Show answer
Use CSS or XPath with contains(), starts-with() or stable attributes, relative axes, or data-test attributes agreed with developers.
69

How do you pass authentication in an API test?

Save to ▾
Show answer
Use headers such as Bearer tokens, basic auth, API keys or OAuth flows; fetch a token in a setup step and reuse it.
70

How do you handle dropdowns in Selenium?

Save to ▾
Show answer
Use the Select class with selectByVisibleText, selectByValue or selectByIndex; for custom dropdowns click and choose from the list of elements.
71

What are listeners in TestNG?

Save to ▾
Show answer
Classes like ITestListener that react to events such as test start, success or failure, commonly used for screenshots and reporting.
72

What is Postman and how do you automate with it?

Save to ▾
Show answer
An API client. Add tests in JavaScript, use environments and collections, and run them with Newman in a CI pipeline.
73

Difference between ArrayList and LinkedList?

Save to ▾
Show answer
ArrayList has fast random access and slower inserts in the middle; LinkedList has fast inserts and deletes but slow access by index.
74

What is the difference between hard and soft assertions?

Save to ▾
Show answer
Hard assert stops the test at the first failure; SoftAssert collects failures and reports them together when assertAll() is called.
75

Which reporting tools do you use?

Save to ▾
Show answer
TestNG reports, ExtentReports and Allure give charts, screenshots and logs that are easy to share with the team.
76

What is the Background keyword and when should you avoid it?

Save to ▾
Show answer
Background holds steps that run before every scenario in a feature file, such as opening the app and logging in. It removes repetition in Given steps. Avoid it when it becomes long, when only some scenarios need it, or when it hides important context, because readers then cannot understand a scenario on its own. In that case use a hook or a clearer Given step.
77

What are Cucumber hooks and how are they different from Background?

Save to ▾
Show answer
Hooks are Java methods annotated with @Before, @After, @BeforeStep and @AfterStep that run around scenarios or steps. Background is visible in the feature file and describes business preconditions; hooks are hidden technical setup such as starting the browser, cleaning data or attaching screenshots. Hooks can be ordered with the order attribute and filtered by tag expressions, for example @Before("@ui").
78

What are Cucumber Expressions and how do they differ from regular expressions?

Save to ▾
Show answer
Cucumber Expressions are the default, simpler way to match steps, using parameter types like {int}, {string}, {word} and {float}. For example "I add {int} items" captures a number and converts it to an Integer automatically. Regular expressions are still supported and offer more control, but are harder to read. Teams usually prefer Cucumber Expressions and define custom parameter types for domain values.
79

How do you share state between step definition classes in Cucumber Java?

Save to ▾
Show answer
Use dependency injection. With cucumber-picocontainer (or Spring/Guice), create a context class such as TestContext holding the driver, page objects and scenario data, and add it as a constructor parameter in every step class. Cucumber creates one instance per scenario and injects the same object everywhere, so state is shared within a scenario but never leaks between scenarios. Avoid static fields because they break parallel runs.
80

What is a DataTable in Cucumber and how do you use it?

Save to ▾
Show answer
A DataTable passes a table written under a step into the step definition. You can read it as List<String>, List<Map<String,String>>, Map<String,String> or convert rows into objects with a @DataTableType method. For example a step that creates several users can take a table of name, role and email. Unlike Scenario Outline, a DataTable feeds data into one step and the scenario runs once.
81

Write a step definition that reads a DataTable as a list of maps.

Save to ▾
Show answer
// Given the following users exist @Given("the following users exist") public void usersExist(DataTable table) { List<Map<String, String>> rows = table.asMaps(); for (Map<String, String> row : rows) { userApi.create(row.get("name"), row.get("role")); } }
82

What makes a good Gherkin scenario?

Save to ▾
Show answer
A good scenario describes one behaviour in business language, uses declarative steps ("When the user logs in as a manager") rather than UI clicks ("When I click the login button"), has one When and a clear Then, stays under about 5 to 7 steps and is independent of other scenarios. The title should state the rule being checked so failures are understood without opening the code.
83

What is the difference between imperative and declarative Gherkin?

Save to ▾
Show answer
Imperative Gherkin lists UI actions: enter username, enter password, click submit. Declarative Gherkin states intent: Given a registered customer is logged in. Declarative steps are shorter, survive UI changes and are understood by business people; the UI detail lives in step definitions and page objects. Imperative style is acceptable only when the exact interaction is the behaviour being tested.
84

Cucumber says a step is undefined even though the step definition exists. How do you fix it?

Save to ▾
Show answer
Check the glue path in the runner points to the package containing the step classes. Check the step text matches exactly, including quotes and parameter types, since {string} expects quoted text. Confirm the step class is under src/test/java and compiled, the annotation import is io.cucumber.java.en, and the Cucumber versions of core, java and the runner module match. Running with dryRun shows all unmatched steps quickly.
85

What causes an AmbiguousStepDefinitionsException?

Save to ▾
Show answer
It occurs when one Gherkin step matches two or more step definitions, usually because of broad regular expressions or duplicate methods in different classes within the glue. Fix it by making expressions more specific, anchoring regexes with ^ and $, or removing the duplicate. Keeping step definitions organised by domain and reviewing new steps in pull requests prevents it.
86

How do you attach a screenshot to the Cucumber report when a scenario fails?

Save to ▾
Show answer
@After public void afterScenario(Scenario scenario) { if (scenario.isFailed()) { byte[] shot = ((TakesScreenshot) driver) .getScreenshotAs(OutputType.BYTES); scenario.attach(shot, "image/png", scenario.getName()); } driver.quit(); }
87

How do you rerun only failed Cucumber scenarios?

Save to ▾
Show answer
Add the rerun plugin, for example rerun:target/failed.txt, to the main runner. It writes the location of each failed scenario. Create a second runner whose features point to @target/failed.txt and run it after the main run in Maven or Jenkins. Use reruns to separate real failures from flaky ones, but track flaky scenarios and fix them instead of hiding them.
88

Should every test in a project be written in Cucumber?

Save to ▾
Show answer
No. Cucumber adds a translation layer, so it is worth it for business-facing acceptance tests that stakeholders discuss. Unit tests, low-level API checks, data validations and technical edge cases are faster to write and maintain directly in TestNG or JUnit. A healthy project uses Cucumber for a focused set of key behaviours and plain code tests for everything else.
89

How do you use Cucumber with REST Assured for API BDD tests?

Save to ▾
Show answer
Write scenarios in business terms, such as "When a customer places an order for 2 items". In step definitions, build the request with REST Assured, store the Response in a shared scenario context, and assert in Then steps using then().statusCode() and JSON path checks. Keep base URI, auth and specs in a helper class so steps stay short and the same steps serve many features.
90

Tell me about a time you introduced BDD to a team. How did it go?

Save to ▾
Show answer
Situation: requirements were often misread, causing rework late in sprints. Task: I proposed BDD for one module. Action: I ran short three-amigos sessions, wrote example scenarios with the BA, automated them with Cucumber and showed them in sprint review. Result: rework on that module dropped noticeably over two sprints, and the team adopted the practice for other complex stories.
91

How do you handle test data cleanup in Cucumber scenarios?

Save to ▾
Show answer
Create data in Given steps through APIs, record the created IDs in the scenario context, and delete them in an @After hook, which runs even when the scenario fails. Use unique names with a timestamp or UUID to avoid clashes in parallel runs. For shared environments, add a nightly cleanup job for leftover data tagged with a test prefix.
92

What is RequestSpecification in REST Assured and why use it?

Save to ▾
Show answer
RequestSpecification holds common request settings such as base URI, base path, headers, content type, authentication and filters. You build it once with RequestSpecBuilder and reuse it with given().spec(reqSpec). This removes repetition, keeps environment settings in one place and makes switching between QA and staging easy. ResponseSpecification does the same for common assertions like status code and content type.
93

What is serialization and deserialization in REST Assured?

Save to ▾
Show answer
Serialization converts a Java object (POJO) into JSON for the request body; deserialization converts the response JSON back into a Java object. REST Assured does this automatically when Jackson or Gson is on the classpath: body(userPojo) serializes and response.as(User.class) deserializes. Using POJOs gives type safety, IDE support and cleaner assertions compared with hand-written JSON strings.
94

What is JsonPath and how do you use it for nested JSON?

Save to ▾
Show answer
JsonPath (Groovy GPath syntax in REST Assured) navigates JSON with dot notation. For {"data":{"items":[{"price":10}]}} you use data.items[0].price. You can also filter: data.items.findAll { it.price > 5 }.name returns names of items costing more than 5. Use it inside body() assertions or via response.jsonPath().getList("data.items.name") to extract values for further checks.
95

How do you validate a response against a JSON schema in REST Assured?

Save to ▾
Show answer
Add the json-schema-validator dependency, place the schema file in src/test/resources, and assert with then().body(matchesJsonSchemaInClasspath("user-schema.json")). Schema validation checks field types, required fields and structure, so it catches contract changes that value checks might miss. It complements, not replaces, assertions on business values like status or totals.
96

What are filters in REST Assured?

Save to ▾
Show answer
Filters intercept requests and responses, similar to middleware. They implement the Filter interface and can add headers, refresh tokens, log traffic, or attach request and response details to Allure reports with AllureRestAssured. You add them with given().filter(myFilter) or globally in a RequestSpecification. Filters keep cross-cutting concerns out of individual tests.
97

How do you handle authentication types in REST Assured?

Save to ▾
Show answer
Basic auth uses auth().preemptive().basic(user, pass). Bearer tokens are set as a header: header("Authorization", "Bearer " + token). OAuth 2.0 can use auth().oauth2(token) after fetching the token from the token endpoint. API keys go in a header or query param. Fetch tokens once per suite or cache them with an expiry check rather than logging in before every test.
98

Write a REST Assured test that deserializes a response into a POJO.

Save to ▾
Show answer
@Test public void getUserAsPojo() { User user = given() .pathParam("id", 2) .when() .get("/users/{id}") .then() .statusCode(200) .extract().as(User.class); Assert.assertEquals(user.getId(), 2); Assert.assertNotNull(user.getEmail()); }
99

How do you upload a file with REST Assured?

Save to ▾
Show answer
Use multipart: given().multiPart("file", new File("src/test/resources/report.pdf"), "application/pdf").formParam("type", "invoice").when().post("/upload").then().statusCode(200). REST Assured sets the multipart/form-data content type automatically. Verify both the status and the response, such as the returned file id or size, and test edge cases like empty, oversized and wrong-type files.
100

How do you assert on an array in a JSON response using Hamcrest?

Save to ▾
Show answer
Use collection matchers inside body(). For example body("data.id", hasItems(1, 2)), body("data", hasSize(6)), body("data.email", everyItem(containsString("@"))) and body("data.find { it.id == 3 }.name", equalTo("Neha")). These check the whole collection in one line. For complex rules, extract a List with jsonPath().getList() and assert with Java or AssertJ.
101

How do you test negative scenarios for an API?

Save to ▾
Show answer
Send invalid or missing fields, wrong data types, values beyond limits, invalid IDs, expired or missing tokens, wrong HTTP methods and malformed JSON. Assert the correct status (400, 401, 403, 404, 405, 422) and a clear error body without stack traces. Negative tests often find more defects than happy paths because validation and security checks are frequently incomplete.
102

Write a REST Assured test using RequestSpecBuilder and ResponseSpecBuilder.

Save to ▾
Show answer
RequestSpecification req = new RequestSpecBuilder() .setBaseUri(Config.baseUrl()) .setContentType(ContentType.JSON) .addHeader("Authorization", "Bearer " + token) .build(); ResponseSpecification ok = new ResponseSpecBuilder() .expectStatusCode(200) .expectContentType(ContentType.JSON) .build(); given().spec(req).when().get("/orders").then().spec(ok);
103

How do you test an API that returns paginated results?

Save to ▾
Show answer
Call the first page, check page size, total count and the next link or cursor. Loop through pages until there is no next page, collecting IDs, then assert no duplicates and the total matches the reported count. Also test edge cases: page 0, a page beyond the last, invalid page size and sorting stability. Cap the loop to avoid endless runs if the API misbehaves.
104

How do you build dynamic JSON request bodies without hard-coded strings?

Save to ▾
Show answer
Use POJOs with a builder pattern or Lombok @Builder, so tests write User.builder().name("Ravi").role("QA").build(). For quick cases use a HashMap or Jackson ObjectNode. For large templates, keep a JSON file and change fields with a JSON library. Combine with a faker library for unique values. This avoids escaping issues and makes changes to the schema easy to update.
105

Your API tests started failing with SSL handshake errors on a new test server. What do you do?

Save to ▾
Show answer
First confirm the server uses a self-signed or internal certificate. The proper fix is to import the company CA certificate into a truststore and configure REST Assured with trustStore(path, password). As a temporary measure in a test environment only, relaxedHTTPSValidation() skips checks. Never use relaxed validation against production, and raise the certificate issue with the infra team.
106

Should assertions be written inside page objects?

Save to ▾
Show answer
Generally no. Page objects should expose state and actions, such as getErrorMessage() or isLoggedIn(), and tests should make the assertions. This keeps page classes reusable across positive and negative tests and keeps the test intent visible. A small exception is a simple check that the correct page has loaded, often done in the constructor or an isAt() method.
107

What is method chaining in Page Object Model?

Save to ▾
Show answer
Method chaining means page methods return a page object, either this or the next page, so calls can be linked: loginPage.enterUser("asha").enterPassword("x").submit().openOrders(). Returning the next page models navigation and makes tests read like a user journey. Be careful when an action can lead to different pages; return the correct type or provide separate methods for success and failure.
108

What is a BasePage and what should it contain?

Save to ▾
Show answer
BasePage is a parent class for all page objects holding common things: the driver reference, a WebDriverWait, and helper methods such as click with wait, type, getText, waitForVisible and scrollIntoView. Child pages extend it and stay focused on page-specific locators and actions. Keep it small; if it grows into hundreds of methods, move helpers into separate utility classes using composition.
109

What are page components or page fragments in POM?

Save to ▾
Show answer
Components are classes for UI parts that repeat across pages, such as the header, search bar, date picker or a data table. A page object then has-a component: homePage.header().search("laptop"). This follows composition over inheritance, avoids duplicate locators and matches modern component-based frontends. Components are usually scoped to a root WebElement so locators search only inside that element.
110

How do you handle waits inside page objects?

Save to ▾
Show answer
Put explicit waits in page methods or BasePage helpers, not in tests. For example click() waits for elementToBeClickable before clicking, and a page's isLoaded() waits for a key element. Avoid Thread.sleep and avoid mixing implicit and explicit waits. Keep the timeout configurable so CI can use a slightly longer value than local runs.
111

How do you pass the WebDriver to page objects in a parallel framework?

Save to ▾
Show answer
Use a DriverManager with a ThreadLocal<WebDriver>, created in @BeforeMethod and removed in @AfterMethod. Page objects receive the driver through the constructor or get it from DriverManager.getDriver(). Constructor injection is cleaner and easier to test. Never store the driver in a static field shared by all threads, or parallel tests will control each other's browsers.
112

A developer changed the UI and 40 tests failed with NoSuchElementException. How does POM help here?

Save to ▾
Show answer
Because locators live only in page classes, I check which page object methods fail, update the changed locators in those few classes, and rerun. Usually 40 failures map to two or three locators. I would also ask developers to add stable data-testid attributes and review UI changes with QA early, so future changes do not break tests unexpectedly.
113

How do you avoid page object classes becoming too large?

Save to ▾
Show answer
Split pages into components for repeated or complex areas, keep only user actions as public methods, move generic helpers to BasePage or utilities, and avoid one method per element. If a page has distinct modes like view and edit, use separate classes. Review page classes during code review and refactor when they cross a few hundred lines.
114

How do you verify that the correct page has loaded in POM?

Save to ▾
Show answer
Give each page an isAt() or waitUntilLoaded() method that waits for a unique element, page title or URL fragment. Call it in the constructor or right after navigation. If it fails, throw a clear error such as "Expected Cart page but URL was /login". This catches navigation problems at the right point instead of failing later with a confusing locator error.
115

Write a BasePage helper that clicks an element after waiting for it to be clickable.

Save to ▾
Show answer
public abstract class BasePage { protected final WebDriver driver; protected final WebDriverWait wait; protected BasePage(WebDriver driver) { this.driver = driver; this.wait = new WebDriverWait(driver, Duration.ofSeconds(10)); } protected void click(By locator) { wait.until(ExpectedConditions.elementToBeClickable(locator)).click(); } }
116

What is the Fluent Page Object pattern?

Save to ▾
Show answer
Fluent page objects return objects from every action so a test reads like a sentence, for example new SearchPage(driver).searchFor("phone").filterByBrand("X").sortByPrice().firstResult(). It improves readability and models navigation. The risk is long chains that hide failures, so keep chains to a single journey and use clear method names that show which page you end on.
117

How do you handle a component that appears inside many different pages, like a modal dialog?

Save to ▾
Show answer
Create a ModalComponent class scoped to the modal root element, with methods like title(), confirm() and cancel(). Pages that open modals return the component, such as cartPage.removeItem() returning ConfirmModal. The component waits for itself to appear and disappear. This keeps modal logic in one place and avoids copying locators into every page.
118

What are the disadvantages of POM?

Save to ▾
Show answer
POM adds upfront design effort and extra classes, which can feel heavy for tiny projects. Poorly designed page objects become large god classes, mix assertions with actions, or use deep inheritance chains that are hard to follow. It also does not solve flaky waits or bad test data by itself. Good conventions, components and code reviews are needed to get its benefits.
119

How do you make page objects work with dynamic locators, such as a row containing a given name?

Save to ▾
Show answer
Write a method that builds the locator from a parameter, for example private By rowFor(String name) { return By.xpath("//tr[td[normalize-space()='" + name + "']]"); }, and expose actions like deleteUser(name). Keep the template in the page class, not in tests. Escape quotes if names may contain them, and prefer CSS with data attributes when the application provides them.
120

Describe a time you improved the maintainability of an automation framework.

Save to ▾
Show answer
Situation: our suite had duplicated locators across 200 tests and each UI release broke many of them. Task: reduce maintenance effort. Action: I introduced page objects and components for the top ten pages, added data-testid attributes with the developers and wrote a short guide. Result: fixing a UI change went from half a day to under an hour, and new joiners wrote tests faster.
121

What is the difference between git merge and git rebase?

Save to ▾
Show answer
Merge combines branches by creating a merge commit, keeping the full history exactly as it happened. Rebase replays your commits on top of another branch, producing a straight, linear history without a merge commit. Rebase is good for tidying a local feature branch before a pull request; never rebase commits that others have already pulled, because it rewrites history.
122

What is the Maven Surefire plugin and how do you configure it for TestNG?

Save to ▾
Show answer
Surefire runs tests during the test phase. For TestNG, configure suiteXmlFiles with the path to testng.xml, so mvn test runs that suite. You can pass system properties, set parallel and threadCount, and control reports. Make the suite file a property like ${suiteXml} so CI can choose smoke.xml or regression.xml with -DsuiteXml=smoke.xml.
123

What are Maven dependency scopes?

Save to ▾
Show answer
compile is the default and available everywhere. test is only for test compile and run, such as TestNG and REST Assured. provided is needed for compiling but supplied at runtime by the container. runtime is not needed to compile but needed to run, like JDBC drivers. system and import are rarer. In test projects, mark test libraries as test scope unless framework code in src/main uses them.
124

What are Maven profiles and how do you use them in automation?

Save to ▾
Show answer
Profiles are sets of configuration activated by name, such as -Pqa or -Pstaging, or by conditions. In automation they switch environment URLs, suite files, browsers or parallel settings without changing code. For example a regression profile sets suiteXml to regression.xml and threadCount to 4. Combined with properties files, profiles keep one codebase for every environment.
125

What is the difference between a declarative and a scripted Jenkins pipeline?

Save to ▾
Show answer
Declarative pipelines use a fixed structure: pipeline, agent, stages, steps, post, with built-in options and validation; they are easier to read and are the recommended default. Scripted pipelines use node blocks and full Groovy, giving more flexibility for complex logic but making them harder to maintain. Most test pipelines use declarative syntax with small script blocks only where needed.
126

Write a declarative Jenkinsfile that runs Maven tests and publishes results.

Save to ▾
Show answer
pipeline { agent any parameters { choice(name: 'SUITE', choices: ['smoke', 'regression']) } stages { stage('Checkout') { steps { checkout scm } } stage('Test') { steps { sh "mvn clean test -DsuiteXml=${params.SUITE}.xml" } } } post { always { junit 'target/surefire-reports/*.xml' archiveArtifacts artifacts: 'target/screenshots/**', allowEmptyArchive: true } } }
127

How do you store passwords and tokens safely in Jenkins?

Save to ▾
Show answer
Use the Jenkins Credentials store and bind them in the pipeline with withCredentials or the credentials() helper in environment blocks. Jenkins masks the values in console logs. Never hard-code secrets in the Jenkinsfile, pom.xml or properties files committed to Git. For larger setups, integrate a vault service and give each job only the credentials it needs.
128

Your Jenkins test stage marks the build green even though tests failed. Why?

Save to ▾
Show answer
Possibly testFailureIgnore is set to true in Surefire, the shell step uses || true, or the script swallows Maven's exit code. Sometimes tests catch exceptions and never fail. Check the console log for Maven's BUILD result and Surefire summary. Fix the configuration so failures produce a non-zero exit, or use junit publishing to mark the build unstable when tests fail.
129

What branching strategy do you use for test automation code?

Save to ▾
Show answer
Most teams use trunk-based development or a light GitHub Flow: short-lived feature branches from main, a pull request with review and a CI run, then merge. Long-lived branches cause painful conflicts. Keep automation code in the same repository as the app when possible so tests change together with features, or tag test versions to match app releases.
130

What is git cherry-pick?

Save to ▾
Show answer
git cherry-pick <commit> applies the changes of one specific commit onto your current branch, creating a new commit. It is useful when a fix on one branch, such as a locator fix on develop, is urgently needed on a release branch without merging everything else. Overuse creates duplicate commits and confusing history, so prefer normal merges when possible.
131

How do you undo a commit that has already been pushed?

Save to ▾
Show answer
Use git revert <commit>, which creates a new commit that reverses the changes and keeps history intact, safe for shared branches. git reset moves the branch pointer backwards and is fine for local commits, but resetting and force-pushing a shared branch rewrites history and breaks teammates' clones. If force push is truly needed, use --force-with-lease and tell the team.
132

Tell me about a time a CI pipeline you owned broke right before a release.

Save to ▾
Show answer
Situation: the night before release, every UI test failed in Jenkins. Task: find the cause fast and unblock the release. Action: I checked the console and saw a browser and driver version mismatch after an agent update, pinned the browser image version, reran the suite and shared a short note. Result: the release went out on time and we added image version pinning to the pipeline.
133

How do you publish Allure or Extent reports from Jenkins?

Save to ▾
Show answer
For Allure, install the Allure Jenkins plugin, configure the commandline tool, and add allure results: [[path: 'target/allure-results']] in the post always block. For Extent, archive the HTML file and use the HTML Publisher plugin to show it as a build link. Keep report history per build and share the link in failure notifications.
134

What is idempotency in REST APIs and why does it matter for testing?

Save to ▾
Show answer
An idempotent operation gives the same result no matter how many times it is called. GET, PUT and DELETE should be idempotent; POST usually is not. Testers verify that repeating a PUT does not create duplicates and that a second DELETE returns a sensible status like 404 or 204. Retries in networks and CI make idempotency important to verify.
135

What is a quality gate in a CI/CD pipeline?

Save to ▾
Show answer
A quality gate is a rule a build must pass before moving forward, such as all smoke tests passing, code coverage above a threshold, no critical static analysis issues, or no new high-severity vulnerabilities. If the gate fails, the pipeline stops and the change is not deployed. Gates make quality an automatic decision instead of a manual check.
136

Which tests should run at each stage of a CI/CD pipeline?

Save to ▾
Show answer
On every commit or pull request: unit tests, static checks and a fast API and UI smoke suite. After deploying to a test environment: broader API and integration tests. Nightly: full UI regression across browsers. Before or after production release: a short production-safe smoke and monitoring checks. Faster feedback first, heavier tests later.
137

How do you mock an external API in automation tests?

Save to ▾
Show answer
Use a tool such as WireMock or MockServer to run a stub server that returns predefined responses for given requests. Point the application or tests to the stub with configuration. This lets you test error codes, timeouts and edge cases that are hard to trigger on the real service, and keeps tests stable when the third party is down. Still keep a few tests against the real integration.
138

How do you run Selenium tests in Docker containers in CI?

Save to ▾
Show answer
Use official Selenium images, either standalone-chrome for simple runs or a Grid with hub and node containers via Docker Compose. The test container or Jenkins agent points RemoteWebDriver to http://selenium-hub:4444. Containers give the same browser version everywhere and are cleaned after each run. Add shm_size for Chrome stability and record videos for failed tests if needed.
139

Tests pass on QA but fail in the staging pipeline. How do you investigate?

Save to ▾
Show answer
Compare what differs: configuration URLs, test data, feature flags, user permissions, network or proxy, browser versions and timing due to slower servers. Check logs and screenshots from staging and rerun one failing test with verbose logging. Often the issue is missing data or a flag. Fix by making environment settings explicit and creating required data in test setup.
140

How would you test an API with rate limiting?

Save to ▾
Show answer
Read the documented limit, then send requests quickly until you exceed it and assert a 429 Too Many Requests response with headers like Retry-After or remaining quota. Wait for the window to reset and confirm requests succeed again. Also check limits are per user or key as designed. Run these tests in isolation so they do not throttle the rest of the suite.
141

Describe a time you convinced developers to fix a problem found by automation.

Save to ▾
Show answer
Situation: an API test kept failing intermittently and developers called it a test issue. Task: prove or disprove it. Action: I collected logs from ten failures, showed the same race condition in the order service with request IDs, and reproduced it with a small parallel script. Result: developers fixed a real concurrency bug before it reached customers, and trust in the suite improved.
142

What is the difference between @Test(priority) and dependsOnMethods in TestNG?

Save to ▾
Show answer
priority only orders tests; a lower number runs first, and a failed test does not stop the others. dependsOnMethods creates a real dependency: if the parent test fails, dependent tests are skipped. Both make tests order-dependent, which hurts parallel runs and isolation, so use them sparingly. Prefer independent tests with their own setup.
143

What does alwaysRun = true do in TestNG?

Save to ▾
Show answer
On a configuration method like @AfterMethod(alwaysRun = true), it makes the method run even when tests fail or are skipped, or when groups filter would exclude it. It is essential for cleanup such as driver.quit(). On a test with dependsOnMethods, alwaysRun = true runs it even if the dependency failed. Missing alwaysRun on teardown is a common cause of leftover browsers in CI.
144

What is the difference between parallel="methods", "classes" and "tests" in testng.xml?

Save to ▾
Show answer
methods runs each @Test method in its own thread, giving the most parallelism but requiring fully independent tests and thread-safe drivers. classes runs all methods of one class in the same thread, with different classes in parallel. tests runs each <test> tag in parallel, often used to run different browsers. instances is also available for factory instances. thread-count sets the pool size.
145

Write a TestNG listener that logs test start and failure.

Save to ▾
Show answer
public class LogListener implements ITestListener { @Override public void onTestStart(ITestResult r) { System.out.println("START: " + r.getMethod().getMethodName()); } @Override public void onTestFailure(ITestResult r) { System.out.println("FAIL: " + r.getName() + " - " + r.getThrowable()); } } // register with @Listeners(LogListener.class) or <listeners> in testng.xml
146

How do you run the same test with data from Excel using a DataProvider?

Save to ▾
Show answer
Write a utility that reads the sheet with Apache POI and returns Object[][] with one row per test case. Create a @DataProvider method that calls the utility, and set dataProvider = "loginData" on the test. Each row runs as a separate test with its own result. Keep the file in src/test/resources and consider CSV or JSON, which are easier to review in Git.
147

Half of your TestNG tests are skipped in CI with no failure shown. What could cause it?

Save to ▾
Show answer
Usually a configuration method failed, such as @BeforeClass or @BeforeSuite throwing an exception, which makes TestNG skip dependent tests. Other causes are dependsOnMethods on a failed test, a group filter excluding setup methods without alwaysRun, or a DataProvider that threw an exception. Check the configuration failures section of the report and the log for the first exception.
148

What are TestNG and JUnit 5 differences that matter in automation?

Save to ▾
Show answer
TestNG has built-in groups, dependencies, suite XML, DataProvider and flexible parallel options, which suit large Selenium suites. JUnit 5 has a modular platform, tags, parameterized tests, extensions and strong IDE and tool support, and is the default for Spring and Cucumber's JUnit Platform engine. Both are capable; the choice usually follows team standards and existing frameworks.
149

A TestNG test passes when run alone but fails when the full class runs. What do you check?

Save to ▾
Show answer
Look for shared state between methods: instance or static fields changed by earlier tests, data created or deleted by another test, cookies or logged-in session kept in the same browser, and priority or order assumptions. Run the class in a different order to confirm. Fix by resetting state in @BeforeMethod, creating unique data per test and avoiding static fields.
150

Your CI pipeline is blocked because a downstream service needed for API tests is often down. What do you do?

Save to ▾
Show answer
Add a health check stage that pings dependencies before tests and marks the run as environment failure rather than test failure. For tests that do not need the real service, use stubs. Escalate with data on downtime frequency to the team owning the service. Keep a separate scheduled job for the real integration tests so pull requests are not blocked.
151

A test reading a properties file works in the IDE but fails in Jenkins with FileNotFoundException. Why?

Save to ▾
Show answer
The file path is probably hard-coded or relative to the IDE working directory, or uses Windows backslashes while Jenkins runs on Linux. Load the file from the classpath with getClass().getClassLoader().getResourceAsStream("config.properties") and keep it in src/test/resources, or build paths with Paths.get. Also check the file is committed to Git and not ignored.
152

You see ConcurrentModificationException in your test utility. What causes it and how do you fix it?

Save to ▾
Show answer
It occurs when a collection is modified while being iterated with a for-each loop, for example removing items from an ArrayList inside the loop. Fix by using Iterator.remove(), removeIf(), collecting items to remove separately, or using CopyOnWriteArrayList or ConcurrentHashMap when threads share the collection. In parallel tests, shared lists are a common source.
153

Your price comparison test fails because 19.99 + 0.01 is not equal to 20.0. Why?

Save to ▾
Show answer
double uses binary floating point, which cannot represent many decimal values exactly, so small rounding errors appear. For money, use BigDecimal created from strings and compare with compareTo(), or compare doubles with a tolerance such as Assert.assertEquals(actual, expected, 0.001). Also strip currency symbols and commas before parsing UI text.
154

A test configuration value has to be the same for the whole run and accessed from many classes. How do you implement it?

Save to ▾
Show answer
Create a ConfigReader that loads properties once, using a singleton or a static holder initialised lazily in a thread-safe way, and exposes typed getters like getInt("timeout"). Let system properties and environment variables override file values so CI can change them. Keep it read-only after loading so parallel threads cannot change settings mid-run.
155

Your code review shows a test class with 30 copy-pasted lines in every method. How do you refactor it with Java features?

Save to ▾
Show answer
Extract repeated steps into private helper methods or a page object, move common setup into @BeforeMethod, and use a DataProvider when only data differs. If the repeated code differs only in a small action, pass that action as a lambda, such as a Consumer<WebDriver>. Rerun the tests after each small refactor to confirm behaviour is unchanged.
156

Write a Java stream that extracts and sorts product prices from a list of WebElements.

Save to ▾
Show answer
List<Double> prices = driver.findElements(By.cssSelector(".price")) .stream() .map(WebElement::getText) .map(t -> t.replaceAll("[^0-9.]", "")) .map(Double::parseDouble) .sorted() .collect(Collectors.toList()); System.out.println(prices);
157

Tell me about a time you mentored a junior tester in Java and automation.

Save to ▾
Show answer
Situation: two new joiners from manual testing struggled with framework code. Task: help them contribute within a sprint. Action: I paired with them daily for an hour, gave small tasks like adding a locator then a full test, and reviewed their code with explanations rather than rewriting it. Result: within three weeks both were writing tests independently, and our automation backlog shrank.
158

How have you handled disagreement with a developer about whether something is a bug?

Save to ▾
Show answer
Situation: a developer said a rounding difference in invoice totals was expected. Task: resolve it without friction. Action: I checked the requirement, found it specified rounding per line, and brought the document and a test case with expected values to a quick call with the BA. Result: the BA confirmed it was a bug, it was fixed, and we added the rule to the acceptance criteria.
159

A click works locally but throws ElementClickInterceptedException in CI. How do you fix it?

Save to ▾
Show answer
Another element, such as a cookie banner, loader overlay or sticky header, covers the target. In CI the window is often smaller, so the layout differs. Set a fixed window size, wait for the overlay to disappear with invisibilityOfElementLocated, close banners in setup and scroll the element into view. Use a JavaScript click only as a last resort, since it bypasses real user behaviour.
160

A test fails with TimeoutException waiting for an element that is clearly visible on screen. What do you check?

Save to ▾
Show answer
Check whether the element is inside an iframe or shadow DOM, the locator matches a different hidden element first, the page opened in a new tab not yet switched to, or the wait condition is wrong, such as presence versus visibility versus clickable. Use findElements to see how many matches the locator has and verify it in browser DevTools.
161

How do you handle an element inside a shadow DOM in Selenium 4?

Save to ▾
Show answer
Find the shadow host element, then call getShadowRoot() to get a SearchContext, and search inside it with CSS selectors: driver.findElement(By.cssSelector("my-app")).getShadowRoot().findElement(By.cssSelector("#submit")). XPath does not work inside shadow roots. For nested shadow roots, repeat the step for each host. Closed shadow roots cannot be accessed this way.
162

Write Selenium code to verify that all links on a page are not broken.

Save to ▾
Show answer
List<WebElement> links = driver.findElements(By.tagName("a")); for (WebElement link : links) { String url = link.getAttribute("href"); if (url == null || !url.startsWith("http")) continue; HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection(); con.setRequestMethod("HEAD"); int code = con.getResponseCode(); if (code >= 400) System.out.println("Broken: " + url + " " + code); }
163

Tests run fine on Chrome but fail on Firefox at the same step. How do you investigate?

Save to ▾
Show answer
Rerun on Firefox with screenshots and logs. Common causes are timing differences, different default window sizes, unsupported CSS or JavaScript behaviour, alerts handled differently, or a driver version mismatch. Compare the DOM in both browsers at that step. Fix by using explicit waits, setting window size, and reporting genuine browser bugs to developers.
164

A dropdown option list loads only after typing three letters. How do you automate selecting a value?

Save to ▾
Show answer
Type the text with sendKeys, wait for the suggestion list with visibilityOfAllElementsLocatedBy, then find the option whose text matches the required value and click it. Avoid selecting by index because suggestion order may change. If the list is virtualised, type more characters to narrow results. Verify the selected value in the input afterwards.
165

Your Selenium tests in CI produce blank screenshots in headless mode. What could be wrong?

Save to ▾
Show answer
The screenshot may be taken before the page renders, the window size in headless mode may be tiny, or the browser is crashing due to low shared memory in Docker. Set --window-size=1920,1080, use the new headless mode, wait for page content before capturing, and add --disable-dev-shm-usage or a larger shm size for containers.
166

Describe a situation where automation was not the right answer.

Save to ▾
Show answer
Situation: a manager wanted a one-time data migration check automated in Selenium. Task: give an honest recommendation. Action: I estimated the UI automation effort, showed a SQL comparison plus a manual sample check would finish in a day, and explained the flows would not repeat. Result: we finished faster, and the team now asks for ROI reasoning before automating.
167

Tell me about a time you worked with a team in a different location or time zone on automation.

Save to ▾
Show answer
Situation: our developers were in another time zone and test failures waited a day for replies. Task: reduce delays. Action: I wrote clear failure reports with screenshots, logs and steps, recorded short videos for complex issues, and set a fixed 30-minute overlap call twice a week. Result: turnaround on defects dropped from two days to about one, and fewer issues bounced back.
168

What are the UiAutomator2 and XCUITest drivers in Appium?

Save to ▾
Show answer
They are the platform drivers that actually control the device. UiAutomator2 drives Android by installing a small server app on the device that uses Google's UiAutomator framework. XCUITest drives iOS through Apple's XCTest framework via WebDriverAgent, which needs Xcode and signing for real devices. In Appium 2 they are installed separately with appium driver install, so each project picks only the drivers and versions it needs.
169

What changed in Appium 2 compared with Appium 1?

Save to ▾
Show answer
Appium 2 split the monolithic server into a core plus separately installed drivers and plugins, managed with appium driver install and appium plugin install. It dropped the old JSON Wire Protocol in favour of W3C WebDriver only, so vendor capabilities need the appium: prefix. The default base path changed from /wd/hub to /. Old TouchAction and MultiTouchAction were removed from the Java client, so gestures use W3C Actions or mobile: commands.
170

How do you switch between native and webview contexts in a hybrid app?

Save to ▾
Show answer
// Requires the webview to be debuggable in the app build Set<String> contexts = driver.getContextHandles(); for (String ctx : contexts) { if (ctx.startsWith("WEBVIEW")) { driver.context(ctx); break; } } driver.findElement(By.cssSelector("#email")).sendKeys("qa@test.com"); // back to native controls driver.context("NATIVE_APP");
171

What is the difference between noReset and fullReset in Appium?

Save to ▾
Show answer
By default Appium clears app data between sessions but keeps the app installed. noReset set to true keeps app data and login state, which speeds up tests but can leak state between them. fullReset set to true uninstalls and reinstalls the app, giving the cleanest state but adding time. A common approach is noReset for fast suites with explicit cleanup in the test, and fullReset only for first-launch or onboarding scenarios.
172

How would you explain to a manager why mobile automation estimates are higher than web estimates?

Save to ▾
Show answer
Situation: a manager questioned why my mobile estimate was nearly double the web one. Task: justify it with facts. Action: I listed the extra work: two platforms with separate locators, device and OS version matrix, slower sessions, app builds and signing, gestures and permissions, and device lab maintenance. I showed timings from a pilot of five tests. Result: the manager accepted a phased plan starting with Android smoke tests, and later estimates were trusted because they were data-backed.
173

Why is XPath slow in Appium and what should you use instead?

Save to ▾
Show answer
For every XPath query Appium must fetch the full page source of the app, convert it into an XML document and then evaluate the expression, which can take seconds on large screens and is even slower on iOS. Index-based XPath also breaks when layouts change. Use accessibility id first, then resource-id, Android UiAutomator selectors or iOS predicate strings and class chains, which are evaluated natively on the device and are much faster.
174

An element is visible in Appium Inspector but your test throws NoSuchElementException on the device. What do you check?

Save to ▾
Show answer
First check timing: the screen may still be loading, so add an explicit wait for presence. Then check context: in a hybrid app the element may be in a webview while you are in NATIVE_APP. Confirm the locator matches exactly, including package prefix in resource-id. The element may be off screen in a list, so scroll first. Also check that the Inspector session used the same app build, language and device size as the test.
175

Mobile tests pass on the emulator but fail on a low-end real device. How do you investigate?

Save to ▾
Show answer
Low-end devices are slower, so fixed waits and short timeouts expire before screens render. Replace sleeps with explicit waits and increase timeouts sensibly. Check for vendor-specific pop-ups, battery optimisation dialogs or different keyboards on that brand. Compare screen size and resolution, since coordinate-based taps break. Collect device logs with adb logcat and screen recordings to see what the app was doing. Also check whether the app crashed due to low memory.
176

A mobile test fails intermittently because an animation is still running when you tap. How do you fix it?

Save to ▾
Show answer
Wait for a stable end state instead of sleeping, for example wait until the target element is visible and enabled or until a spinner disappears. On test devices and emulators you can disable animations with adb shell settings put global window_animation_scale 0, along with the transition and animator scales. Ask developers for an idle indicator if needed. Disabling animations makes tests faster and more stable, but keep one manual check of the real animations.
177

Write Java code to start an Android Appium session using UiAutomator2Options.

Save to ▾
Show answer
UiAutomator2Options options = new UiAutomator2Options() .setPlatformName("Android") .setAutomationName("UiAutomator2") .setDeviceName("Pixel_7_API_34") .setApp(System.getProperty("user.dir") + "/apps/shop.apk") .setAutoGrantPermissions(true) .setNewCommandTimeout(Duration.ofSeconds(120)); AndroidDriver driver = new AndroidDriver( new URL("http://127.0.0.1:4723"), options); driver.manage().timeouts().implicitlyWait(Duration.ZERO); // use explicit waits in tests driver.quit();
178

Write Appium code to scroll to an element by its text using UiScrollable on Android.

Save to ▾
Show answer
// Scrolls the first scrollable container until the text is visible String selector = "new UiScrollable(new UiSelector().scrollable(true))" + ".scrollIntoView(new UiSelector().text(\"Order History\"))"; WebElement item = driver.findElement(AppiumBy.androidUIAutomator(selector)); item.click();
179

How do you capture a screen recording of a mobile test and attach it on failure?

Save to ▾
Show answer
// Start before the test, stop and save only if it fails driver.startRecordingScreen(); // ... test steps ... String base64 = driver.stopRecordingScreen(); if (result.getStatus() == ITestResult.FAILURE) { byte[] video = Base64.getDecoder().decode(base64); Files.write(Paths.get("target/videos/" + result.getName() + ".mp4"), video); }
180

Tell me about a time you moved from web automation to mobile automation.

Save to ▾
Show answer
Situation: my team needed Android regression tests and I only knew Selenium. Task: deliver a smoke suite in one month. Action: I learned Appium 2 setup, used Appium Inspector to find locators, asked developers to add accessibility ids, and reused our TestNG, POM and reporting structure with a new driver factory. Result: twenty smoke tests ran nightly on emulators within four weeks, and release smoke testing dropped from half a day to forty minutes.
181

What is the Optional class in Java and where is it useful in test code?

Save to ▾
Show answer
Optional is a container that may or may not hold a value, introduced in Java 8 to avoid returning null. In test code it suits lookups that can legitimately find nothing, such as finding a row in a table or reading an optional config key. Callers use orElse, orElseThrow or ifPresent instead of null checks. For example, findRowByName(name).orElseThrow(() -> new AssertionError(name + " not found")) gives a clear failure message.
182

What are generics in Java and how do they help in a test framework?

Save to ▾
Show answer
Generics let classes and methods work with a type parameter while keeping compile-time type safety, such as List<String> or a method <T> T readJson(String path, Class<T> type). In a framework they let you write one reusable helper for many types, for example a generic API client that deserializes responses into any POJO, or a BasePage method that returns the correct page type for chaining. They remove casts and catch type errors at compile time.
183

What is the difference between the normal, eager and none page load strategies in Selenium?

Save to ▾
Show answer
Page load strategy decides when navigation commands like get() return. Normal, the default, waits for the full load event including images and stylesheets. Eager returns when the DOM is ready (DOMContentLoaded), which speeds up heavy pages. None returns immediately after the initial response. With eager or none you must rely on explicit waits for the elements you need. Set it through options.setPageLoadStrategy(PageLoadStrategy.EAGER).
184

How do you handle a browser basic authentication pop-up in Selenium?

Save to ▾
Show answer
The basic auth dialog is not part of the page, so findElement cannot reach it. The simplest way is putting credentials in the URL, like https://user:pass@site.test, which works in many browsers. In Selenium 4 with Chromium you can register credentials through the HasAuthentication interface: ((HasAuthentication) driver).register(UsernameAndPassword.of("user", "pass")). Keep the credentials in environment variables or a secret store, never in code.
185

Tell me about a time a flaky test cost your team time and how you fixed it permanently.

Save to ▾
Show answer
Situation: a checkout test failed about one run in five and the team started ignoring red builds. Task: fix the root cause, not just rerun it. Action: I added logs and screenshots, found it raced with an async price recalculation, replaced a fixed sleep with a wait on the updated total and asked developers for a loading flag. Result: zero failures in the next sixty runs, and the team trusted red builds again.
186

Tell me about a time you reduced the run time of a test suite significantly.

Save to ▾
Show answer
Situation: our TestNG regression took three hours, so it only ran nightly. Task: get it under forty minutes to run on every merge. Action: I profiled slow tests, replaced UI login with an API token, made the driver ThreadLocal and enabled parallel classes, moved data setup to APIs and removed duplicate tests. Result: the suite ran in thirty-five minutes on four threads, and defects were caught on the same day they were introduced.
187

What are the standalone, hub and node, and distributed modes of Selenium Grid 4?

Save to ▾
Show answer
Standalone runs every Grid component and a local node in a single process, which suits a laptop or a single container. Hub and node mode runs the router, distributor, queue and session map together as the hub, with separate node processes registering to it, which is the usual team setup. Fully distributed mode runs each component separately, often on Kubernetes, for very large grids that need independent scaling and high availability.
188

Why do Selenium browser containers need a larger shm_size?

Save to ▾
Show answer
Chrome and Firefox use shared memory at /dev/shm for rendering and inter-process communication. Docker gives containers only 64 MB of shared memory by default, which is not enough for modern pages, so the browser tab crashes with errors like session deleted because of page crash. Setting shm_size to 2g in Compose, or --shm-size=2g with docker run, fixes it. Mounting /dev/shm from the host is an alternative.
189

What does SE_NODE_MAX_SESSIONS control in the Docker Selenium images?

Save to ▾
Show answer
It sets how many browser sessions a node container can run at once. The default is one, which gives the best isolation and stability. Increasing it lets one container run several browsers in parallel, but you must also set SE_NODE_OVERRIDE_MAX_SESSIONS to true and give the container enough CPU, memory and shared memory. Many teams keep one session per container and scale the number of containers instead.
190

How do you get reports, screenshots and downloaded files out of a Docker container?

Save to ▾
Show answer
Use volumes. A bind mount maps a host folder into the container, for example -v $(pwd)/target:/app/target, so reports written in the container appear on the CI agent for archiving. Named volumes are managed by Docker and suit data that should survive restarts. For browser downloads, mount the node's download folder or enable the Grid's managed downloads with the se:downloadsEnabled capability to fetch files through the Grid API.
191

Describe a time you convinced your team to run tests in Docker.

Save to ▾
Show answer
Situation: our tests behaved differently on each tester's laptop and on Jenkins because of browser and driver versions. Task: make results consistent. Action: I built a small demo with Docker Compose running the Grid and the app, showed identical results on three machines and on CI, and wrote a one-page setup guide. Result: the team adopted it within two sprints, works-on-my-machine failures almost disappeared and new joiners were productive on day one.
192

Write a docker-compose.yml that runs a Selenium hub with Chrome and Firefox nodes.

Save to ▾
Show answer
services: selenium-hub: image: selenium/hub:4.25.0 ports: - "4442:4442" - "4443:4443" - "4444:4444" chrome: image: selenium/node-chrome:4.25.0 shm_size: 2gb depends_on: - selenium-hub environment: - SE_EVENT_BUS_HOST=selenium-hub - SE_EVENT_BUS_PUBLISH_PORT=4442 - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 firefox: image: selenium/node-firefox:4.25.0 shm_size: 2gb depends_on: - selenium-hub environment: - SE_EVENT_BUS_HOST=selenium-hub - SE_EVENT_BUS_PUBLISH_PORT=4442 - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
193

Write a Dockerfile that runs a Maven and TestNG test suite.

Save to ▾
Show answer
FROM maven:3.9-eclipse-temurin-21 WORKDIR /app # cache dependencies first for faster rebuilds COPY pom.xml . RUN mvn -q dependency:go-offline COPY src ./src COPY testng.xml . ENV GRID_URL=http://selenium-hub:4444 CMD ["sh", "-c", "mvn test -Dgrid.url=$GRID_URL -Dsurefire.suiteXmlFiles=testng.xml"]
194

How do you record videos of tests running on a Docker Selenium Grid?

Save to ▾
Show answer
Add the selenium/video image as a sidecar container next to each node, sharing the node's display through DISPLAY_CONTAINER_NAME, and mount a folder for the mp4 files. Newer Grid versions also support recording per session by setting the se:recordVideo capability with Dynamic Grid. Name videos with se:name so they match test names. Keep videos only for failed tests or for a few days, because they use a lot of disk space.
195

Tests on the Grid fail with SessionNotCreatedException saying the new session request timed out. What do you check?

Save to ▾
Show answer
It means no matching free slot appeared in time. Check the Grid UI to see whether nodes are registered and whether their capabilities match the request, such as browser name, version or platform. Compare the test thread count with total slots, since extra threads just wait in the queue. Look for stuck sessions holding slots after aborted builds. Then increase capacity, reduce threads, or raise the session request timeout.
196

Chrome inside a Docker node keeps crashing with session deleted because of page crash. How do you fix it?

Save to ▾
Show answer
This is almost always shared memory exhaustion, because Docker's default /dev/shm of 64 MB is too small for Chrome. Set shm_size: 2gb in Compose or --shm-size=2g in docker run. Also check the container's memory limit and the number of sessions per node, since several browsers in one container multiply memory use. Heavy pages or memory leaks in long sessions can also crash tabs, so restart sessions between test classes.
197

File upload tests pass locally but fail when they run on a remote Grid. Why?

Save to ▾
Show answer
sendKeys with a file path sends a path that exists on your test machine, but the browser runs on the remote node where that path does not exist. Set a LocalFileDetector on the RemoteWebDriver, using ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector()), so Selenium zips and transfers the file to the node first. Alternatively mount the test data folder into the node container. Always use absolute paths.
198

After aborted Jenkins builds, Grid slots stay busy and new tests wait. How do you handle it?

Save to ▾
Show answer
When a build is killed, driver.quit() never runs, so sessions stay open until the node notices. Set a sensible session timeout on nodes, such as SE_NODE_SESSION_TIMEOUT of 300 seconds, so idle sessions are cleaned up. Always call quit in an @AfterMethod with alwaysRun or a finally block. In CI, bring the Compose Grid up per build and tear it down in a post always step, so each build gets a fresh Grid.
199

Tests running inside Docker cannot reach the application running on the host's localhost. Why, and how do you fix it?

Save to ▾
Show answer
Inside a container, localhost means the container itself, not the host machine. On Docker Desktop use host.docker.internal as the host name. On Linux add extra_hosts with host.docker.internal:host-gateway, or use the host's IP. A cleaner option is running the application in the same Compose network and calling it by its service name, such as http://web:8080. Make sure the app listens on 0.0.0.0, not only 127.0.0.1.
200

Tell me about a time you set up test infrastructure that other teams started using.

Save to ▾
Show answer
Situation: three product teams each kept their own unstable Grid VMs. Task: provide one reliable shared Grid. Action: I set up a Docker-based Grid with pinned images, health checks, video for failures and a short onboarding guide, then ran a pilot with one team and fixed their issues before opening it up. Result: all three teams moved within a quarter, VM costs dropped and Grid-related failures fell sharply.
201

Tell me about a time a BDD conversation clarified a requirement before development started.

Save to ▾
Show answer
Situation: a story said users get a refund if an order is cancelled early. Task: write scenarios with the product owner and developer. Action: while writing examples I asked what early meant and whether shipped orders counted. The three of us found the story had no time limit and no rule for partial shipments, and we wrote four concrete scenarios. Result: the rules were fixed before coding, avoiding a rework that had happened in a previous sprint.
202

What is the difference between git reset --soft, --mixed and --hard?

Save to ▾
Show answer
All three move the current branch to another commit, but treat your changes differently. Soft keeps the changes staged, which is useful to squash recent commits. Mixed, the default, keeps the changes in the working folder but unstages them. Hard throws away staged and working changes completely, so use it carefully. Never reset commits that are already pushed to a shared branch; use git revert there instead.
203

What is the Maven Failsafe plugin and how is it different from Surefire?

Save to ▾
Show answer
Surefire runs unit tests in the test phase and stops the build as soon as tests fail. Failsafe runs integration tests in the integration-test phase and checks results later in the verify phase, so post-integration-test steps, like stopping a server or Docker containers, still run after failures. By default Failsafe picks classes named *IT. Many teams run UI and API suites through Failsafe with mvn verify for that reason.
204

Describe a time you automated a manual build or release step for the QA team.

Save to ▾
Show answer
Situation: before each regression a tester spent an hour deploying the build to QA and seeding data by hand. Task: remove that manual step. Action: I wrote a Jenkins pipeline stage that deployed the build, ran database seed scripts and a smoke check, then triggered the regression job, and documented it for the team. Result: setup dropped to ten minutes without human effort, and regressions could run overnight automatically.
205

What is correlation in JMeter and why is it needed?

Save to ▾
Show answer
Correlation means capturing dynamic values from one response and passing them into later requests. Session ids, CSRF tokens, auth tokens and order ids change every run, so a recorded script with hard-coded values fails on replay. In JMeter you use post-processors such as JSON Extractor, Regular Expression Extractor or CSS Selector Extractor to save the value into a variable, then reference it as ${token} in later headers or bodies.
206

What is the difference between average, median and 95th percentile response time?

Save to ▾
Show answer
Average is the sum divided by count, so a few very slow requests can distort it. Median is the middle value, meaning half the requests were faster. The 95th percentile means 95 percent of requests were faster than that value, which reflects what most users experience including slow cases. SLAs are usually written on 90th, 95th or 99th percentiles because averages hide long tails that frustrate real users.
207

What are pre-processors and post-processors in JMeter?

Save to ▾
Show answer
Pre-processors run before a sampler, for example a JSR223 PreProcessor that builds a signature or timestamp, or User Parameters that set values per thread. Post-processors run after a sampler and usually extract data from the response, such as JSON Extractor, Regular Expression Extractor or Boundary Extractor, storing it as a variable for later requests. Their scope depends on where they sit in the tree, so place them as children of the right sampler.
208

Why is JSR223 with Groovy preferred over BeanShell in JMeter?

Save to ▾
Show answer
JSR223 elements with Groovy compile scripts once and cache them, so they run much faster and use less CPU under load. BeanShell is interpreted on every call and becomes a bottleneck at high thread counts. Groovy also supports modern Java syntax and is the default JSR223 language. Enable caching by keeping the cache compiled script option on and passing values through vars or parameters, not by embedding ${} inside the script.
209

What is the Transaction Controller in JMeter used for?

Save to ▾
Show answer
A Transaction Controller groups several samplers into one logical business transaction, such as Login, which may include loading the page, posting credentials and fetching the dashboard. JMeter reports an extra sample with the total time of the group, so reports show user-level timings instead of only individual requests. With generate parent sample enabled the children appear nested. It makes SLA reporting easier for business stakeholders.
210

During a load test response times rise sharply. Which server-side metrics do you check?

Save to ▾
Show answer
Check CPU and memory usage of application servers, garbage collection pauses and heap usage for Java services, thread pool and connection pool saturation, database slow queries, locks and connection counts, disk I/O and network bandwidth. Also look at load balancer and cache hit rates and error logs. Correlate the timestamp of the slowdown with these graphs in an APM or monitoring tool to find which resource saturated first.
211

How do you handle stakeholders who ask for performance testing only a few days before go-live?

Save to ▾
Show answer
Situation: a product team requested load testing three days before launch. Task: give useful results fast and set expectations. Action: I explained the risk, agreed on the two most critical journeys, reused API scripts and ran a short load and spike test, sharing results daily. I also proposed adding a performance stage to future sprints. Result: we found a missing database index before launch, and the next release included performance tests from the start.
212

How do you extract an auth token with JSON Extractor and use it in later JMeter requests?

Save to ▾
Show answer
Add a JSON Extractor as a child of the login sampler. Set the variable name to token, the JSON path expression to $.access_token, match number 1 and a default like TOKEN_NOT_FOUND so failures are visible. Then add an HTTP Header Manager at Thread Group level with Authorization set to Bearer ${token}. Each thread extracts and uses its own token, because JMeter variables are per thread.
213

How do you pass thread count and duration to a JMeter test from the command line?

Save to ▾
Show answer
// In the Thread Group fields use property functions with defaults Number of Threads: ${__P(users,10)} Ramp-up period: ${__P(rampup,30)} Duration (seconds): ${__P(duration,300)} // Then override them when running jmeter -n -t load.jmx -l out.jtl -Jusers=200 -Jrampup=120 -Jduration=1800
214

Your recorded JMeter script fails with 403 on every request after login. What is the likely cause?

Save to ▾
Show answer
The script is probably replaying hard-coded dynamic values, such as a CSRF token, session cookie or auth header captured during recording. The server rejects them because they belong to the old session. Add an HTTP Cookie Manager so cookies are handled per thread, extract the CSRF or bearer token from the login response with an extractor, and replace the recorded value with the variable. Verify with View Results Tree on one thread.
215

Tell me about a time a performance test found a serious issue before release.

Save to ▾
Show answer
Situation: a new search feature passed functional testing. Task: run a load test at expected peak traffic. Action: at 150 users the 95th percentile jumped from under one second to nine seconds. I correlated it with database metrics, found a full table scan caused by a missing index and shared the query and graphs with developers. Result: after the fix, response time stayed under 800 milliseconds at 400 users, and release went ahead on time.
216

How do you validate an XML response in REST Assured?

Save to ▾
Show answer
// REST Assured uses GPath for XML as well as JSON given() .accept(ContentType.XML) .when() .get("/orders/42") .then() .statusCode(200) .contentType(ContentType.XML) .body("order.@id", equalTo("42")) .body("order.items.item.size()", equalTo(3)) .body("order.status", equalTo("SHIPPED"));
217

Tell me about a time your API tests caught a breaking change before the UI tests did.

Save to ▾
Show answer
Situation: a backend team renamed a response field during a refactor. Task: our nightly REST Assured suite had to protect the mobile and web clients. Action: schema validation failed within minutes of the merge, and I shared the failing response and the contract with the developer. Result: the field was restored with a deprecation plan before the UI suite even ran, and the team added our schema tests to their pull request checks.
218

What is the LoadableComponent pattern in Selenium?

Save to ▾
Show answer
LoadableComponent is a Selenium support class that standardises how a page object ensures it is loaded. You extend it and implement load(), which navigates to the page, and isLoaded(), which throws an Error if the page is not ready. Calling get() checks isLoaded and calls load only if needed, then checks again. It gives a consistent, self-verifying way to open pages and fails fast with a clear message.
219

A login action can lead either to the dashboard or to an error message. How should the page object method return?

Save to ▾
Show answer
Make the outcome explicit with separate methods instead of one method guessing. For example loginAs(user) returns DashboardPage for valid credentials, while loginExpectingError(user) returns the same LoginPage so the test can check the error. Each method waits for its expected page and fails clearly if it does not appear. This keeps tests readable and avoids returning a generic Object or checking types in tests.
220

How do you test a responsive page in a mobile viewport using Selenium?

Save to ▾
Show answer
For layout checks you can set the window size, like driver.manage().window().setSize(new Dimension(390, 844)). For closer emulation in Chrome use mobile emulation in ChromeOptions: options.setExperimentalOption("mobileEmulation", Map.of("deviceName", "Pixel 7")), which also sets the user agent, pixel ratio and touch events. This catches responsive layout bugs quickly, but it is not a replacement for testing on real mobile browsers.
221

Tell me about a time you had to explain a technical test failure to a non-technical manager.

Save to ▾
Show answer
Situation: a release was blocked by failing tests and the manager wanted to know if it was safe to ship. Task: explain the risk without jargon. Action: I separated the failures into one real bug, where customers could be charged twice, and three environment issues. I showed the bug with a short screen recording. Result: the manager delayed the release by one day, the bug was fixed and the environment issues were assigned to DevOps.

Frequently asked questions

Who should practise medium Automation Testing questions?

Anyone with some hands-on practice: most real interview time is spent on medium questions like these.

How should I practise these?

Answer each question aloud before opening the answer, mark it as solved only when your answer matches the key idea, and save misses to Last-Minute Revision.

Other difficulty levels