🔥 Live 2,847 QA engineers learning right now — Start Free Automation Roadmap →

SDET Interview Rounds by Company (2026)

Round-by-round interview process, real sample questions with answers, and prep tips for 15 top companies hiring SDET and QA engineers.

📦

Amazon Interview Process

FAANG · E-Commerce · AWS · Seattle USA · 5–6 Rounds

📋 OA → Technical 1 → Technical 2 → System Design → Bar Raiser🎯 SDET I / II / III📍 Bangalore · Hyderabad · Remote

💻 Online Assessment (OA)

90-minute HackerTest with 2 coding problems (Medium) + Work Simulation. Focus: Arrays, Strings, HashMap, Sliding Window, BFS/DFS. Amazon's OA bar for SDET is slightly lower than SDE but still needs clean working code with edge cases.

Q1 Find the longest substring without repeating characters. Return its length.
Medium · Sliding Window · Amazon OA 2024
Use Sliding Window + HashMap. Maintain a window [left, right] and a map storing the last seen index of each character. When you see a repeated character, move left pointer past its last occurrence.
public int lengthOfLongestSubstring(String s) {
    Map<Character,Integer> map = new HashMap<>();
    int maxLen = 0, left = 0;
    for (int right = 0; right < s.length(); right++) {
        char c = s.charAt(right);
        if (map.containsKey(c))
            left = Math.max(left, map.get(c) + 1);
        map.put(c, right);
        maxLen = Math.max(maxLen, right - left + 1);
    }
    return maxLen;
}
// "abcabcbb"→3  "bbbbb"→1  ""→0  "pwwkew"→3
💡 Always state edge cases BEFORE coding: empty string, single char, all unique, all same. Amazon interviewers specifically note whether you proactively cover these.
Q2 Given an array of integers, return indices of two numbers that add up to a target value.
Easy · HashMap · Amazon OA 2023-24
Use a HashMap storing value→index. For each element, check if target - nums[i] already exists in the map. O(n) time, O(n) space.
public int[] twoSum(int[] nums, int target) {
    Map<Integer,Integer> seen = new HashMap<>();
    for (int i = 0; i < nums.length; i++) {
        int complement = target - nums[i];
        if (seen.containsKey(complement))
            return new int[]{seen.get(complement), i};
        seen.put(nums[i], i);
    }
    return new int[]{};
}
// [2,7,11,15] target=9 → [0,1]  [3,3] target=6 → [0,1]
💡 Brute force O(n²) will work for small inputs but mention the O(n) HashMap solution proactively — shows you think about efficiency.
Q3 Given a sorted rotated array, find the index of a target element. Return -1 if not found.
Medium · Binary Search · Amazon OA 2024
Modified binary search. At every mid, one half is always sorted. Check which half is sorted and whether target lies in it. Recurse accordingly.
public int search(int[] nums, int target) {
    int lo = 0, hi = nums.length - 1;
    while (lo <= hi) {
        int mid = lo + (hi - lo) / 2;
        if (nums[mid] == target) return mid;
        if (nums[lo] <= nums[mid]) {       // left half sorted
            if (target >= nums[lo] && target < nums[mid])
                hi = mid - 1;
            else lo = mid + 1;
        } else {                           // right half sorted
            if (target > nums[mid] && target <= nums[hi])
                lo = mid + 1;
            else hi = mid - 1;
        }
    }
    return -1;
}
// [4,5,6,7,0,1,2] target=0 → 4  target=3 → -1
💡 Draw the rotation on paper before coding. Identify: "which half is sorted?" is the key insight.
Q4 Implement a stack that supports push, pop, top, and getMin() in O(1) time for all operations.
Medium · Stack · Amazon OA 2023
Use two stacks — main stack and min stack. Min stack always holds the current minimum. On every push, push the new minimum (min of current element and current min) onto the min stack.
class MinStack {
    private Deque<Integer> stack = new ArrayDeque<>();
    private Deque<Integer> minStack = new ArrayDeque<>();

    public void push(int val) {
        stack.push(val);
        int newMin = minStack.isEmpty() ? val : Math.min(val, minStack.peek());
        minStack.push(newMin);
    }
    public void pop() { stack.pop(); minStack.pop(); }
    public int top()  { return stack.peek(); }
    public int getMin(){ return minStack.peek(); }
}
💡 Amazon loves this problem because it tests "can you use extra space creatively?" The min-stack approach is O(n) space but O(1) time — always a valid trade-off in interviews.
Q5 Given an array of strings, group all anagrams together and return list of groups.
Medium · HashMap + Array · Amazon OA 2024
Use sorted string as HashMap key. Two words are anagrams iff their sorted versions are equal.
public List<List<String>> groupAnagrams(String[] strs) {
    Map<String, List<String>> map = new HashMap<>();
    for (String s : strs) {
        char[] c = s.toCharArray();
        Arrays.sort(c);
        String key = new String(c);
        map.computeIfAbsent(key, k -> new ArrayList<>()).add(s);
    }
    return new ArrayList<>(map.values());
}
// ["eat","tea","tan","ate","nat","bat"]
// → [["eat","tea","ate"],["tan","nat"],["bat"]]
💡 Alternative key: character frequency array as string — avoids sorting but same concept. Mention both approaches.
Q6 Check if a string is a palindrome (ignoring non-alphanumeric characters and case).
Easy · String Manipulation · Amazon NQT
Use two pointers from both ends. Skip non-alphanumeric characters. Compare lowercased characters.
public boolean isPalindrome(String s) {
    int lo = 0, hi = s.length() - 1;
    while (lo < hi) {
        while (lo < hi && !Character.isLetterOrDigit(s.charAt(lo))) lo++;
        while (lo < hi && !Character.isLetterOrDigit(s.charAt(hi))) hi--;
        if (Character.toLowerCase(s.charAt(lo)) !=
            Character.toLowerCase(s.charAt(hi))) return false;
        lo++; hi--;
    }
    return true;
}
// "A man, a plan, a canal: Panama" → true
// "race a car" → false
💡 Edge cases: empty string is a palindrome, single character is a palindrome, all spaces/punctuation is a palindrome.
Q7 Given a binary tree, return the level-order traversal as a list of lists.
Medium · Queue / BFS · Amazon OA
Use a Queue (BFS). Process nodes level by level. At each level, record the queue size first, then process exactly that many nodes.
public List<List<Integer>> levelOrder(TreeNode root) {
    List<List<Integer>> result = new ArrayList<>();
    if (root == null) return result;
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    while (!queue.isEmpty()) {
        int size = queue.size();          // capture level size!
        List<Integer> level = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            TreeNode node = queue.poll();
            level.add(node.val);
            if (node.left  != null) queue.offer(node.left);
            if (node.right != null) queue.offer(node.right);
        }
        result.add(level);
    }
    return result;
}
💡 The "capture size before loop" pattern is reused in many BFS problems. Once you internalize it, all level-order variants become easy.
Q8 Generate all valid combinations of N pairs of parentheses.
Medium · Recursion / Backtracking · Amazon OA 2023
Backtracking: track open and close counts. Add "(" if open < n. Add ")" if close < open.
public List<String> generateParenthesis(int n) {
    List<String> result = new ArrayList<>();
    backtrack(result, new StringBuilder(), 0, 0, n);
    return result;
}
private void backtrack(List<String> res, StringBuilder cur,
                        int open, int close, int n) {
    if (cur.length() == 2 * n) { res.add(cur.toString()); return; }
    if (open < n) {
        cur.append("(");
        backtrack(res, cur, open + 1, close, n);
        cur.deleteCharAt(cur.length() - 1);
    }
    if (close < open) {
        cur.append(")");
        backtrack(res, cur, open, close + 1, n);
        cur.deleteCharAt(cur.length() - 1);
    }
}
// n=3 → ["((()))","(()())","(())()","()(())","()()()"]
💡 Amazon SDET interviews often ask: "Now write unit tests for this function." Have 5 test cases ready: n=0, n=1, n=2, n=3, large n.
Q9 Given a list of test execution times, find the maximum sum of non-adjacent times (you cannot pick two consecutive tests).
Medium · Dynamic Programming · Amazon OA
House Robber DP. At each index, choose max of: include current + best_two_back, or skip and take best_one_back.
public int rob(int[] nums) {
    if (nums.length == 0) return 0;
    if (nums.length == 1) return nums[0];
    int prev2 = 0, prev1 = 0;
    for (int n : nums) {
        int curr = Math.max(prev1, prev2 + n);
        prev2 = prev1;
        prev1 = curr;
    }
    return prev1;
}
// [2,7,9,3,1] → 12  (2+9+1)
// [1,2,3,1]   → 4   (1+3)
💡 Optimized from O(n) space to O(1) space by only keeping prev1 and prev2. Always mention this optimization.
Q10 Given an m×n matrix of 0s and 1s, find the number of islands (connected 1s).
Hard · Matrix / BFS · Amazon OA 2024
DFS/BFS flood fill. For each unvisited "1", increment count and mark all connected 1s as visited (set to 0 or use visited array).
public int numIslands(char[][] grid) {
    int count = 0;
    for (int i = 0; i < grid.length; i++)
        for (int j = 0; j < grid[0].length; j++)
            if (grid[i][j] == "1") { dfs(grid,i,j); count++; }
    return count;
}
private void dfs(char[][] g, int i, int j) {
    if (i<0||i>=g.length||j<0||j>=g[0].length||g[i][j]!="1") return;
    g[i][j] = "0";           // mark visited
    dfs(g,i+1,j); dfs(g,i-1,j); dfs(g,i,j+1); dfs(g,i,j-1);
}
// [["1","1","0"],["1","1","0"],["0","0","1"]] → 2
💡 "Flood fill" is a family of problems. Once you master this pattern, "Max Area of Island", "Surrounded Regions", and "Pacific Atlantic Waterflow" all follow the same structure.

🔬 Technical Round 1

Deep dive into Selenium internals, Java OOP, TestNG, and framework architecture. The interviewer will ask you to write live code. Amazon values "working backwards" — always explain WHY you chose each design before HOW.

Q1 Design a Page Object Model framework for Amazon checkout from scratch. Walk through the complete architecture.
Hard · POM Framework · Amazon SDET Tech Round
Layer 1 - Base: BasePage with ThreadLocal WebDriver, WebDriverWait, PageFactory.initElements. Layer 2 - Pages: One class per page (HomePage, CartPage, CheckoutPage) extending BasePage. Each method returns the next page object (fluent). Layer 3 - Tests: BaseTest with @BeforeMethod setup, @AfterMethod teardown. Test classes extend BaseTest. Config: config.properties for URL, browser, timeouts. Rule: No assertions in page classes — only in test classes.
// BasePage.java
public class BasePage {
    protected WebDriver driver;
    protected WebDriverWait wait;
    public BasePage(WebDriver driver) {
        this.driver = driver;
        this.wait   = new WebDriverWait(driver, Duration.ofSeconds(15));
        PageFactory.initElements(driver, this);
    }
    protected void click(By by) {
        wait.until(ExpectedConditions.elementToBeClickable(by)).click();
    }
    protected void type(By by, String text) {
        WebElement el = wait.until(ExpectedConditions.visibilityOfElementLocated(by));
        el.clear(); el.sendKeys(text);
    }
}

// CheckoutPage.java
public class CheckoutPage extends BasePage {
    @FindBy(id="placeYourOrder") private WebElement placeOrderBtn;
    public CheckoutPage(WebDriver d) { super(d); }
    public OrderConfirmPage placeOrder() {
        placeOrderBtn.click();
        return new OrderConfirmPage(driver);
    }
}

// BaseTest.java
public class BaseTest {
    @BeforeMethod @Parameters("browser")
    public void setUp(@Optional("chrome") String browser) {
        DriverFactory.initDriver(browser);
    }
    @AfterMethod(alwaysRun=true)
    public void tearDown() { DriverFactory.quitDriver(); }
}
💡 Mention: ThreadLocal for parallel execution, never store WebElements as instance fields (stale risk), and config.properties to avoid hardcoding.
Q2 How do you identify and fix flaky tests in a large Selenium suite? Give a real example.
Medium · Flaky Tests · Amazon SDET Round 2024
Identify: Implement IRetryAnalyzer in TestNG. Log every failure with timestamp, thread, screenshot, environment. Any test with 5–40% intermittent failure rate is flaky. Root Causes: (1) Timing — replace Thread.sleep with WebDriverWait. (2) Stale elements — re-locate in method, not field. (3) Test data collision — unique data per thread. (4) Test order dependency — make each test self-contained. (5) Environment instability — add retry + health check. Policy: Fix >5% rate immediately, quarantine 1–5%, delete tests quarantined >2 sprints.
// RetryAnalyzer.java
public class RetryAnalyzer implements IRetryAnalyzer {
    private int count = 0;
    private static final int MAX = 2;  // retry up to 2 times
    @Override
    public boolean retry(ITestResult result) {
        if (count < MAX) { count++; return true; }
        return false;
    }
}

// Usage in test method
@Test(retryAnalyzer = RetryAnalyzer.class)
public void checkoutFlowTest() { ... }

// Or apply globally via TestNG listener
public class RetryListener implements IAnnotationTransformer {
    @Override
    public void transform(ITestAnnotation annotation, ...) {
        annotation.setRetryAnalyzer(RetryAnalyzer.class);
    }
}
💡 "In my last role I reduced flaky test rate from 18% to 2.3% in 6 weeks by implementing explicit waits and ThreadLocal driver management." Always give a quantified result.
Q3 Explain implicit, explicit and fluent wait. Which should you use and when?
Medium · Selenium Waits · Amazon Tech Screen
Implicit Wait: Global polling for every findElement call. Simple but dangerous when mixed with explicit waits — can cause up to 2× timeout. Explicit Wait: Waits for a specific condition on a specific element. Best practice for most cases. Fluent Wait: Explicit wait with configurable polling interval + exception ignoring. Use for elements that appear/disappear intermittently. Rule: Never mix implicit + explicit waits.
// Explicit Wait - recommended
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(15));
WebElement el = wait.until(
    ExpectedConditions.visibilityOfElementLocated(By.id("toast")));

// Fluent Wait - for intermittent elements
Wait<WebDriver> fluent = new FluentWait<>(driver)
    .withTimeout(Duration.ofSeconds(20))
    .pollingEvery(Duration.ofMillis(500))
    .ignoring(NoSuchElementException.class)
    .ignoring(StaleElementReferenceException.class);
WebElement btn = fluent.until(d -> d.findElement(By.id("submit")));

// Custom condition
wait.until(d -> d.findElement(By.id("count"))
               .getText().equals("10"));
💡 Never mix implicit + explicit waits — a common pitfall. If implicit is 10s and explicit is 5s, actual wait can be 15s. Use explicit-only strategy.
Q4 How do you implement thread-safe parallel Selenium execution in TestNG with 5 browsers simultaneously?
Hard · Parallel Execution · Amazon SDET 2023
Use ThreadLocal<WebDriver> in DriverFactory. Each thread gets its own WebDriver instance. testng.xml sets parallel="methods" thread-count="5". Most critical: always call driverPool.remove() in teardown to prevent memory leaks.
public class DriverFactory {
    private static final ThreadLocal<WebDriver> pool = new ThreadLocal<>();

    public static WebDriver getDriver() { return pool.get(); }

    public static void initDriver(String browser) {
        WebDriver d = switch(browser.toLowerCase()) {
            case "firefox" -> new FirefoxDriver();
            case "edge"    -> new EdgeDriver();
            default -> {
                ChromeOptions o = new ChromeOptions();
                o.addArguments("--headless=new","--no-sandbox");
                yield new ChromeDriver(o);
            }
        };
        d.manage().window().maximize();
        pool.set(d);
    }

    public static void quitDriver() {
        if (pool.get() != null) {
            pool.get().quit();
            pool.remove();  // CRITICAL: prevents memory leak
        }
    }
}
// testng.xml: <suite parallel="methods" thread-count="5">
💡 Forgetting pool.remove() is a very common bug causing memory leak in long-running CI pipelines. Flipkart/Amazon interviewers specifically check for this.
Q5 How do you implement data-driven testing with TestNG DataProvider? Show reading from Excel.
Medium · TestNG DataProvider · Amazon QA Interview
Use @DataProvider for in-code data or read from Excel via Apache POI. DataProvider returns Object[][] — each row becomes a separate test run.
// Simple DataProvider
@DataProvider(name = "loginData")
public Object[][] loginDataProvider() {
    return new Object[][] {
        {"admin@test.com", "Pass123", true},
        {"wrong@test.com", "wrongPass", false},
        {"",               "pass",    false},
        {"admin@test.com", "",        false},
    };
}
@Test(dataProvider = "loginData")
public void loginTest(String email, String pwd, boolean expected) {
    boolean result = loginPage.login(email, pwd);
    Assert.assertEquals(result, expected);
}

// Excel-driven (Apache POI)
@DataProvider(name = "excelData")
public Object[][] fromExcel() throws Exception {
    FileInputStream fis = new FileInputStream("testdata.xlsx");
    XSSFWorkbook wb = new XSSFWorkbook(fis);
    XSSFSheet sheet = wb.getSheetAt(0);
    int rows = sheet.getLastRowNum() + 1;
    Object[][] data = new Object[rows - 1][2];
    for (int i = 1; i < rows; i++) {
        XSSFRow row = sheet.getRow(i);
        data[i-1][0] = row.getCell(0).getStringCellValue();
        data[i-1][1] = row.getCell(1).getStringCellValue();
    }
    wb.close();
    return data;
}
💡 Data-driven tests should be independent — each row must set up and tear down its own state. Never share mutable state between DataProvider runs.
Q6 How do you capture screenshots on test failure and attach them to Allure reports?
Medium · Screenshot / Reporting · Amazon Tech Round
Implement ITestListener for automatic screenshots on failure. Attach to Allure using @Attachment annotation.
public class TestListener implements ITestListener {
    @Override
    public void onTestFailure(ITestResult result) {
        captureScreenshot(result.getName());
    }

    @Attachment(value = "Failure Screenshot", type = "image/png")
    private byte[] captureScreenshot(String testName) {
        return ((TakesScreenshot) DriverFactory.getDriver())
                   .getScreenshotAs(OutputType.BYTES);
    }
}

// In Allure - attach in test itself
@Attachment(value = "Page Screenshot", type = "image/png")
public static byte[] takeScreenshot() {
    return ((TakesScreenshot) DriverFactory.getDriver())
               .getScreenshotAs(OutputType.BYTES);
}

// testng.xml
// <listener class-name="com.pkg.TestListener"/>
💡 Allure reports also support video recording with allure-video-recorder plugin. Mention this for bonus points — shows awareness of production-grade reporting.
Q7 Your Selenium suite has 2000 tests running in 4 hours. How do you reduce it to under 30 minutes?
Hard · Framework Design · Amazon Senior SDET
Strategy 1 - Parallel Execution: Set TestNG thread-count=20, use ThreadLocal driver, run on Selenium Grid with 20 browser nodes → ~12x speedup. Strategy 2 - Test categorization: Tag tests @smoke, @regression, @slow. Run smoke on every PR (5 min), regression nightly. Strategy 3 - API + UI split: Replace UI setup steps with API calls. Login via API instead of Selenium → saves 15-30s per test. Strategy 4 - Headless browsers: 30% faster than headed. Strategy 5 - Remove redundancy: Audit 2000 tests — typically 20-30% are duplicates or cover the same path.
// API-based login for faster test setup
@BeforeMethod
public void setUp() {
    // Instead of Selenium login (15-20s):
    String token = ApiClient.post("/auth/login",
        Map.of("email","test@co.com","pwd","pass")).path("token");
    // Inject cookie into browser - instant!
    DriverFactory.initDriver("chrome");
    driver.get(BASE_URL);  // navigate first
    driver.manage().addCookie(
        new Cookie("session", token, "/"));
    driver.navigate().refresh();
}
💡 Real-world answer: at Amazon scale they use "API setup + UI verification" pattern. UI tests only verify UI, not business logic. All business logic is covered at API level.
Q8 Design a Jenkins pipeline that runs smoke tests on every PR and full regression nightly.
Medium · CI/CD Integration · Amazon DevOps Round
Two pipelines: PR Pipeline (triggered on every PR) runs smoke suite in 5 minutes. Nightly Pipeline (cron: 0 2 * * *) runs full regression with parallel browsers.
// Jenkinsfile - PR Pipeline
pipeline {
    agent any
    triggers { githubPush() }
    stages {
        stage("Smoke Tests") {
            steps {
                sh "mvn test -Dgroups=smoke -Dbrowser=chrome -Denv=staging -q"
            }
            post {
                always { junit "target/surefire-reports/*.xml" }
                failure { slackSend "#qa-alerts", "PR SMOKE FAILED: ${env.BUILD_URL}" }
            }
        }
    }
}

// Nightly Pipeline
pipeline {
    agent any
    triggers { cron("0 2 * * *") }
    stages {
        stage("Regression - Parallel") {
            parallel {
                stage("Chrome")  { steps { sh "mvn test -Dbrowser=chrome  -Dgroups=regression" } }
                stage("Firefox") { steps { sh "mvn test -Dbrowser=firefox -Dgroups=regression" } }
                stage("Edge")    { steps { sh "mvn test -Dbrowser=edge    -Dgroups=regression" } }
            }
        }
        stage("Allure Report") {
            steps { allure results: [[path: "target/allure-results"]] }
        }
    }
}
💡 Amazon expects you to own your pipeline. Saying "DevOps handles that" is a red flag. Show you can write Jenkinsfile from scratch.
Q9 Write a REST Assured test to: POST an order, extract the order ID, GET the order, and verify the details match.
Hard · REST Assured · Amazon API Testing Round
This tests API chaining — the most common real-world API test pattern. Extract orderId from POST response and use in GET request.
@Test
public void createAndVerifyOrder() {
    // Step 1: Create order
    String orderId = given()
        .baseUri(BASE_URL)
        .header("Authorization", "Bearer " + getToken())
        .header("Idempotency-Key", UUID.randomUUID().toString()) // prevent duplicates
        .contentType(ContentType.JSON)
        .body("{ \"productId\": \"B01N5IB20Q\", \"qty\": 2 }")
    .when()
        .post("/orders")
    .then()
        .statusCode(201)
        .body("status", equalTo("CREATED"))
        .time(lessThan(2000L))   // SLA assertion
        .extract().path("orderId");

    // Step 2: Verify GET returns same details
    given()
        .baseUri(BASE_URL)
        .header("Authorization", "Bearer " + getToken())
        .pathParam("id", orderId)
    .when()
        .get("/orders/{id}")
    .then()
        .statusCode(200)
        .body("orderId",   equalTo(orderId))
        .body("status",    equalTo("CREATED"))
        .body("productId", equalTo("B01N5IB20Q"))
        .body("qty",       equalTo(2));
}
💡 Always add .time(lessThan(Xms)) to API tests — it validates SLAs automatically. Amazon production APIs have strict latency requirements.
Q10 How do you design a test data management strategy for a team of 10 SDETs running 500 tests in parallel?
Hard · Test Architecture · Amazon System Design
Problem: Tests in parallel cannot share test data — they will interfere with each other. Solution: Data isolation per test. Strategy 1: Each test creates its own data via API in @BeforeMethod and deletes it in @AfterMethod. Strategy 2: Test data pool — pre-create 500 accounts, each test claims one using a thread-safe queue. Strategy 3: Database snapshots — restore per-test using TestContainers. Strategy 4: Data scoping — use unique identifiers (UUID) per test run to namespace all created data.
// Thread-safe test data pool
public class TestDataPool {
    private static final ConcurrentLinkedQueue<TestUser> pool = new ConcurrentLinkedQueue<>();

    static {
        // Pre-load 500 test users at suite start
        for (int i = 0; i < 500; i++) {
            pool.offer(new TestUser("user"+i+"@test.com", "Pass"+i));
        }
    }

    public static TestUser borrow() { return pool.poll(); }
    public static void release(TestUser u) { pool.offer(u); }
}

// In test
public class CheckoutTest extends BaseTest {
    private TestUser user;

    @BeforeMethod
    public void setUp() {
        user = TestDataPool.borrow();  // get exclusive user
    }

    @AfterMethod
    public void tearDown() {
        TestDataPool.release(user);    // return to pool
        DriverFactory.quitDriver();
    }
}
💡 This is a system design thinking question. Show you understand concurrency risks in parallel testing. The pool approach is Amazon-scale thinking.

🔌 Technical Round 2 — API & CI/CD

Focus on REST API testing, REST Assured, Postman, Jenkins pipelines, and Docker. Expect live coding of API test scenarios. Amazon SDETs own their test pipelines — show you can build and maintain them end-to-end.

Q1 Test the complete order lifecycle: Create order → Add item → Checkout → Verify status using REST Assured.
Hard · API Chaining · Amazon API Round
Chain multiple API calls, passing responses between steps. Use RequestSpecification builder to avoid repetition.
public class OrderLifecycleTest {
    private RequestSpecification spec;
    private String orderId, cartId;

    @BeforeClass
    public void setup() {
        spec = new RequestSpecBuilder()
            .setBaseUri(BASE_URL)
            .addHeader("Authorization", "Bearer " + getToken())
            .setContentType(ContentType.JSON)
            .log(LogDetail.BODY).build();
    }

    @Test(priority=1)
    public void createOrder() {
        orderId = given(spec)
            .body("{\"customerId\":\"C001\"}")
        .when().post("/orders")
        .then().statusCode(201)
        .extract().path("orderId");
    }

    @Test(priority=2, dependsOnMethods="createOrder")
    public void addItem() {
        given(spec)
            .pathParam("id", orderId)
            .body("{\"productId\":\"P001\",\"qty\":3}")
        .when().post("/orders/{id}/items")
        .then().statusCode(200)
              .body("itemCount", equalTo(1));
    }

    @Test(priority=3, dependsOnMethods="addItem")
    public void checkout() {
        given(spec).pathParam("id", orderId)
        .when().post("/orders/{id}/checkout")
        .then().statusCode(200)
              .body("status", equalTo("CONFIRMED"));
    }
}
💡 Use dependsOnMethods only when test order genuinely matters (like lifecycle tests). Avoid in regression suites — creates brittle dependencies.
Q2 How do you validate that an API response matches an expected JSON schema?
Medium · Schema Validation · Amazon QA Interview
Use JSON Schema Validator with REST Assured. Define the expected schema (types, required fields, constraints) in a JSON file and assert the response matches it.
// schema: src/test/resources/schemas/order-schema.json
// {
//   "type": "object",
//   "required": ["orderId","status","total"],
//   "properties": {
//     "orderId": {"type":"string"},
//     "status":  {"type":"string","enum":["CREATED","CONFIRMED","SHIPPED"]},
//     "total":   {"type":"number","minimum":0}
//   }
// }

@Test
public void validateOrderSchema() {
    given()
        .baseUri(BASE_URL)
        .header("Authorization", "Bearer " + getToken())
    .when()
        .get("/orders/ORD-001")
    .then()
        .statusCode(200)
        .body(matchesJsonSchemaInClasspath("schemas/order-schema.json"));
}

// pom.xml dependency:
// <dependency>
//   <groupId>io.rest-assured</groupId>
//   <artifactId>json-schema-validator</artifactId>
// </dependency>
💡 Schema validation catches contract breaks between services. This is "contract testing" at a basic level. Mention Pact as the advanced version for microservices.
Q3 How do you handle OAuth 2.0 Bearer token authentication and token refresh in REST Assured tests?
Hard · Authentication · Amazon Security Round
Create a TokenManager class that fetches token once, caches it, and refreshes when expired. Use RequestSpecification to inject token in all requests.
public class TokenManager {
    private static String token;
    private static long tokenExpiry = 0;

    public static synchronized String getToken() {
        if (System.currentTimeMillis() > tokenExpiry) {
            Response res = given()
                .formParam("grant_type",    "client_credentials")
                .formParam("client_id",     Config.get("client.id"))
                .formParam("client_secret", Config.get("client.secret"))
                .post(AUTH_URL + "/token");

            token       = res.path("access_token");
            int expiresIn = res.path("expires_in");
            tokenExpiry = System.currentTimeMillis() + (expiresIn - 60) * 1000L;
        }
        return token;
    }
}

// Usage in test
@Test
public void protectedEndpoint() {
    given()
        .header("Authorization", "Bearer " + TokenManager.getToken())
    .when()
        .get("/protected/resource")
    .then()
        .statusCode(200);
}
💡 The 60-second buffer (expiresIn - 60) prevents failures when token expires mid-test. Always build in a safety margin.
Q4 Write comprehensive negative test cases for a payment API POST /payments endpoint.
Medium · Negative Testing · Amazon API Round
Cover all validation failure scenarios. Group by: missing fields, invalid values, boundary values, auth failures, duplicate requests.
@DataProvider(name = "negativePayments")
public Object[][] negativePaymentData() {
    return new Object[][] {
        // body, expectedStatus, expectedError
        {"{}", 400, "amount is required"},
        {"{\"amount\":0, \"currency\":\"INR\", \"vpa\":\"a@upi\"}", 400, "amount must be positive"},
        {"{\"amount\":-100, \"currency\":\"INR\", \"vpa\":\"a@upi\"}", 400, "amount must be positive"},
        {"{\"amount\":200001, \"currency\":\"INR\", \"vpa\":\"a@upi\"}", 422, "exceeds daily limit"},
        {"{\"amount\":100, \"currency\":\"XYZ\", \"vpa\":\"a@upi\"}", 400, "unsupported currency"},
        {"{\"amount\":100, \"currency\":\"INR\", \"vpa\":\"invalid-vpa\"}", 400, "invalid VPA format"},
    };
}

@Test(dataProvider = "negativePayments")
public void negativePaymentTest(String body, int status, String errorMsg) {
    given()
        .header("Authorization", "Bearer " + getToken())
        .contentType(ContentType.JSON)
        .body(body)
    .when()
        .post("/payments")
    .then()
        .statusCode(status)
        .body("error.message", containsString(errorMsg));
}
💡 Negative testing is 40% of a good API test suite. Amazon specifically asks: "What happens when the API receives unexpected input?" Show you think beyond happy paths.
Q5 How do you add performance assertions to your API tests to enforce SLA requirements?
Medium · Performance SLA · Amazon Perf Round
REST Assured supports .time(lessThan(Xms)) for response time assertions. Combine with custom reporting for SLA trend monitoring.
@Test
public void checkoutAPI_ShouldRespondWithin1Second() {
    long startTime = System.currentTimeMillis();

    given()
        .baseUri(BASE_URL)
        .header("Authorization", "Bearer " + getToken())
        .contentType(ContentType.JSON)
        .body("{\"cartId\":\"C001\",\"paymentMethod\":\"UPI\"}")
    .when()
        .post("/checkout")
    .then()
        .statusCode(200)
        .time(lessThan(1000L))  // SLA: must respond within 1 second
        .body("status", equalTo("SUCCESS"));

    // Log for SLA trend dashboard
    long duration = System.currentTimeMillis() - startTime;
    SlaReporter.record("POST /checkout", duration, 1000);
    System.out.println("Checkout API: " + duration + "ms");
}

// Critical API SLAs (typical Amazon):
// GET /products   < 200ms
// POST /cart      < 300ms
// POST /checkout  < 1000ms
// POST /payments  < 3000ms (payment gateway latency)
💡 SLA testing in functional tests catches regressions early. A PR that makes checkout 50% slower should fail the CI gate — not just the load test.
Q6 How do you test that a payment API is idempotent — the same request processed twice should not double-charge?
Hard · Idempotency Testing · Amazon Payment Systems
Send the same idempotency key twice. First request creates payment (201). Second request with same key returns same result (200 with idem flag) without creating new payment.
@Test
public void paymentIdempotency_SameKey_NoDoubleCharge() {
    String idempotencyKey = "test-idem-" + UUID.randomUUID();
    String body = "{\"amount\":500,\"currency\":\"INR\",\"vpa\":\"test@upi\"}";

    // First call - creates payment
    String paymentId1 = given()
        .header("Idempotency-Key", idempotencyKey)
        .header("Authorization", "Bearer " + getToken())
        .contentType(ContentType.JSON).body(body)
    .when().post("/payments")
    .then().statusCode(201)
    .extract().path("paymentId");

    // Second call - same key, must NOT create new payment
    Response second = given()
        .header("Idempotency-Key", idempotencyKey)
        .header("Authorization", "Bearer " + getToken())
        .contentType(ContentType.JSON).body(body)
    .when().post("/payments")
    .then()
        .statusCode(anyOf(equalTo(200), equalTo(201)))
        .body("idempotent", equalTo(true))
        .extract().response();

    String paymentId2 = second.path("paymentId");
    Assert.assertEquals(paymentId1, paymentId2,
        "Same idempotency key should return same paymentId");
}
💡 This is Amazon's #1 payment testing question. Every payment system must be idempotent. Know the RFC 7231 standard for idempotent HTTP methods.
Q7 How do you test that a webhook is delivered correctly when an order status changes?
Medium · Webhook Testing · Amazon Integration Test
Use WireMock to create a local HTTP server that records webhook deliveries. Trigger the event, then assert WireMock received the correct webhook payload.
// WireMock webhook test
@Test
public void orderWebhook_StatusChange_ShouldFire() {
    // Start local mock server
    WireMockServer mock = new WireMockServer(8099);
    mock.start();

    // Register webhook listener in system
    given().baseUri(BASE_URL)
        .body("{\"url\":\"http://localhost:8099/webhook\",\"events\":[\"order.shipped\"]}")
        .post("/webhooks/register");

    // Configure WireMock to capture the call
    mock.stubFor(post(urlEqualTo("/webhook")).willReturn(ok()));

    // Trigger order status change
    given().baseUri(BASE_URL)
        .body("{\"status\":\"SHIPPED\"}")
        .patch("/orders/ORD-001/status");

    // Wait and verify webhook received
    await().atMost(10, SECONDS).untilAsserted(() -> {
        mock.verify(1, postRequestedFor(urlEqualTo("/webhook"))
            .withRequestBody(containing("\"event\":\"order.shipped\""))
            .withRequestBody(containing("\"orderId\":\"ORD-001\"")));
    });
    mock.stop();
}
💡 Use Awaitility library for async assertions — never Thread.sleep() for webhook tests. The await().atMost() pattern handles timing without brittleness.
Q8 How do you compare API performance between two releases to detect regressions?
Medium · Response Time Comparison · Amazon Perf Analysis
Build a baseline comparison framework. Store p95 response times per endpoint from the previous release. Alert if current run exceeds baseline by >10%.
public class PerformanceBaseline {
    private static final Map<String, Long> baseline = Map.of(
        "GET /products",    180L,
        "POST /cart",       250L,
        "POST /checkout",   800L
    );

    public static void assertNoRegression(String endpoint, long actualMs) {
        Long baselineMs = baseline.get(endpoint);
        if (baselineMs != null) {
            long threshold = (long)(baselineMs * 1.10); // 10% regression allowed
            Assert.assertTrue(actualMs <= threshold,
                String.format("%s regressed: was %dms, now %dms (limit: %dms)",
                    endpoint, baselineMs, actualMs, threshold));
        }
    }
}

// In test:
@Test
public void productSearch_ShouldNotRegress() {
    long start = System.nanoTime();
    given().baseUri(BASE_URL).get("/products?q=laptop").then().statusCode(200);
    long durationMs = (System.nanoTime() - start) / 1_000_000;

    PerformanceBaseline.assertNoRegression("GET /products", durationMs);
}
💡 Run baseline comparison tests in your PR pipeline. A 15% latency regression is often as critical as a functional bug but gets caught much later without this.
Q9 What is Pact contract testing and how do you implement it between a consumer and provider?
Hard · Contract Testing · Amazon Microservices Round
Pact ensures API consumers and providers agree on the contract without full integration tests. Consumer writes expectations → generates pact file. Provider verifies against pact file.
// Consumer side (e.g., Frontend calling Order API)
@ExtendWith(PactConsumerTestExt.class)
@PactTestFor(providerName = "OrderService")
public class OrderServiceConsumerTest {

    @Pact(consumer = "FrontendApp")
    public RequestResponsePact createPact(PactDslWithProvider builder) {
        return builder
            .given("order ORD-001 exists")
            .uponReceiving("a request to get order ORD-001")
                .path("/orders/ORD-001")
                .method("GET")
                .headers(Map.of("Authorization", "Bearer token"))
            .willRespondWith()
                .status(200)
                .body(new PactDslJsonBody()
                    .stringType("orderId")
                    .stringValue("status", "CONFIRMED")
                    .decimalType("total"))
            .toPact();
    }

    @Test
    @PactTestFor(pactMethod = "createPact")
    public void verifyOrderAPI(MockServer mock) {
        // Test against Pact mock server (no real service needed)
        given().baseUri(mock.getUrl())
               .get("/orders/ORD-001")
               .then().statusCode(200);
    }
}
💡 Contract testing replaces expensive integration environments. At Amazon scale, Pact lets teams deploy independently without a shared staging environment. Mention this — it shows architectural thinking.
Q10 How do you test an API endpoint for common OWASP security vulnerabilities like IDOR, auth bypass, and SQL injection?
Hard · Security Testing · Amazon Security SDET
IDOR (Insecure Direct Object Reference): Login as user A, try to access user B's resources. Auth bypass: Access protected endpoints without token, with expired token, with tampered JWT. Input validation: SQL injection payloads, XSS, XXE in request body.
@Test
public void idor_ShouldNotAccessOtherUsersOrder() {
    // Create order as User A
    String tokenA = getToken("userA@test.com", "passA");
    String orderId = given().header("Authorization","Bearer "+tokenA)
        .post("/orders").then().extract().path("orderId");

    // Try to access User A order as User B - should fail
    String tokenB = getToken("userB@test.com", "passB");
    given()
        .header("Authorization","Bearer "+tokenB)
        .pathParam("id", orderId)
    .when()
        .get("/orders/{id}")
    .then()
        .statusCode(403);  // Forbidden - not 200!
}

@Test
public void authBypass_NoToken_ShouldReturn401() {
    given().baseUri(BASE_URL)
    .when().get("/orders/ORD-001")
    .then().statusCode(401);
}

@Test
public void sqlInjection_ShouldNotReturnData() {
    given().baseUri(BASE_URL)
        .header("Authorization","Bearer "+getToken())
        .queryParam("productId", "1 OR 1=1; DROP TABLE orders;--")
    .when().get("/products")
    .then().statusCode(anyOf(equalTo(400), equalTo(404)))
          .body("products", is(empty()));
}
💡 IDOR is the #1 API vulnerability. Always test: "Can user B access user A's data?" This is critical for Amazon given the data privacy implications.

⭐ Bar Raiser

The most important Amazon round. An interviewer from a DIFFERENT team ensures you meet Amazon's bar. Almost entirely behavioral using STAR format. Every answer must map to Amazon's 16 Leadership Principles. Most common for SDET: Customer Obsession, Dive Deep, Insist on Highest Standards, Ownership.

Q1 Tell me about a time you found a critical bug that others had missed.
Hard · Insist on Highest Standards · Amazon Bar Raiser
S: During regression testing one week before a major sale event, automated suite was 100% green but I noticed a suspicious 200ms variance in refund response times in logs. T: My job was to sign off release readiness. Instead of reporting green, I investigated the variance. A: Added detailed logging, ran the refund API test 50 times under simulated load. Discovered refunds initiated within 30s of authorization silently returned 200 OK but didn't process — a race condition in the payment state machine. Wrote a focused reproduction test and escalated with full evidence. R: Bug fixed before the sale. Would have affected ~3,200 customers and ₹18 lakh in failed refunds. Added permanent test for this timing condition to regression suite.
// Always prepare STAR stories in this format:
// S - Situation (2-3 sentences, set the context)
// T - Task (what was YOUR specific responsibility)
// A - Action (what YOU specifically did - use "I" not "we")
// R - Result (quantified: %, ₹, time saved, users affected)

// Key metrics to have ready:
// - % improvement in defect escape rate
// - Time reduction in test suite execution
// - Number of bugs prevented from reaching production
// - Business impact in rupees or user count
💡 Bar Raiser probes with follow-ups: "What would you do differently?" and "How did you know the fix was complete?" Prepare 3 levels of depth for each story.
Q2 Describe a time you took ownership of a problem that was not your responsibility.
Medium · Ownership · Amazon Bar Raiser
Structure: The problem was clearly in another team's domain. You could have ignored it. You chose to own it anyway. Result: problem solved AND you built a bridge with another team.\n\nExample: "Our automated tests were failing intermittently due to a slow database query in the payments service — clearly the payments team's problem. But the failures were blocking my team's CI pipeline 3x per week. Instead of just filing a Jira ticket and waiting, I profiled the query myself using EXPLAIN ANALYZE, identified a missing composite index, and created a PR for the payments team with the fix and test data showing 10x query improvement. The payments team merged it in 2 days. Our CI pipeline failures from that cause dropped to zero."
// Ownership LP in practice:
// 1. Never say "that's not my job" in an Amazon interview
// 2. Show you go BEYOND your immediate scope when quality is at risk
// 3. Demonstrate you FOLLOWED THROUGH to completion
// 4. Quantify how YOUR ownership changed the outcome

// Anti-patterns that FAIL the Bar Raiser:
// ❌ "I told my manager about it"
// ❌ "I filed a bug report and moved on"
// ❌ "The team eventually fixed it"
// ✅ "I dug in, understood the root cause, proposed the fix, and verified it"
💡 Ownership = acting like a founder, not an employee. The Bar Raiser looks for evidence you treat Amazon's problems as your own, even when it's inconvenient.
Q3 Tell me about a time you found the root cause of a complex technical problem. Walk me through your debugging process.
Hard · Dive Deep · Amazon Bar Raiser
The Setup: Choose a problem that required multiple layers of investigation, not a surface-level fix. Show methodical debugging. Process: (1) Reproduce consistently first. (2) Narrow down through binary search on components. (3) Add targeted logging at each layer. (4) Form and test hypotheses. (5) Confirm fix with data, not assumption. Example answer framework: "Our payment tests were failing 8% of the time, always on Tuesday nights. I ruled out code changes (no Tuesday deployments). Checked logs — failures correlated with high DB query time. Checked DBA logs — a backup job ran Tuesdays at 2am. The job locked tables briefly causing our tests to timeout. Fix: added 30-second retry with exponential backoff + moved backup window to Sunday."
// Dive Deep investigative framework:
// 1. Reproduce: Can you make it happen consistently?
// 2. Isolate: Which component/layer is failing?
// 3. Correlate: Does it correlate with time/load/data patterns?
// 4. Hypothesize: Form 3 hypotheses, rank by likelihood
// 5. Test: Prove/disprove each hypothesis with data
// 6. Fix: Change ONE thing at a time
// 7. Confirm: Run 100 iterations to confirm fix holds
// 8. Prevent: Add test/alert so it never recurs silently
💡 Dive Deep = going past the obvious answer. The Bar Raiser will ask "But WHY did that happen?" 3 times. Prepare your "5 Whys" for every story.
Q4 How do you prioritize which bugs to fix when you have 50 open defects and limited time before release?
Medium · Customer Obsession · Amazon Bar Raiser
Framework — Customer Impact First: Classify every defect by: (1) Customer visibility — does the customer see this? (2) Frequency — how many customers hit this path? (3) Severity — does it cause data loss, financial harm, or just cosmetic issue? (4) Workaround — is there a way for customers to avoid it?\n\nDecision matrix: P0 = Customer cannot complete core journey (checkout, login, payment) → block release. P1 = Customer sees error but can work around it → fix before release or document. P2 = Minor UX issue, edge case → schedule for next sprint. P3 = Cosmetic/rare edge case → backlog.\n\nKey principle: Always start from the customer's perspective, not the easiest-to-fix perspective.
// Bug triage framework
Priority P0: blocks core user journey         → MUST FIX, release blocked
Priority P1: affects many users, has workaround→ fix before release
Priority P2: affects few users, low impact    → next sprint
Priority P3: cosmetic, extremely rare         → backlog

// Questions for each bug:
// 1. How many customers hit this per day?
// 2. Does it cause financial or data loss?
// 3. Is there a workaround customers can use?
// 4. How long to fix vs impact of delay?

// Amazon principle: "Start with the customer and work backwards"
// Never: "This is easy to fix so let's do it first"
💡 Amazon wants engineers who naturally think about customer impact, not technical interest. Every answer should start with "The customer sees..." not "The code does..."
Q5 Tell me about a time you disagreed with your tech lead or manager on a technical decision. What did you do?
Hard · Conflict Resolution · Amazon Bar Raiser
Key: Show you can disagree respectfully using data, AND commit once a decision is made. Amazon calls this "Disagree and Commit."\n\nExample: "My tech lead wanted to use Cypress for our new automation suite because it was trending. I believed REST Assured + Selenium was better for our team's Java expertise. I didn't just say 'I disagree.' I built a 2-week PoC of both approaches, tested them on 20 of our most complex test scenarios, and documented: setup time, execution speed, CI integration effort, team learning curve, and community support. I presented data showing Selenium was 40% faster to implement given our team's skills. My lead reviewed the data and agreed. We went with Selenium. The suite was delivered 2 weeks early."
// Disagree and Commit pattern:
// Step 1: Disagree with DATA, not opinion
//   "I disagree because our benchmarks show X"
//   NOT "I disagree because I prefer Y"

// Step 2: Present your position with evidence
//   PoC, benchmarks, team survey, cost analysis

// Step 3: Clearly state your recommendation
//   "Based on this data, I recommend A over B"

// Step 4: If decision goes against you - COMMIT
//   "I understand. I'll make B work as well as possible."
//   NOT: "I told you so" when it doesn't work

// What NOT to say:
// ❌ "I just went along with it"
// ❌ "I kept pushing until I won"
// ❌ "I implemented it badly because I disagreed"
💡 "Disagree and Commit" is one of Amazon's 16 LPs. Showing you know the name and demonstrate it naturally is very powerful.
Q6 Describe a time you had to make a significant decision quickly with incomplete information.
Medium · Bias for Action · Amazon Bar Raiser
Amazon values speed in decision-making. The principle: "Many decisions are reversible. Prefer fast decisions that can be corrected over slow 'perfect' decisions."\n\nExample: "20 minutes before a Black Friday deployment, our smoke tests showed a 5% failure rate on the payment flow. Our tech lead was unreachable. I had to decide: delay deployment (millions in revenue at risk) or deploy with known failure rate (5% payment failures). I analyzed: 5% of our payment tests were in a specific edge case (Brazilian credit cards). Brazil represents 2% of our traffic. Real impact: 0.1% of all transactions. I documented my reasoning, got verbal sign-off from the on-call PM, and allowed deployment to proceed. I set up an alert to monitor Brazil payment failures post-deploy. Actual failure rate was 0.08% — within acceptable range. We deployed the Brazil fix in the next 4-hour window."
// Bias for Action decision framework:
// 1. What is the reversibility? (Can we roll back easily?)
// 2. What is the real blast radius? (Not theoretical worst case)
// 3. What data do I have RIGHT NOW?
// 4. Can I get 70% confidence in 10 minutes?
// 5. Document reasoning BEFORE deciding
// 6. Set up monitoring to catch if wrong
// 7. Have rollback ready

// Amazon two-pizza rule: teams should be small enough
// that two pizzas can feed them - same applies to decisions:
// If decision affects your squad, you can make it.
// Escalate only when it crosses squad boundary.
💡 The Bar Raiser wants to see you are NOT paralyzed by incomplete information. Calculated risk + monitoring is valued highly. "I waited for perfect data" is a red flag.
Q7 Give me an example where you had to rebuild trust with a team or stakeholder after something went wrong.
Hard · Earn Trust · Amazon Bar Raiser
Key structure: Own the mistake fully. Describe concrete repair actions. Show systemic prevention.\n\nExample: "I approved a release that had a bug causing 3% of users to see wrong order totals for 6 hours. When discovered, I immediately:\n1. Wrote a clear incident report without defensive language\n2. Personally briefed the PM with full timeline and impact data\n3. Ran a post-mortem with the team to find root cause (we had insufficient boundary value tests for discount calculation)\n4. Added 15 new boundary value tests to our regression suite\n5. Created a release checklist item: 'pricing tests must pass at 100%, no exceptions'\n\nThree months later, those boundary value tests caught a similar bug in pre-release. The PM specifically mentioned the improved process in my performance review."
// Earn Trust after failure - the playbook:
// 1. ACKNOWLEDGE: No defensive language. "I made a mistake."
// 2. IMPACT: Quantify exactly what happened
// 3. ROOT CAUSE: Show you investigated deeply
// 4. FIX: What exactly did you do to repair it?
// 5. PREVENTION: What changed in the process to prevent recurrence?
// 6. FOLLOW-UP: Did the prevention actually work?

// The worst answers:
// ❌ Blame external factors
// ❌ Minimize the impact
// ❌ Promise to "be more careful" (not a system fix)
// ✅ Systemic change that prevented future occurrences
💡 Amazon rewards people who are self-aware about failures AND turn them into improvements. "I made a mistake AND here's what changed permanently because of it" is the gold standard.
Q8 If you were hiring for your team, what qualities would you look for in an SDET candidate beyond technical skills?
Medium · Hiring Best · Amazon Bar Raiser
Amazon's LP says "Hire and Develop the Best" — Bar Raiser evaluates whether YOU would raise the bar.\n\nQuality 1 - Curiosity over knowledge: Someone who asks "why" when a test passes unexpectedly is more valuable than someone who just marks it green.\n\nQuality 2 - Ownership mentality: Do they talk about "our quality" or "the quality team's responsibility"?\n\nQuality 3 - Clear communicator: Can they explain a complex bug to a PM without jargon?\n\nQuality 4 - Data-driven: Do they use metrics to make decisions or just intuition?\n\nQuality 5 - Growth mindset: Have they genuinely changed their mind about something technical in the last year?
// Structured interview I would design:
// Round 1: Live test case writing (not just "write 10 test cases"
//           but "here is a feature spec with gaps - find them")
// Round 2: Debugging session (I give them a broken Selenium test
//           and watch how they investigate, not just fix)
// Round 3: System design ("how would you test Alexa's response
//           quality across 50 languages")
// Round 4: Behavioral (ownership, conflict, failure stories)

// Red flags I would look for:
// - Says "100% coverage" as a goal (quality theater)
// - Never modified or challenged a process
// - No specific numbers in any achievement
// - "Testing is about finding bugs" (missing prevention)
💡 The Bar Raiser is secretly evaluating: "Would I hire this person on MY team?" Answer this question in a way that shows you'd be a high-bar addition to any Amazon team.
Q9 Where do you see QA Automation heading in the next 5 years? How are you preparing for it?
Hard · Think Big · Amazon Senior SDET
Trend 1 — AI-assisted test generation: Tools like Copilot and specialized AI will generate baseline test cases from specs. SDETs will shift to reviewing and improving AI-generated tests rather than writing from scratch. Trend 2 — Shift-left extremism: Testing happening at requirements stage (AI analyzing spec for ambiguity and edge cases). Trend 3 — Observability-driven testing: Production monitoring data feeding back into test prioritization — test what breaks most in production. Trend 4 — Chaos engineering mainstream: Every SDET expected to design resilience experiments. How I'm preparing: Learning ML basics to evaluate AI-generated test quality. Contributing to open source chaos engineering projects. Studying distributed systems to test microservices effectively.
// The evolving SDET role:
// 2020: Write manual tests → automate them
// 2023: Design automation frameworks + own CI/CD pipelines
// 2025: Observability-driven + chaos engineering + AI-assisted
// 2028: AI generates tests, SDET validates strategy + coverage

// Skills to build NOW for future-proof career:
// 1. Prompt engineering for test generation (ChatGPT, Copilot)
// 2. Distributed systems understanding (test what you cant replicate)
// 3. Chaos engineering (LitmusChaos, Gremlin)
// 4. Contract testing (Pact for microservices)
// 5. eBPF + observability (test via production signals)
💡 "Think Big" LP: Amazon wants people who think beyond their current scope. Show you are thinking about where the industry is going, not just your current tools.
Q10 How have you reduced the cost or resource usage of your test infrastructure?
Medium · Frugality · Amazon Bar Raiser
Amazon's Frugality LP: "Accomplish more with less."\n\nExample 1 — Reduce cloud costs: "Our Selenium Grid on AWS ran 20 EC2 instances 24/7 costing $2,400/month. I found they were idle 70% of the time. I implemented auto-scaling: scale to 2 instances at night, scale up to 20 only when tests run. Saved $1,680/month — 70% cost reduction."\n\nExample 2 — Reduce test execution time: "Our 4-hour regression suite was running on 5 machines. I analyzed test duration data and found 20% of tests took 80% of the time. By running the slow tests first in parallel, I reduced total duration to 45 minutes on the same infrastructure."\n\nKey principle: Frugality is not about being cheap — it's about maximizing value per dollar.
// Cost optimization for test infrastructure:
// 1. Auto-scaling Grid nodes (on-demand not 24/7)
//    EC2 on-demand vs Reserved vs Spot for batch test runs
// 2. Headless browsers (no GUI = lower CPU)
// 3. API setup instead of UI setup (10x faster, lower resource)
// 4. TestContainers instead of persistent test environments
// 5. Test quarantine (remove flaky tests = less re-runs)
// 6. Smoke-first pipeline (fail fast, dont run full suite on bad build)

// Calculate monthly test infrastructure cost:
// Instances × hours × AWS rate = monthly cost
// Compare with developer time saved from faster pipelines
// ROI must be positive
💡 Frugality in tech interviews is about showing business sense. You understand that compute costs money and you optimize accordingly. Shows you think like an owner, not just a developer.
🔍

Google Interview Process

FAANG · Search · GCP · Android · Mountain View USA · 5–7 Rounds

📋 Phone Screen → Coding ×2 → Test Design → System Design → Googliness🎯 SET · TE · SWE-QA📍 Hyderabad · Bangalore · Remote

💻 Coding Round

Google's coding round for SET/TE is IDENTICAL to SWE rounds — LeetCode Medium/Hard. Google values communication as much as correctness. Always explain your approach before typing. Ask clarifying questions. Mention time and space complexity without being asked.

Q1 Check if all brackets in a string are balanced: (), [], {}.
Easy-Medium · Stack · Google Phone Screen
Use a Stack. Push opening brackets. On closing bracket, pop and verify match. Stack must be empty at end.
public boolean isBalanced(String s) {
    Deque<Character> stack = new ArrayDeque<>();
    Map<Character,Character> pairs = Map.of(")","(", "]","[", "}","{");
    for (char c : s.toCharArray()) {
        if (pairs.containsValue(c)) stack.push(c);
        else if (pairs.containsKey(c))
            if (stack.isEmpty() || stack.pop() != pairs.get(c)) return false;
    }
    return stack.isEmpty();
}
// "([]{})"→true  "([)]"→false  "{"→false  ""→true
💡 After solving, Google ALWAYS asks: "Now write unit tests for this." Have 6 test cases ready: empty, single bracket, matched pairs, wrong order, unclosed, non-bracket chars.
Q2 Find the maximum depth of a binary tree.
Medium · Tree / BFS · Google Onsite
Recursive DFS: max depth = 1 + max(leftDepth, rightDepth). Base case: null node returns 0.
// Recursive - clean and elegant
public int maxDepth(TreeNode root) {
    if (root == null) return 0;
    return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));
}

// Iterative BFS - mention both to Google
public int maxDepthBFS(TreeNode root) {
    if (root == null) return 0;
    Queue<TreeNode> q = new LinkedList<>();
    q.offer(root); int depth = 0;
    while (!q.isEmpty()) {
        depth++;
        int size = q.size();
        for (int i = 0; i < size; i++) {
            TreeNode n = q.poll();
            if (n.left  != null) q.offer(n.left);
            if (n.right != null) q.offer(n.right);
        }
    }
    return depth;
}
💡 Google loves when you offer both recursive and iterative solutions. Shows depth of thinking. The iterative BFS is useful when stack overflow is a concern for very deep trees.
Q3 Given a 2D grid of characters, count all islands (connected groups of "1"s).
Medium · Graph / DFS · Google SET Round
DFS flood fill. For each unvisited "1", increment island count and recursively mark all connected cells as visited.
public int numIslands(char[][] grid) {
    int count = 0;
    for (int i = 0; i < grid.length; i++)
        for (int j = 0; j < grid[0].length; j++)
            if (grid[i][j] == "1") { dfs(grid,i,j); count++; }
    return count;
}
private void dfs(char[][] g, int i, int j) {
    if (i<0||i>=g.length||j<0||j>=g[0].length||g[i][j]!="1") return;
    g[i][j]="0";
    dfs(g,i+1,j); dfs(g,i-1,j); dfs(g,i,j+1); dfs(g,i,j-1);
}
// [["1","1","0"],["1","1","0"],["0","0","1"]] → 2
💡 Google often asks: "What if the grid is too large for recursion?" Answer: use BFS with a queue (iterative DFS) to avoid stack overflow.
Q4 Given a sorted array, remove duplicates in-place and return the new length.
Medium · Two Pointers · Google Coding Round
Use two pointers: slow pointer tracks the write position, fast pointer scans. Only write when a new unique value is found.
public int removeDuplicates(int[] nums) {
    if (nums.length == 0) return 0;
    int slow = 0;
    for (int fast = 1; fast < nums.length; fast++) {
        if (nums[fast] != nums[slow]) {
            slow++;
            nums[slow] = nums[fast];
        }
    }
    return slow + 1;  // length = index + 1
}
// [1,1,2]       → 2, nums=[1,2,...]
// [0,0,1,1,1,2] → 3, nums=[0,1,2,...]
💡 In-place modification is O(1) space. Always mention the trade-off: no new array allocation. Google values space efficiency.
Q5 Given a string s, find the longest palindromic substring.
Hard · Dynamic Programming · Google Senior SET
Expand Around Center. For each character (and between characters), expand outward as long as characters match. Track the longest found.
public String longestPalindrome(String s) {
    int start = 0, maxLen = 1;
    for (int i = 0; i < s.length(); i++) {
        // Odd length palindromes (center at i)
        int len1 = expandAroundCenter(s, i, i);
        // Even length palindromes (center between i and i+1)
        int len2 = expandAroundCenter(s, i, i+1);
        int len = Math.max(len1, len2);
        if (len > maxLen) {
            maxLen = len;
            start = i - (len - 1) / 2;
        }
    }
    return s.substring(start, start + maxLen);
}
private int expandAroundCenter(String s, int lo, int hi) {
    while (lo >= 0 && hi < s.length() && s.charAt(lo) == s.charAt(hi)) {
        lo--; hi++;
    }
    return hi - lo - 1;
}
// "babad"→"bab"  "cbbd"→"bb"  "a"→"a"
💡 Google may ask for DP solution as follow-up (O(n²) time and space). Know Manacher's algorithm exists (O(n)) but the expand-center O(n²) time O(1) space solution is usually sufficient.
Q6 Find the first non-repeating character in a string. Return its index, or -1 if none.
Medium · HashMap Frequency · Google OA
Two passes: first pass count frequencies with HashMap. Second pass find first character with frequency 1. O(n) time.
public int firstUniqChar(String s) {
    Map<Character,Integer> freq = new HashMap<>();
    for (char c : s.toCharArray())
        freq.merge(c, 1, Integer::sum);
    for (int i = 0; i < s.length(); i++)
        if (freq.get(s.charAt(i)) == 1) return i;
    return -1;
}
// "leetcode"→0  "loveleetcode"→2  "aabb"→-1
💡 Alternative: use int[26] array instead of HashMap for lowercase letters — O(1) space and faster. Google appreciates this optimization.
Q7 Given a list of intervals, merge all overlapping intervals.
Medium · Merge Intervals · Google Onsite
Sort by start time. Iterate through sorted intervals. If current interval overlaps with last in result (start ≤ last end), merge by updating end. Otherwise add as new interval.
public int[][] merge(int[][] intervals) {
    Arrays.sort(intervals, (a,b) -> a[0] - b[0]);
    List<int[]> merged = new ArrayList<>();
    for (int[] cur : intervals) {
        if (merged.isEmpty() || merged.get(merged.size()-1)[1] < cur[0])
            merged.add(cur);
        else
            merged.get(merged.size()-1)[1] = Math.max(
                merged.get(merged.size()-1)[1], cur[1]);
    }
    return merged.toArray(new int[0][]);
}
// [[1,3],[2,6],[8,10],[15,18]] → [[1,6],[8,10],[15,18]]
💡 This appears in test scheduling problems: "Given N test suites with start/end times, what's the minimum number of test agents needed?" — Interval scheduling variation.
Q8 Find the square root of a non-negative integer using binary search (return floor value).
Medium · Binary Search · Google Phone Screen
Binary search between 0 and x. For each mid, check if mid*mid ≤ x. Keep track of the largest valid mid.
public int mySqrt(int x) {
    if (x < 2) return x;
    int lo = 1, hi = x / 2, result = 0;
    while (lo <= hi) {
        long mid = lo + (hi - lo) / 2;  // long to prevent overflow
        if (mid * mid == x) return (int) mid;
        else if (mid * mid < x) { result = (int) mid; lo = (int)(mid+1); }
        else hi = (int)(mid-1);
    }
    return result;
}
// 4→2  8→2  9→3  1→1  0→0
💡 Use long for mid*mid to avoid integer overflow when x is large. Google interviewers specifically look for this overflow prevention.
Q9 Find all subsets of a given array (power set). No duplicate subsets.
Hard · Backtracking · Google Senior SET
Backtracking. For each element, decide to include or exclude. Build subsets recursively. To handle duplicates: sort first and skip duplicate elements at the same recursion level.
public List<List<Integer>> subsets(int[] nums) {
    List<List<Integer>> result = new ArrayList<>();
    backtrack(result, new ArrayList<>(), nums, 0);
    return result;
}
private void backtrack(List<List<Integer>> res, List<Integer> cur,
                        int[] nums, int start) {
    res.add(new ArrayList<>(cur));   // add current subset
    for (int i = start; i < nums.length; i++) {
        cur.add(nums[i]);
        backtrack(res, cur, nums, i+1);
        cur.remove(cur.size()-1);    // backtrack
    }
}
// [1,2,3] → [[],[1],[1,2],[1,2,3],[1,3],[2],[2,3],[3]]
// 2^n subsets total
💡 Google uses this to test "combination/permutation" thinking. The SDET context: "generate all valid input combinations for a form with N optional fields."
Q10 Find the K largest elements in an array. Return them in any order.
Hard · Heap / Priority Queue · Google Onsite 2024
Use a min-heap of size K. Process all elements — if current > heap top, replace top. At end, heap contains K largest.
public int[] findTopK(int[] nums, int k) {
    PriorityQueue<Integer> minHeap = new PriorityQueue<>(k);
    for (int n : nums) {
        if (minHeap.size() < k) minHeap.offer(n);
        else if (n > minHeap.peek()) {
            minHeap.poll();
            minHeap.offer(n);
        }
    }
    return minHeap.stream().mapToInt(x->x).toArray();
}
// [3,2,1,5,6,4] k=2 → [5,6]
// [1] k=1          → [1]

// Time: O(n log k)  Space: O(k)
// vs Sort: O(n log n) time  O(1) space
// Heap wins when k << n
💡 Always compare heap approach vs sorting approach and explain when each wins. Heap is O(n log k) — critical advantage when k is small relative to n (e.g., top 10 results from 1 billion).

🧪 Test Design Round

Google's most unique round. Asked to "test X" where X is often abstract — a vending machine, elevator, Google Search. They evaluate STRUCTURED THINKING, not tool knowledge. Use: Functional → Edge Cases → Non-Functional → Security → Accessibility → Negative.

Q1 How would you test Google Search? Walk through your complete test strategy.
Hard · Test Strategy · Google Classic Question
1. Clarify scope: "Am I testing the UI? The algorithm? Performance? I'll cover all layers."\n\n2. Functional:\n• Basic query returns relevant results\n• Autocomplete suggests correct completions\n• Spell correction: "hwo to test" → "how to test"\n• Special operators: quotes for exact match, minus to exclude, site:, filetype:\n• Filters: Images, News, Videos, Shopping, Maps show correct content\n• Pagination: different results per page, no duplicates\n\n3. Edge Cases:\n• Empty query — no crash\n• 1 character: "a"\n• 10,000 character query\n• Unicode: Hindi/Arabic/Chinese\n• JavaScript/SQL injection in query\n\n4. Performance:\n• Results in <200ms (p95)\n• Handles 8.5B searches/day\n\n5. Accessibility:\n• Screen reader, keyboard-only navigation, high-contrast mode
// Test Design Structure Template:
// 1. CLARIFY: What exactly is in scope?
// 2. FUNCTIONAL: What should it DO correctly?
// 3. EDGE CASES: What unusual inputs break it?
// 4. NEGATIVE: What should it REJECT?
// 5. NON-FUNCTIONAL: Performance, Security, Reliability
// 6. ACCESSIBILITY: WCAG 2.1 compliance
// 7. COMPATIBILITY: Browsers, devices, OS
// 8. LOCALIZATION: Multiple languages, RTL text
💡 Google likes when you prioritize: "I'd test payment flow first because financial correctness is highest risk, then auth, then core features." Show you can triage by risk.
Q2 How would you test a vending machine (software)? List all test scenarios.
Medium · Physical System Testing · Google Classic
Classic Google question. Cover all state transitions systematically.\n\nHappy Path: Insert money → select item → item dispenses → correct change returned\n\nPayment Tests:\n• Exact change\n• Overpayment → correct change returned\n• Underpayment → item not dispensed, money returned\n• Multiple coins of different denominations\n\nItem Tests:\n• Item available → dispenses\n• Item out of stock → error message, money returned\n• Item stuck in dispenser — failure handling\n• Last item purchased → show "Out" immediately\n\nEdge Cases:\n• Cancel mid-transaction → full refund\n• Power cut mid-dispensing\n• Concurrent users (two people hit same item simultaneously)\n\nNon-Functional:\n• Display readability in sunlight\n• Temperature extremes (coins jam in cold)
// State Machine test approach for vending machine:
// States: IDLE → AWAITING_SELECTION → DISPENSING → CHANGE → IDLE
// Test each valid transition AND invalid transitions

// Valid: IDLE → insert coin → AWAITING_SELECTION
// Valid: AWAITING_SELECTION → select item → DISPENSING
// Invalid: AWAITING_SELECTION → select item (out of stock) → IDLE (refund)

// Boundary values:
// Amount = 0         → reject, stay IDLE
// Amount = item price → dispense, 0 change
// Amount = INT_MAX   → overflow protection
💡 State machine thinking is the key to Google test design questions. Draw the states and transitions before listing test cases. Shows structured thinking.
Q3 Design a test strategy for Gmail compose: cover all scenarios including edge cases.
Hard · Feature Testing · Google Onsite
Functional Core:\n• To, CC, BCC fields accept valid emails\n• Subject and body accept text\n• Send button triggers delivery\n• Draft auto-saves every 30 seconds\n\nEdge Cases:\n• 500 recipients in To field\n• 25MB attachment (max limit)\n• Over 25MB — error shown, not sent\n• Empty subject — confirmation dialog\n• Empty body — confirmation dialog\n• Reply-all with large distribution list\n• Unicode in subject/body (emoji, Arabic, Chinese)\n• Undo Send within 30 seconds\n\nNegative Tests:\n• Invalid email format: "user@" → error\n• Attachments with .exe extension → blocked\n• Script tags in HTML compose → sanitized\n\nAccessibility:\n• Screen reader announces To field changes\n• Tab order is logical\n• Keyboard shortcut Ctrl+Enter sends
// Test categories by risk:
// CRITICAL (P0): Email actually sends and delivers
// HIGH (P1):     Attachments, Reply-all, Draft save
// MEDIUM (P2):   Formatting, CC/BCC, Undo send
// LOW (P3):      Keyboard shortcuts, theme, font size
💡 Google wants you to identify the riskiest tests first. For Gmail, "email actually delivers" is P0 — a Gmail that sends but doesn't deliver is catastrophic.
Q4 How would you test Google Maps navigation? Cover all test scenarios.
Hard · Algorithm Testing · Google Test Design
Route Calculation:\n• Shortest vs fastest route\n• Traffic-aware routing (recalculates on congestion)\n• Avoid highways, tolls, ferries options\n• Multi-waypoint routing\n\nNavigation:\n• Turn-by-turn voice guidance accuracy\n• Rerouting when wrong turn taken\n• Lane guidance on complex junctions\n• Roundabout instructions\n\nEdge Cases:\n• No route possible (ocean destination)\n• Start = destination\n• Extremely long route (London to Beijing driving)\n• New road not in database\n• Road closed — automatic reroute\n\nNon-Functional:\n• Offline maps work without internet\n• Battery usage (GPS-intensive)\n• Works in tunnels (GPS dead zone)\n• Location accuracy ±5 meters
// Test data strategy for Maps testing:
// Use fixed start/end coordinates for reproducible tests
// Real locations that have known routes
// Test routes with known complexities (ferry, toll, highway)
// Compare against known-correct directions as baseline
💡 Maps testing requires location mocking. In Selenium/Appium, use DevTools CDP to set fake GPS coordinates without physically being at the location.
Q5 Design a test strategy for the Google Chrome Android browser.
Medium · Mobile App Testing · Google Android Team
Core Browsing:\n• Load HTTP and HTTPS pages correctly\n• Navigate back/forward history\n• Multiple tabs open simultaneously\n• Bookmark creation and retrieval\n\nPerformance:\n• Page load time < 3s on 4G\n• Memory usage under 300MB for 10 open tabs\n• Smooth scrolling at 60fps\n\nMobile-Specific:\n• Portrait and landscape orientation\n• Pinch-to-zoom on pages\n• Text size readability (accessibility)\n• One-handed reachability\n\nNetwork Conditions:\n• Slow 3G (throttled)\n• Offline mode — cached pages serve\n• Network switch: WiFi → mobile data\n\nSecurity:\n• HTTPS padlock shows for secure sites\n• Warning shown for HTTP sites\n• Phishing URL detection
// Mobile-specific test scenarios to always include:
// 1. App state after phone call interruption
// 2. Low battery mode behavior
// 3. Low storage (< 100MB free)
// 4. Background/foreground app switching
// 5. Different Android versions (5, 8, 10, 13, 14)
// 6. Manufacturer-specific OS modifications (Samsung, OnePlus)
// 7. Accessibility services: TalkBack enabled
💡 Google expects deep Android knowledge for mobile testing. Mention Espresso for unit UI tests and Appium/UIAutomator for E2E. Demonstrate awareness of Android fragmentation.
Q6 Design a comprehensive test plan for a REST API that allows users to upload files to Google Drive.
Hard · API Test Design · Google Backend Round
Functional Tests:\n• Upload file < 100MB → success, file accessible\n• Upload file = 15GB (max) → success\n• Resume interrupted upload (resumable upload API)\n• Duplicate filename → version created\n• Correct MIME type detected\n\nBoundary Tests:\n• 0 bytes (empty file) → defined behavior\n• Exactly at size limit\n• 1 byte over limit → 413 error\n\nPermission Tests:\n• Upload to own drive → success\n• Upload to shared drive (editor) → success\n• Upload to shared drive (viewer) → 403 forbidden\n• Upload without auth token → 401\n\nError Scenarios:\n• Network interruption mid-upload\n• Corrupted file content\n• Unsupported file format\n\nPerformance:\n• 1GB file upload within 5 minutes on 100Mbps
// API test design checklist:
// ✅ Authentication: valid token, expired, no token, wrong scope
// ✅ Authorization: owner, editor, viewer, no access
// ✅ Happy path: minimal valid request
// ✅ Required fields: remove each required field
// ✅ Optional fields: test with/without each
// ✅ Boundary values: min, max, just over
// ✅ Idempotency: same request twice
// ✅ Error messages: correct status codes
// ✅ Response time: meets SLA
💡 Google Drive upload uses a resumable upload protocol. Knowing that real Google APIs use this protocol shows domain depth beyond basic REST testing.
Q7 How would you test OAuth 2.0 login flow for security vulnerabilities?
Medium · Security Testing · Google Security Round
Authorization Code Flow Tests:\n• State parameter is random and validated (prevents CSRF)\n• Authorization code is single-use (replay attack)\n• Code is short-lived (expires in 10 min)\n• Redirect URI matches registered exactly\n\nToken Security:\n• Access token is opaque or JWT with correct signature\n• Refresh token rotation on use\n• Tokens are revoked on logout\n• Tokens not in URL (must be in Authorization header)\n\nAttack Scenarios:\n• CSRF: submit request with no/wrong state param → rejected\n• Open redirect: inject malicious redirect_uri → rejected\n• Token leakage: check tokens not logged to server logs\n• PKCE bypass attempt (for mobile apps)
// OAuth 2.0 security test assertions:
// ✅ state param: random UUID per request, validated on return
// ✅ code: single-use (second use returns 400)
// ✅ redirect_uri: exact match with registered URIs
// ✅ tokens: HTTPS only, never in GET params
// ✅ logout: both access + refresh tokens revoked
// ✅ JWT: signature verified, claims validated (exp, iss, aud)
💡 Google has a dedicated Security team for OAuth. Demonstrating knowledge of PKCE (Proof Key for Code Exchange) for mobile/SPA flows shows advanced security testing awareness.
Q8 How would you load test a new Google API that will serve 100M requests per day at launch?
Hard · Performance Testing · Google SRE Round
Pre-load Phase:\n• Capacity planning: 100M/day = ~1,157 RPS average, ~3,000 RPS peak\n• Baseline test: measure with 1 user first\n• Ramp test: gradually increase to 1,000 RPS, observe latency\n\nLoad Test:\n• Target: 3,000 RPS (peak) for 30 minutes\n• SLA: p99 < 200ms, error rate < 0.01%\n• Monitor: CPU, memory, DB connections, GC pauses\n\nStress Test:\n• Push to 5,000 RPS — find breaking point\n• Observe degradation: does it fail gracefully or cascade?\n\nSpike Test:\n• 10x traffic spike (viral event): 100 → 10,000 RPS in 10 seconds\n• Does auto-scaling kick in fast enough?\n\nSoak Test:\n• 2,000 RPS for 24 hours — memory leak detection
// k6 load test script for Google API
import http from "k6/http";
import { check, sleep } from "k6";
export let options = {
    stages: [
        { duration: "5m",  target: 500  },  // ramp up
        { duration: "20m", target: 3000 },  // steady state
        { duration: "5m",  target: 0    },  // ramp down
    ],
    thresholds: {
        "http_req_duration": ["p(99)<200"],  // SLA
        "http_req_failed":   ["rate<0.0001"], // 0.01% error
    },
};
export default function() {
    let res = http.get("https://api.google.com/v1/endpoint",
        { headers: { "Authorization": `Bearer ${__ENV.TOKEN}` }});
    check(res, { "status 200": r => r.status === 200 });
    sleep(0.1);
}
💡 Always mention BOTH latency and error rate SLAs. A 200ms response with 5% errors is worse than a 500ms response with 0.001% errors for most APIs.
Q9 How do you test a web application for WCAG 2.1 AA accessibility compliance?
Medium · Accessibility Testing · Google A11y Round
Automated Tools:\n• axe-core (Selenium integration) — catches ~35% of issues\n• Lighthouse accessibility score\n• WAVE browser extension\n\nManual Tests:\n• Keyboard-only navigation (no mouse)\n• Tab order is logical and visible\n• All interactive elements are focusable\n• Screen reader (NVDA/VoiceOver) reads page correctly\n\nWCAG AA Checklist:\n• All images have alt text\n• Color contrast ratio ≥ 4.5:1 (text)\n• Focus indicator visible\n• Error messages not solely red color\n• Form labels associated with inputs\n• Videos have captions
// Selenium + axe-core automated accessibility test
@Test
public void accessibilityTest_CheckoutPage_ShouldPassWCAG_AA() {
    driver.get(BASE_URL + "/checkout");

    // Inject axe-core and run accessibility check
    JavascriptExecutor js = (JavascriptExecutor) driver;
    js.executeScript(loadAxeScript()); // load axe-core JS
    Map<String, Object> result = (Map<String, Object>)
        js.executeScript("return axe.run()");

    List<Map> violations = (List<Map>) result.get("violations");
    violations.forEach(v -> System.out.println(
        "VIOLATION: " + v.get("id") + " - " + v.get("description")));

    Assert.assertEquals(violations.size(), 0,
        "Accessibility violations found: " + violations.size());
}
💡 Google has a dedicated Accessibility team. Showing knowledge of axe-core + WCAG standards demonstrates maturity beyond standard automation testing.
Q10 Design a visual regression testing system for Google Docs that works across 50 languages and 10 browsers.
Hard · Test Infrastructure Design · Google System Design
Capture Layer:\n• Playwright takes screenshots per page/component/locale/browser\n• Grid: run all combinations in parallel (50 langs × 10 browsers = 500 combinations)\n• Store screenshots in GCS (Google Cloud Storage) with metadata: page, locale, browser, timestamp\n\nComparison Layer:\n• Compare current vs baseline using perceptual hash (pHash) or pixel diff\n• ML similarity scoring to ignore known irrelevant differences (font rendering, antialiasing)\n• Threshold: flag if >0.1% pixel change\n\nBaseline Management:\n• New baseline approved via PR review (QA approves)\n• Historical baselines stored indefinitely for rollback\n\nReporting:\n• Visual diff shown side-by-side with highlights\n• Grouped by locale/browser to identify systematic issues\n• Jira auto-created for each new regression
// Visual regression test with Playwright
const { test, expect } = require("@playwright/test");
test("Google Docs editor - visual regression", async ({ page }) => {
    await page.goto("/docs/create");
    await page.waitForLoadState("networkidle");
    // Take full-page screenshot
    await expect(page).toHaveScreenshot("docs-editor.png", {
        fullPage: true,
        animations: "disabled",    // disable CSS animations
        mask: [page.locator(".timestamp")],  // mask dynamic content
    });
});
// Playwright stores baseline on first run
// Subsequent runs diff against baseline
// toHaveScreenshot fails if diff > threshold
💡 Mention "masking dynamic content" — timestamps, user avatars, ads. Visual regression tests fail on irrelevant dynamic content without masking, creating alert fatigue.

🌟 Googliness / Behavioral

Google evaluates "Googliness": intellectual humility, enjoying learning, doing the right thing, comfort with ambiguity. Less scripted than Amazon's LP round — more conversational. Focus on genuine stories, intellectual honesty, and curiosity over prepared scripts.

Q1 Tell me about a time you had to learn a new technology quickly to solve a problem.
Medium · Learning Agility · Google Googliness Round
Structure: Show your learning PROCESS, not just that you learned it. Google values how you learn, not just what you've learned.\n\nExample: "Our team needed to migrate from Selenium to Playwright in 3 weeks. I'd never used Playwright. I spent day 1-3 reading the full docs — not just the quick-start, the complete API reference. I built 10 of our hardest test scenarios in Playwright side-by-side with Selenium, documenting every difference. I joined the Playwright Discord to ask edge case questions. On day 7 I had a demo ready. The migration completed in 2.5 weeks. I then wrote an internal guide that two other teams used to migrate."
// My learning framework:
// 1. Read official docs end-to-end (not tutorials)
// 2. Build something real, not hello-world
// 3. Find edge cases where documentation is unclear
// 4. Join the community (Discord, GitHub issues)
// 5. Teach someone else within 2 weeks (solidifies understanding)
// 6. Document what surprised you (for the team)
💡 Google loves: "I went beyond the minimum." Reading full docs, joining the community, and documenting for others shows Googliness — thoroughness and sharing.
Q2 Tell me about a time you changed your mind about something technical. What convinced you?
Medium · Intellectual Honesty · Google Behavioral
Google values people who update their beliefs based on evidence. "Intellectual honesty" is a Googliness pillar.\n\nExample: "I was a strong advocate for BDD/Cucumber for our team — I believed readable Gherkin tests would get PMs involved in test design. After 6 months, our PM had never read a single feature file. Meanwhile, our step definitions were complex and brittle. I reviewed the data: test maintenance cost increased 40%, PM engagement was zero. I admitted I was wrong, made the case to the team, and we migrated back to plain TestNG with comments. Test maintenance time dropped by 35% in the next quarter."
// Signs of intellectual honesty Google looks for:
// ✅ "I was wrong about X because Y"
// ✅ "The data convinced me to change my approach"
// ✅ "I held X belief until I saw evidence of Y"
// ✅ "I tried to disprove my own hypothesis"

// Signs of intellectual dishonesty (avoid):
// ❌ "I was always right about this"
// ❌ "I changed my mind because my manager told me to"
// ❌ "I never make technical mistakes"
💡 Google specifically looks for intellectual humility. Someone who "has never changed their mind" is a red flag — it signals defensiveness and inability to update on new evidence.
Q3 Describe a time you had to make progress on a project despite very unclear requirements.
Hard · Ambiguity · Google Senior Round
Google hires for ambiguity tolerance — especially for SET roles where requirements are often "make sure this works" without specifics.\n\nExample: "I was asked to 'test the new recommendation algorithm' with no spec, no acceptance criteria, and the algorithm was changing daily. I couldn't wait for a perfect spec. I: (1) Defined my own testing charter by interviewing the PM and data scientist for 30 minutes. (2) Built a golden dataset of 1,000 user queries with expert-labeled expected results. (3) Created a script that measured recommendation quality against the golden dataset. (4) Ran it after every algorithm change, reporting quality delta. This became the de facto acceptance test that the team used to validate algorithm releases."
// Framework for testing under ambiguity:
// 1. Interview stakeholders: "What does success look like?"
// 2. Define your own testable acceptance criteria
// 3. Start with what you DO know and expand
// 4. Make your assumptions explicit and visible
// 5. Build quick feedback loop (not perfect, but running)
// 6. Iterate — refine criteria as you learn more
// 7. Document your assumptions for team alignment
💡 Google loves: "I didn't wait for perfect requirements." Taking initiative to define test criteria from ambiguous requirements is a senior-level skill they actively test for.
Q4 Tell me about a time you had to work with a team you found difficult. How did you make it work?
Medium · Collaboration · Google Team Round
Key: Show empathy and systems thinking — find the root cause of why the team was "difficult" rather than blaming them.\n\nStructure: Situation → Why was it hard → What I understood about their perspective → What I changed in my approach → Result.\n\nCommon example: Dev team pushing back on every QA bug report. Root cause: devs felt bugs were filed without context or reproduction steps, wasting their time. Resolution: I created a bug report template requiring exact steps, environment details, and a video recording. Bug acceptance rate went from 60% to 94%. "Difficult team" → collaborative team.
// Collaboration framework:
// Before: "This team is difficult"
// Reframe: "What is their incentive structure?"
//           "What do they find painful about our interaction?"
//           "What can I change in MY behavior?"

// Common root causes of cross-team friction:
// 1. Different definitions of "done"
// 2. Bugs filed without sufficient context
// 3. QA blocking releases for low-priority issues
// 4. Dev not including QA in design reviews
// Solution: always address the SYSTEM not the person
💡 Google is a collaborative culture. "I changed my own behavior" stories are valued over "I convinced them to change." Show you can adapt, not just persuade.
Q5 What has been your greatest technical impact as a QA engineer? Give me specifics.
Hard · Impact · Google Senior SDET
Format: Before state → What I built → After state → Business impact in numbers.\n\nStrong example: "When I joined, we had 400 manual test cases taking 3 engineers 5 days to execute before each release. We released every 6 weeks. I designed and built a Selenium + TestNG automation framework from scratch over 3 months. Key decisions: Page Object Model, ThreadLocal parallel execution, REST Assured for API layer, GitHub Actions CI. Result: 340 of 400 test cases automated. Suite runs in 28 minutes with 8 parallel threads. Release cycle dropped from 6 weeks to 1 week. Engineering team now deploys to production weekly instead of biweekly. The framework has since grown to 1,400 tests and is maintained by 3 SDETs."
// Quantifiable impact metrics to have ready:
// Test execution time: X hours → Y minutes (Z% reduction)
// Release frequency: every N weeks → every M days
// Bug escape rate: X% → Y% (defects caught before prod)
// Test coverage: X% → Y%
// Manual testing hours saved per sprint: N hours
// Business impact: N releases per quarter vs previous M
💡 Google wants specifics. Vague: "improved our testing process." Strong: "reduced release cycle from 6 weeks to 1 week, enabling 3x more feature deliveries per quarter." Numbers make your story credible.
Q6 Tell me about your biggest professional failure. What did you learn?
Medium · Failure · Google Round
Key: Google wants intellectual honesty. Own the failure fully, show what you learned, and show what changed permanently because of it.\n\nExample: "I approved a release that had a regression in the search filter — users couldn't filter results by date. It affected 8% of users for 14 hours before discovery. The failure: I had removed date filter tests from our smoke suite because they were 'flaky.' I mistook flakiness (a test infrastructure problem) for the tests being unnecessary.\n\nWhat changed:\n1. I stopped deleting flaky tests — I fix or quarantine them, never delete\n2. I created a rule: any test removed from suite requires written justification and PM sign-off\n3. I built a 'test coverage map' linking test cases to user-facing features\n\nThree months later, those restored tests caught a similar regression in pre-release."
// Failure story structure:
// 1. What exactly went wrong (be specific, no vagueness)
// 2. What was YOUR role (take full ownership)
// 3. What was the impact (user/business impact in numbers)
// 4. Root cause (your actual thinking error, not external factors)
// 5. What changed in the SYSTEM (not just "I was more careful")
// 6. Evidence the change worked (follow-up result)
💡 Google interviewers are very experienced at detecting when candidates minimize their mistakes. Go all in on owning the failure — it builds enormous trust when done genuinely.
Q7 If you were designing the testing strategy for a new Google product from scratch, what would you do?
Hard · Think Big · Google Senior SET
Step 1 — Understand the risk profile: What can go wrong? Financial risk? Privacy risk? Availability risk? This determines where to focus testing effort.\n\nStep 2 — Define quality goals: Not "test everything" but specific, measurable targets: 99.9% availability, < 0.1% error rate, < 200ms p95 latency.\n\nStep 3 — Build the test pyramid:\n• 70% unit/component tests (developer-owned)\n• 20% integration/contract tests (shared)\n• 10% E2E critical user journeys (QA-owned)\n\nStep 4 — Observability from day 1: Build monitoring before launch, not after. Define alerts for each quality goal.\n\nStep 5 — Shift-left: QA in design reviews, writing acceptance criteria, reviewing API contracts before implementation.
// Quality strategy document outline:
// 1. Risk register: top 10 risks + mitigation
// 2. Quality goals: SLAs per metric
// 3. Test pyramid: % allocation per layer
// 4. Coverage map: critical user journeys vs test coverage
// 5. Monitoring strategy: what gets alerted, who responds
// 6. Release criteria: definition of "ready to ship"
// 7. Chaos engineering plan: what do we intentionally break?
💡 Google thinks at product level, not test case level. Show you can define a quality strategy for an entire product, not just write tests for individual features.
Q8 How have you helped grow the skills of less experienced engineers on your team?
Medium · Mentoring · Google Senior Round
Key: Google values engineers who make the team better, not just their own work.\n\nConcrete examples to mention:\n• Pair testing sessions: sit together and test a feature — teach by doing, not by telling\n• Code reviews with detailed explanations: not just "change this" but "here's why this matters"\n• Internal tech talks: present a new testing technique to the whole team\n• Test case review: before junior engineers submit test cases, review together and explain gap analysis\n• "Teach me" rule: when a junior asks a question, answer it, then 2 weeks later ask them to explain it to you
// Mentoring activities (pick 2-3 with specific outcomes):
// 1. Pair testing: "Improved junior SDET's bug report quality,
//                   acceptance rate went from 50% to 90%"
// 2. Framework training: "Created 3-session workshop,
//                          2 juniors independently built page objects after"
// 3. PR reviews: "Detailed review comments, junior started catching
//                 their own XPath fragility issues after 4 reviews"
// 4. Study group: "Ran weekly Java deep-dive, whole team passed
//                  ISTQB Foundation in Q3"
💡 Quantify mentoring impact: "After 3 pairing sessions, she independently debugged a complex Selenium synchronization issue." This shows your mentoring was effective, not just well-intentioned.
Q9 Describe a process improvement you initiated that had a measurable impact on quality.
Hard · Process Improvement · Google Googliness
Example: "Our team had no standard for writing test cases — every SDET used a different format, making it impossible to review or maintain each other's work. I noticed this was causing 2x re-work when someone was on leave and another SDET had to run their tests.\n\nI created a 'Test Case Standard' document: title format, preconditions, steps in Given/When/Then, expected results with specific assertions, and test data requirements. I ran a 1-hour workshop and made it the standard for PR reviews.\n\nResult: 30% reduction in test review cycle time. Cross-team coverage (when someone was on leave) went from 'basically impossible' to functional in 2 months. The standard was adopted by 2 other QA teams."
// Process improvement template:
// PROBLEM: specific pain point with data
// "It took 40 min to understand someone else's test case"
// ROOT CAUSE: why is it happening?
// "No standard format, everyone writes differently"
// SOLUTION: what specifically you built/changed
// ADOPTION: how you got others to follow it
// RESULT: measurable improvement (time, quality, velocity)

// Key: "I initiated" not "I suggested"
// Show you drove it to completion, not just proposed
💡 Google values engineers who improve the system around them. Process improvements show you're thinking about the team's velocity, not just your own.
Q10 How do you prioritize when you have too much on your plate and competing deadlines?
Medium · Work-Life Balance · Google Culture
Framework: Explicit prioritization + early communication + ruthless trade-off making.\n\nMy approach:\n1. Write down ALL commitments with deadlines\n2. Classify each: customer/quality impact vs internal work\n3. Communicate early if something will slip: "I can deliver A by Friday and B by next Tuesday. Which is more critical?" — never miss a deadline silently\n4. Say no with data: "If I take task X, task Y will slip by 3 days — is that acceptable?"\n5. Batch context-switching: focus on one project for 2-hour blocks rather than multitasking across 5\n\nKey principle: Prioritization is a communication skill as much as a planning skill. The biggest mistakes come from making prioritization decisions in isolation.
// Prioritization framework:
// P1: Customer/quality impact, deadline TODAY
// P2: Customer/quality impact, deadline THIS WEEK
// P3: Important but deadline flexible
// P4: Nice to have

// "Urgent important" matrix:
// High impact + high urgency → do now
// High impact + low urgency → schedule block
// Low impact + high urgency → delegate or quick-fix
// Low impact + low urgency → decline or backlog

// Communication rule: raise a capacity concern
// when it's still 3 days early, not 1 hour before deadline
💡 Google values transparency. "I communicated early that something would slip" is far better than "I worked 80 hours to deliver everything." Sustainable pace is part of Google's culture.
Advertisement
🪟

Microsoft Interview Process

FAANG · Azure · Office · Teams · Redmond USA · 4–5 Rounds

📋 Phone Screen → Technical ×2 → Design → As-Appropriate🎯 SDET · SDE-T · QA Lead📍 Hyderabad · Bangalore

☕ Technical Round 1

Microsoft technical rounds for SDET focus on Java OOP design quality, SOLID principles, and clean code. They care about code readability and maintainability as much as correctness. Expect "write a mini-system" style questions.

Q1 Design a parking lot system. Walk through the class hierarchy and key methods.
Hard · OOP Design · Microsoft SDET Round
Classes: ParkingLot (manages floors), ParkingFloor (has spots), ParkingSpot (abstract), CompactSpot/LargeSpot/MotorbikeSpot (concrete). Ticket: ParkingTicket with entryTime, spotNumber. FeeCalculator: strategy pattern for different pricing models.
public abstract class ParkingSpot {
    protected String id; protected boolean isOccupied;
    public abstract VehicleType getType();
    public boolean canFit(Vehicle v) { return v.getType() == getType(); }
    public void park(Vehicle v) { isOccupied = true; }
    public void unpark() { isOccupied = false; }
}
public class ParkingFloor {
    private List<ParkingSpot> spots;
    public Optional<ParkingSpot> findAvailableSpot(Vehicle v) {
        return spots.stream()
            .filter(s -> !s.isOccupied && s.canFit(v)).findFirst();
    }
}
public class ParkingLot {
    private List<ParkingFloor> floors;
    private Map<String, ParkingTicket> tickets = new HashMap<>();
    public ParkingTicket park(Vehicle v) {
        for (ParkingFloor f : floors) {
            Optional<ParkingSpot> spot = f.findAvailableSpot(v);
            if (spot.isPresent()) {
                spot.get().park(v);
                ParkingTicket t = new ParkingTicket(spot.get().id);
                tickets.put(t.id, t); return t;
            }
        }
        throw new ParkingFullException("No available spot");
    }
}
💡 Microsoft specifically evaluates SOLID principles. Mention: Open/Closed (new spot type without changing ParkingLot), Dependency Inversion (FeeCalculator interface), Single Responsibility.
Q2 Explain and implement the Singleton pattern. When would you use it in a test framework?
Medium · Design Patterns · Microsoft Round
Singleton ensures only one instance exists. In test frameworks: DriverManager, ConfigReader, ReportManager — things that should be shared across all tests.
// Thread-safe Singleton (double-checked locking)
public class ConfigReader {
    private static volatile ConfigReader instance;
    private Properties props;
    private ConfigReader() {
        props = new Properties();
        try { props.load(getClass().getResourceAsStream("/config.properties")); }
        catch (IOException e) { throw new RuntimeException(e); }
    }
    public static ConfigReader getInstance() {
        if (instance == null) {
            synchronized (ConfigReader.class) {
                if (instance == null) instance = new ConfigReader();
            }
        }
        return instance;
    }
    public String get(String key) { return props.getProperty(key); }
}
// Usage: ConfigReader.getInstance().get("base.url")
💡 Microsoft often asks: "What are the drawbacks of Singleton?" Answer: hard to unit test (can't inject mock), tight coupling, global state issues. Show you know the trade-offs.
Q3 How do you implement the Factory pattern for cross-browser WebDriver creation?
Hard · Framework Architecture · Microsoft SDET
Factory pattern creates objects without exposing creation logic. DriverFactory decides which WebDriver to instantiate based on config.
public class DriverFactory {
    public static WebDriver createDriver(String browser) {
        return switch (browser.toLowerCase()) {
            case "chrome"  -> { ChromeOptions o  = new ChromeOptions();
                               o.addArguments("--headless=new");
                               yield new ChromeDriver(o); }
            case "firefox" -> { FirefoxOptions o = new FirefoxOptions();
                               o.addArguments("-headless");
                               yield new FirefoxDriver(o); }
            case "edge"    -> new EdgeDriver();
            case "remote"  -> {
                String gridUrl = ConfigReader.getInstance().get("grid.url");
                ChromeOptions o = new ChromeOptions();
                yield new RemoteWebDriver(new URL(gridUrl), o);
            }
            default -> throw new IllegalArgumentException("Unknown browser: "+browser);
        };
    }
}
// Usage: WebDriver d = DriverFactory.createDriver(System.getProperty("browser","chrome"));
💡 Microsoft appreciates when you mention: "I would add a browser version parameter and use WebDriverManager to auto-download matching drivers." Shows awareness of real-world maintenance.
Q4 How do you build a robust custom exception hierarchy for a test automation framework?
Medium · Exception Handling · Microsoft Technical
Create a domain-specific exception hierarchy so callers know exactly what went wrong and can handle exceptions appropriately.
// Root exception for framework
public class AutomationException extends RuntimeException {
    private final ErrorCode code;
    public AutomationException(ErrorCode code, String msg) { super(msg); this.code=code; }
    public AutomationException(ErrorCode code, String msg, Throwable cause) {
        super(msg, cause); this.code=code;
    }
    public ErrorCode getCode() { return code; }
}
public enum ErrorCode { ELEMENT_NOT_FOUND, PAGE_LOAD_TIMEOUT, API_ERROR, DATA_ERROR }

// Specific exceptions
public class ElementNotFoundException extends AutomationException {
    public ElementNotFoundException(By locator) {
        super(ErrorCode.ELEMENT_NOT_FOUND,
              "Element not found: " + locator.toString());
    }
}
public class PageLoadTimeoutException extends AutomationException {
    public PageLoadTimeoutException(String page, int timeoutSec) {
        super(ErrorCode.PAGE_LOAD_TIMEOUT,
              page + " did not load within " + timeoutSec + "s");
    }
}
// In BasePage:
protected WebElement findElement(By by) {
    try { return wait.until(ExpectedConditions.visibilityOfElementLocated(by)); }
    catch (TimeoutException e) { throw new ElementNotFoundException(by); }
}
💡 Custom exceptions improve test reports — instead of "TimeoutException at line 247" you get "ElementNotFoundException: Login button not found." Much easier to diagnose failures in CI reports.
Q5 How would you refactor a God class TestHelper with 50 methods into well-designed classes?
Medium · SOLID Principles · Microsoft Design Round
Apply Single Responsibility Principle. Group methods by their concern/responsibility.
// Before: God class (anti-pattern)
public class TestHelper {
    public WebElement waitForElement(By by) {...}
    public void clickElement(By by) {...}
    public void scrollToElement(WebElement el) {...}
    // ... 47 more mixed methods
    public String readExcel(String file, int row) {...}
    public void logTestStart(String name) {...}
    public String getApiToken() {...}
    public Response sendApiRequest(String url) {...}
}

// After: Single Responsibility (each class does ONE thing)
public class ElementActions {          // UI interactions only
    public void click(By by) {...}
    public void type(By by, String text) {...}
    public WebElement waitFor(By by) {...}
}
public class BrowserUtils {            // browser-level operations
    public void scrollTo(WebElement el) {...}
    public void switchToFrame(By by) {...}
    public byte[] takeScreenshot() {...}
}
public class ExcelReader {             // data utilities only
    public String readCell(String file, int row, int col) {...}
    public Object[][] readSheet(String file) {...}
}
public class ApiClient {               // API calls only
    public Response get(String endpoint) {...}
    public Response post(String endpoint, Object body) {...}
}
💡 Microsoft senior roles require architectural thinking. Show you can identify bad patterns (God class, Feature Envy) and refactor to SOLID. This is a differentiator for senior positions.
Q6 Design a test reporting interface that supports Allure, ExtentReports, and custom HTML reports interchangeably.
Hard · Interface Design · Microsoft Architecture
Use Strategy + Adapter pattern. Define a ReportStrategy interface. Each reporter implements it. Tests call the interface, not the concrete class.
// Strategy interface
public interface ReportStrategy {
    void startTest(String name, String description);
    void logStep(String stepName, boolean passed);
    void attachScreenshot(byte[] screenshot);
    void endTest(boolean passed);
    void generateReport();
}

// Allure implementation
public class AllureReporter implements ReportStrategy {
    @Override
    public void startTest(String name, String description) {
        Allure.description(description);
    }
    @Override @Attachment(value="Screenshot", type="image/png")
    public void attachScreenshot(byte[] img) { ... }
    // ...
}

// Extent implementation
public class ExtentReporter implements ReportStrategy {
    private ExtentTest test;
    @Override
    public void startTest(String name, String description) {
        test = ExtentReports.getInstance().createTest(name, description);
    }
    // ...
}

// Factory to select reporter
public class ReportFactory {
    public static ReportStrategy create() {
        return switch(Config.get("reporter")) {
            case "allure"  -> new AllureReporter();
            case "extent"  -> new ExtentReporter();
            default        -> new HtmlReporter();
        };
    }
}
💡 Microsoft interviewers deeply appreciate when you name the patterns used: "This is Strategy pattern for interchangeable reporters, and Factory to select the implementation." Naming patterns shows design vocabulary.
Q7 How do you implement a generic page object factory that can create any page type?
Medium · Generics · Microsoft Java Round
Use Java Generics + Reflection to create a type-safe PageFactory that can instantiate any page class.
public class PageFactory {
    private WebDriver driver;
    public PageFactory(WebDriver driver) { this.driver = driver; }

    public <T extends BasePage> T create(Class<T> pageClass) {
        try {
            T page = pageClass.getDeclaredConstructor(WebDriver.class)
                               .newInstance(driver);
            org.openqa.selenium.support.PageFactory.initElements(driver, page);
            return page;
        } catch (Exception e) {
            throw new AutomationException(ErrorCode.PAGE_INIT_FAILED,
                "Could not create page: " + pageClass.getSimpleName(), e);
        }
    }
}
// Usage (type-safe, no casting needed):
PageFactory factory = new PageFactory(driver);
LoginPage login    = factory.create(LoginPage.class);
DashboardPage dash = factory.create(DashboardPage.class);

// Fluent builder chain:
factory.create(LoginPage.class)
       .enterEmail("user@test.com")
       .enterPassword("pass")
       .clickLogin()
       .verifyDashboardVisible();
💡 Generics eliminate type casting errors at runtime. Microsoft evaluates Java generics deeply — show you understand bounded wildcards, type erasure, and why raw types are dangerous.
Q8 How do you ensure thread safety when writing to a shared test result collection from parallel tests?
Medium · Multithreading · Microsoft Concurrency
Use ConcurrentHashMap and CopyOnWriteArrayList or synchronized blocks for thread-safe result collection.
// Thread-safe result collection for parallel tests
public class TestResultCollector {
    // ConcurrentHashMap: thread-safe reads/writes per key
    private final Map<String, TestResult> results = new ConcurrentHashMap<>();
    // CopyOnWriteArrayList: thread-safe iteration even during writes
    private final List<String> failedTests = new CopyOnWriteArrayList<>();

    public void recordResult(String testId, boolean passed, long durationMs) {
        results.put(testId, new TestResult(testId, passed, durationMs));
        if (!passed) failedTests.add(testId);
    }

    public void printSummary() {
        int total   = results.size();
        int passed  = (int) results.values().stream().filter(r->r.passed).count();
        int failed  = failedTests.size();
        double rate = (double) passed / total * 100;
        System.out.printf("Total: %d | Passed: %d | Failed: %d | Rate: %.1f%%",
            total, passed, failed, rate);
    }
}
// AtomicInteger for thread-safe counters
private final AtomicInteger passCount = new AtomicInteger(0);
// passCount.incrementAndGet(); // thread-safe increment
💡 Avoid synchronized on the entire method — it creates a bottleneck. ConcurrentHashMap and AtomicInteger allow lock-free operations in most cases, which is critical for parallel test performance.
Q9 Implement the Builder pattern for creating complex test data objects.
Hard · Test Data Builder · Microsoft Design Pattern
Builder pattern creates objects step-by-step without a telescoping constructor. Perfect for test data objects with many optional fields.
public class UserTestData {
    private final String email, password, firstName, lastName, role;
    private final boolean isVerified, isActive;
    private final String phoneNumber, address;

    private UserTestData(Builder b) {
        this.email       = b.email;       this.password  = b.password;
        this.firstName   = b.firstName;   this.lastName  = b.lastName;
        this.role        = b.role;        this.isVerified= b.isVerified;
        this.isActive    = b.isActive;
        this.phoneNumber = b.phoneNumber; this.address   = b.address;
    }

    public static class Builder {
        // Required fields
        private String email, password;
        // Optional fields with defaults
        private String firstName="Test", lastName="User", role="USER";
        private boolean isVerified=true, isActive=true;
        private String phoneNumber, address;

        public Builder(String email, String password) {
            this.email=email; this.password=password;
        }
        public Builder role(String r) { this.role=r; return this; }
        public Builder verified(boolean v) { isVerified=v; return this; }
        public Builder phone(String p) { this.phoneNumber=p; return this; }
        public UserTestData build() { return new UserTestData(this); }
    }
}
// Usage:
UserTestData admin = new UserTestData.Builder("a@t.com","pass")
    .role("ADMIN").verified(true).phone("9999999999").build();
UserTestData unverified = new UserTestData.Builder("b@t.com","pass")
    .verified(false).build();
💡 Builder pattern is the most commonly asked design pattern in Microsoft SDET interviews. Know it cold — both implementation and when to use it (objects with many optional fields, immutable objects).
Q10 How does the Interface Segregation Principle apply to test automation framework design?
Medium · Interface Segregation · Microsoft SOLID
ISP: Clients should not depend on interfaces they don't use. Split large interfaces into focused ones. Each page type implements only the interfaces relevant to it.
// Before ISP violation: one large interface
interface IPage {
    void clickElement(By by);     // all pages need
    void fillForm(Map data);      // only form pages need
    void verifyChart(String id);  // only dashboard pages need
    void uploadFile(By by, String path); // only upload pages need
}

// After ISP: focused interfaces
interface IClickable   { void click(By by); void hover(By by); }
interface IFormFillable{ void fill(Map<String,String> data); void submit(); }
interface IVerifiable  { boolean isVisible(By by); String getText(By by); }
interface IFileUploader{ void upload(By by, String filePath); }

// Each page implements only what it needs:
class LoginPage extends BasePage implements IClickable, IFormFillable {
    // No uploadFile or verifyChart methods imposed
}
class UploadPage extends BasePage implements IClickable, IFileUploader {
    // No fillForm methods imposed
}
class DashboardPage extends BasePage implements IVerifiable, IClickable {
    // All analytics-specific methods only
}
💡 ISP reduces the "fat interface" problem. Microsoft asks this to see if you understand the practical impact: smaller interfaces = fewer breaking changes when interface evolves.

🏗️ Design Round

Microsoft Design round: design testing strategy for a Microsoft product (Teams, Azure, Office, Xbox). They evaluate your ability to think at system scale, identify risk, and design for observability. Always start: "Let me clarify the scope."

Q1 Design an end-to-end test strategy for Microsoft Teams message delivery feature.
Hard · Feature Test Strategy · Microsoft Design Round
Critical Path: Sender types message → message delivered to recipient in real-time → notifications fire → message persists in history.\n\nTest Layers:\n• Unit: Message formatting, encoding, size limits\n• Integration: Chat service → notification service → push service\n• E2E: Full send-receive via Selenium/Playwright\n\nEdge Cases:\n• Message with 10,000 characters\n• Unicode (emoji, RTL text, Chinese)\n• Offline recipient — message queued and delivered on reconnect\n• Group chat with 250 participants\n• Message edit and delete sync across all members\n\nPerformance:\n• Message delivery < 300ms (p99)\n• 1M concurrent users
// Test Design for Teams message delivery:
// Risk 1: Message not delivered (HIGH) → E2E delivery verification
// Risk 2: Message order wrong (HIGH) → timestamp ordering tests
// Risk 3: Message not encrypted (CRITICAL) → security tests
// Risk 4: Mentions/notifications fail (MEDIUM) → @mention tests
// Risk 5: Offline sync failure (MEDIUM) → reconnect tests
💡 Microsoft interviewers appreciate when you reference specific Teams architecture knowledge. Mention SignalR (real-time messaging), Azure Notification Hubs, and how push notifications work differently on iOS/Android.
Q2 Design a complete CI/CD quality pipeline for a Microsoft Azure microservice with 50 services.
Hard · CI/CD Pipeline Design · Microsoft DevOps
Layer 1 - Code Commit: SAST scan (SonarQube), unit tests, code coverage gate (>80%)\nLayer 2 - Build: Docker image build, Trivy container scan\nLayer 3 - Deploy to Dev: Contract tests (Pact), API smoke tests\nLayer 4 - Deploy to Staging: Full regression, performance baseline check\nLayer 5 - Deploy to Prod: Canary deployment (5% traffic), smoke tests, automated rollback if error rate >1%
// Azure DevOps Pipeline (yaml)
stages:
- stage: Test
  jobs:
  - job: UnitTests
    steps:
    - task: Maven@3
      inputs: { goals: "test jacoco:report", options: "-Dgroups=unit" }
    - task: PublishCodeCoverageResults@1
  - job: ContractTests
    dependsOn: UnitTests
    steps:
    - script: mvn test -Dgroups=contract
  - job: IntegrationTests
    dependsOn: ContractTests
    steps:
    - script: mvn test -Dgroups=integration -Denv=dev
- stage: PerformanceGate
  dependsOn: Test
  jobs:
  - job: PerfBaseline
    steps:
    - script: k6 run --env ENV=staging tests/perf.js
      env: { K6_CLOUD_TOKEN: $(K6_TOKEN) }
💡 Microsoft Azure DevOps is their own CI/CD tool — knowing it specifically (not just Jenkins) shows cultural fit. YAML pipelines are the modern approach over classic pipelines.
Q3 How would you performance test Microsoft Office 365 OneDrive file sync?
Medium · Performance Testing · Microsoft Performance
Scenarios to test:\n• Sync 1,000 files (10MB each) → time to complete full sync\n• Conflict resolution: two users edit same file simultaneously\n• Sync on slow connection: throttle to 1 Mbps\n• Reconnection after offline: 24 hours of changes sync correctly\n\nSLAs:\n• 100MB file upload: <30 seconds on 100Mbps\n• Conflict detection: <5 seconds\n• Incremental sync: 1KB change syncs in <10 seconds\n\nScale tests:\n• 100,000 concurrent users syncing files\n• Simulate Black Friday: 10x normal traffic in 5 minutes
// OneDrive sync performance test approach:
// Use: Microsoft Graph API to upload files programmatically
// Measure: time from API upload to file appearing on sync client
// Tool: k6 for API load, PowerShell for sync client automation

// Key metric: Delta Sync (only changed bytes sent, not full file)
// Test: modify 1 byte in 1GB file
// Expected: only 1KB delta transmitted, not 1GB retransmission
💡 OneDrive uses delta sync — only changed bytes are transmitted. Testing this specifically shows domain depth into Microsoft's products. Impress the interviewer with product knowledge.
Q4 Design a security testing strategy for a Microsoft Azure Active Directory (AAD) authentication service.
Hard · Security Design · Microsoft Security Round
Authentication Tests:\n• Valid credentials → token issued with correct claims\n• Invalid password → 401, account lockout after 5 attempts\n• Expired token → 401, refresh token flow\n• MFA bypass attempt → blocked\n\nAuthorization Tests:\n• Token scope enforcement: read-only token cannot write\n• Cross-tenant access: tenant A cannot access tenant B data\n• Privilege escalation: regular user cannot access admin endpoints\n\nSecurity Scan:\n• OWASP ZAP automated scan on all auth endpoints\n• JWT token: alg:none attack, key confusion\n• SQL injection in login fields\n• Brute force: 100 login attempts/second → rate limited
// AAD Security Test Cases:
@Test public void bruteForce_ShouldLockAfter5Attempts() {
    for (int i = 0; i < 4; i++)
        given().body(invalidCreds).post("/login").then().statusCode(401);
    // 5th attempt → locked
    given().body(invalidCreds).post("/login").then().statusCode(423); // Locked
}
@Test public void crossTenant_ShouldReturn403() {
    String tenantAToken = getToken("tenantA");
    given().header("Authorization", "Bearer " + tenantAToken)
           .get("/tenants/tenantB/users")
           .then().statusCode(403);
}
💡 AAD is Microsoft's most critical security product. Demonstrating you know about tenant isolation, JWT attacks, and MFA shows you can contribute to their security testing team immediately.
Q5 Microsoft products must meet WCAG 2.1 AA standards. How do you build accessibility into your test strategy?
Medium · Accessibility Testing · Microsoft A11y
Microsoft's Accessibility commitment: Every product ships with Accessibility Conformance Report (ACR).\n\nAutomated (35% of issues):\n• Axe-core integrated in Selenium suite\n• Run on every UI page change\n• Lighthouse CI for web products\n\nManual (65% of issues):\n• Keyboard-only navigation test\n• Screen reader testing: NVDA (Windows), VoiceOver (Mac)\n• High-contrast mode visual verification\n• Zoom to 400% — content still functional\n• Color contrast ratio check (4.5:1 minimum)\n\nAssistive Technology:\n• Test with Windows Narrator (Microsoft's own screen reader)\n• Test with Eye Control (Microsoft assistive tech)\n• Test with Switch Access (for motor disabilities)
// Axe-core accessibility test in Selenium
@Test
public void teamsLogin_ShouldPassWCAG_AA() {
    driver.get(TEAMS_URL + "/login");
    JavascriptExecutor js = (JavascriptExecutor) driver;
    js.executeScript(axeScript);
    @SuppressWarnings("unchecked")
    Map<String,Object> res = (Map<String,Object>) js.executeScript(
        "return axe.run({ runOnly: { type: \"tag\", values: [\"wcag2aa\"] } })");
    List violations = (List) res.get("violations");
    Assert.assertEquals(violations.size(), 0,
        "WCAG AA violations: " + violations.size());
}
💡 Microsoft is an industry leader in accessibility (they invented Xbox Adaptive Controller). Showing genuine knowledge of Narrator and accessibility conformance reports demonstrates cultural alignment with Microsoft's mission.
Q6 How do you manage test data for a multi-tenant SaaS application like Microsoft 365?
Medium · Test Data Strategy · Microsoft Data Round
Challenges: Each test needs isolated tenant data, PII must not be used in tests, data must be production-realistic.\n\nStrategy:\n• Synthetic data generation: Faker library creates realistic but fake user data\n• Tenant-per-test: each test creates its own ephemeral tenant via API\n• Data cleanup: @AfterTest deletes created tenant\n• Shared read-only data: reference data (pricing plans, features) shared but immutable\n• Sensitive data: store in Azure Key Vault, never in test code
public class TenantFactory {
    public static TestTenant createEphemeral() {
        String tenantId = "test-" + UUID.randomUUID();
        given()
            .header("Authorization", "Bearer " + getAdminToken())
            .body(Map.of("tenantId", tenantId, "tier", "TRIAL"))
            .post("/admin/tenants")
            .then().statusCode(201);
        return new TestTenant(tenantId);
    }
    public static void cleanup(TestTenant tenant) {
        given()
            .header("Authorization", "Bearer " + getAdminToken())
            .delete("/admin/tenants/" + tenant.id)
            .then().statusCode(204);
    }
}
// In test:
@BeforeMethod  void setUp()    { tenant = TenantFactory.createEphemeral(); }
@AfterMethod   void tearDown() { TenantFactory.cleanup(tenant); }
💡 Ephemeral tenants per test provide complete isolation without complex data cleanup. The API-driven creation/deletion pattern is used by Azure's own test teams.
Q7 How would you implement chaos engineering for Microsoft Azure Storage service?
Hard · Chaos Engineering · Microsoft SRE
Hypotheses to test:\n• If one Azure region goes down, traffic auto-routes to secondary region within 30s\n• If blob storage latency spikes, circuit breaker activates and clients see degraded-but-functional response\n• If 20% of storage nodes fail, data is still accessible (3x replication)\n\nChaos Experiments:\n• Block network to primary region → verify failover to geo-redundant region\n• Inject 2s latency on all storage reads → verify timeout handling + retry\n• Kill primary storage pod → verify replica promotes without data loss\n\nSuccess Criteria:\n• SLA maintained (99.99% availability) during experiment\n• No data loss (zero bytes corrupted)\n• Client applications see graceful degradation, not hard failure
// Azure Chaos Studio experiment (JSON config)
{
  "steps": [{
    "name": "Step1-RegionFailover",
    "branches": [{
      "name": "Kill primary region network",
      "actions": [{
        "type": "continuous",
        "name": "NSFW-1",
        "duration": "PT10M",
        "parameters": { "virtualMachineScaleSetId": "/subscriptions/.../vmss" }
      }]
    }]
  }],
  "startOnCreation": false
}
// Monitor: Azure Monitor alerts + custom SLA dashboard
// Abort condition: error rate > 1% triggers auto-stop
💡 Azure has its own Chaos Studio product. Knowing it by name shows you follow Microsoft-specific tooling, which is a green flag for Microsoft interviewers.
Q8 How do you prevent breaking changes in APIs across 50 Azure microservices using contract testing?
Medium · Contract Testing · Microsoft Microservices
Pact Contract Testing: Consumer teams define what they expect from APIs (consumer contract). Provider teams verify their API meets all consumer contracts before deployment.\n\nProcess:\n1. Consumer team adds test: "I expect /users/{id} to return {id, email, name}"\n2. Pact generates contract file\n3. Contract published to PactBroker\n4. Provider pipeline verifies: "Do I still satisfy all my consumers?"\n5. If NO → deployment blocked\n\nResult: 50 services can deploy independently without a shared integration environment.
// Provider verification in CI pipeline
@Provider("UserService")
@PactBroker(host="pactbroker.company.com",
            authentication=@PactBrokerAuth(token="${PACT_TOKEN}"))
@ExtendWith(PactVerificationInvocationContextProvider.class)
public class UserServiceProviderTest {
    @TestTemplate
    @ExtendWith(PactVerificationInvocationContextProvider.class)
    void verifyPact(PactVerificationContext context) {
        context.verifyInteraction();
    }
    @BeforeEach
    void setUp(PactVerificationContext context) {
        context.setTarget(new HttpTestTarget(
            testServer.getHost(), testServer.getPort()));
    }
    // State setup for each consumer expectation
    @State("user 123 exists")
    public void userExists() {
        userRepo.save(new User("123", "test@email.com", "Test User"));
    }
}
💡 Microsoft uses contract testing heavily for Azure API backward compatibility. Demonstrating Pact knowledge for the provider side (not just consumer) shows advanced API testing maturity.
Q9 How do you implement test observability — knowing not just that a test failed, but WHY?
Medium · Observability · Microsoft SRE Round
Standard failure: "NullPointerException at line 247" → useless.\nObservable failure: "LoginTest failed: Expected URL /dashboard but got /login. Screenshot: attached. Network request log: POST /auth returned 401. Headers: X-Request-ID: abc123. Timestamp: 14:23:47 UTC. Browser: Chrome 121. Environment: staging-us-east"\n\nObservability stack:\n• Screenshots on every step (not just failure)\n• Network logs (selenium DevTools CDP)\n• Browser console logs\n• Correlation ID injected in every test request\n• Structured logs (JSON) for easy parsing\n• Allure report with attachments per step
// Rich test observability in BaseTest
public class BaseTest {
    @BeforeMethod
    public void enableObservability() {
        driver.executeCdpCommand("Network.enable", Map.of());
        driver.executeCdpCommand("Console.enable", Map.of());
        networkLogs = new ArrayList<>();
        // Capture every network request
        driver.addDevToolsEventListener("Network.requestWillBeSent",
            e -> networkLogs.add(e.get("request")));
    }
    @AfterMethod(alwaysRun = true)
    public void collectDiagnostics(ITestResult result) {
        if (!result.isSuccess()) {
            Allure.addAttachment("Screenshot", "image/png",
                new ByteArrayInputStream(takeScreenshot()), "png");
            Allure.addAttachment("NetworkLog", "text/json",
                networkLogs.toString());
            Allure.addAttachment("BrowserConsole", "text/plain",
                getBrowserLogs());
        }
    }
}
💡 Test observability is the difference between a 30-minute debugging session and 2 days. Microsoft values engineers who invest in diagnostic tooling that saves the whole team time.
Q10 Write a one-page test strategy for a new Microsoft Surface Duo feature (dual-screen folding Android phone).
Hard · Test Strategy Document · Microsoft QA Lead
Feature scope: App continuation between screens when unfolded\n\nUnique test scenarios:\n• App visible on single screen → unfold → app spans both screens correctly\n• App on screen 1 → drag to screen 2 → position preserved\n• System dialog (camera permission) appears correctly on both orientations\n\nHinge tests:\n• Hinge angle: 0° (closed), 90°, 180° (flat), 360° (tent mode)\n• App behavior at each angle\n\nPerformance:\n• Screen transition <200ms lag\n• No frame drops during unfold animation\n\nCompatibility:\n• All pre-installed Microsoft apps work correctly\n• Third-party apps that don't support dual-screen don't crash
// Surface Duo specific test tooling:
// Microsoft Surface Duo Emulator (available in Android Studio)
// SurfaceDuoHelper API:
// isDualScreenMode() → boolean
// getHingeAngle() → 0-360
// getSpannedRect() → left+right screen bounds

// Appium dual-screen automation:
// Use Microsoft Windows Application Driver (WinAppDriver)
// Extended with SurfaceDuo specific capabilities
// "microsoft:surfaceHingeAngle": 90 // 90 degree hinge
💡 Mentioning product-specific tools (Surface Duo Emulator, WinAppDriver) shows you research the company's actual tech stack before the interview. This is a major differentiator at Microsoft.
🛒

Flipkart Interview Process

Indian Product · E-Commerce · Walmart-owned · Bangalore HQ · 4–5 Rounds

📋 Coding Test → Technical ×2 → HM Round → HR🎯 SDET I/II · QA Lead📍 Bangalore · Remote

💻 Coding Test (HackerEarth)

Flipkart's OA is 90 minutes with 2–3 coding problems. Strong Java skills required. They read code for QUALITY not just correctness. Write clean, well-named variables and include edge case handling.

Q1 Group all anagrams from a list of strings together.
Medium · HashMap + Sorting · Flipkart OA 2024
Sort each string → use as HashMap key. Anagrams produce identical sorted strings.
public List<List<String>> groupAnagrams(String[] strs) {
    Map<String,List<String>> map = new HashMap<>();
    for (String s : strs) {
        char[] c = s.toCharArray(); Arrays.sort(c);
        map.computeIfAbsent(new String(c), k->new ArrayList<>()).add(s);
    }
    return new ArrayList<>(map.values());
}
// ["eat","tea","tan","ate","nat","bat"]
// → [["eat","tea","ate"],["tan","nat"],["bat"]]
💡 Flipkart evaluates Java code quality. Use computeIfAbsent instead of manual null-check — shows modern Java knowledge.
Q2 Given a string, find the first non-repeating character and return its index.
Easy · String · Flipkart OA
Two passes: count frequencies with int[26] array, then find first with count==1.
public int firstUniqChar(String s) {
    int[] freq = new int[26];
    for (char c : s.toCharArray()) freq[c-"a"]++;
    for (int i = 0; i < s.length(); i++)
        if (freq[s.charAt(i)-"a"] == 1) return i;
    return -1;
}
// "leetcode"→0  "loveleetcode"→2  "aabb"→-1
💡 Using int[26] instead of HashMap is O(1) space. Always mention this optimization.
Q3 Generate all permutations of a given string.
Medium · Recursion · Flipkart OA 2023
Backtracking: swap character at each position with every character from that position onward, recurse, then swap back.
public List<String> permutations(String s) {
    List<String> result = new ArrayList<>();
    char[] arr = s.toCharArray();
    permute(arr, 0, result);
    return result;
}
private void permute(char[] arr, int start, List<String> res) {
    if (start == arr.length) { res.add(new String(arr)); return; }
    for (int i = start; i < arr.length; i++) {
        swap(arr, start, i);
        permute(arr, start+1, res);
        swap(arr, start, i);  // backtrack
    }
}
private void swap(char[] a, int i, int j) { char t=a[i]; a[i]=a[j]; a[j]=t; }
// "abc" → ["abc","acb","bac","bca","cab","cba"]
💡 Permutations = n! results. For n=8, that's 40,320 permutations. Always state time complexity. Flipkart appreciates when you preemptively mention scalability limits.
Q4 Find the maximum product of two integers in an array.
Easy · Array · Flipkart OA
Sort the array. The max product is either the two largest positives or two most negative numbers (product of two negatives is positive).
public int maxProduct(int[] nums) {
    Arrays.sort(nums);
    int n = nums.length;
    // Compare: product of two largest vs two most negative
    return Math.max(nums[n-1]*nums[n-2], nums[0]*nums[1]);
}
// [-4,-3,2,6] → 12  ((-4)*(-3))
// [1,2,3,4]   → 12  (3*4)
💡 Don't forget the negative×negative case! This catches most candidates. Always think about negative numbers in product problems.
Q5 Evaluate a Reverse Polish Notation (RPN) expression: ["2","1","+","3","*"] = 9.
Medium · Stack · Flipkart OA
Use a stack. Push numbers. When operator found, pop two operands, compute, push result.
public int evalRPN(String[] tokens) {
    Deque<Integer> stack = new ArrayDeque<>();
    for (String t : tokens) {
        switch(t) {
            case "+" -> stack.push(stack.pop() + stack.pop());
            case "-" -> { int b=stack.pop(),a=stack.pop(); stack.push(a-b); }
            case "*" -> stack.push(stack.pop() * stack.pop());
            case "/" -> { int b=stack.pop(),a=stack.pop(); stack.push(a/b); }
            default  -> stack.push(Integer.parseInt(t));
        }
    }
    return stack.pop();
}
// ["2","1","+","3","*"] → 9  (2+1=3, 3*3=9)
💡 Note the subtraction and division order: b=pop first (second operand), a=pop second (first operand). Easy to get wrong — mention this explicitly.
Q6 Find the minimum element in a sorted rotated array.
Medium · Binary Search · Flipkart OA 2024
Binary search. The minimum is in the unsorted half. If nums[mid] > nums[hi], minimum is in right half. Otherwise left half.
public int findMin(int[] nums) {
    int lo = 0, hi = nums.length - 1;
    while (lo < hi) {
        int mid = lo + (hi - lo) / 2;
        if (nums[mid] > nums[hi]) lo = mid + 1;  // min in right
        else hi = mid;                             // min in left (or is mid)
    }
    return nums[lo];
}
// [3,4,5,1,2] → 1  [4,5,6,7,0,1,2] → 0  [1] → 1
💡 Use nums[hi] as reference, not nums[lo]. Comparing with hi avoids the edge case where the array is not rotated.
Q7 Calculate the power of a number: implement pow(x, n) efficiently.
Easy · Recursion · Flipkart OA
Fast exponentiation: if n is even, pow(x,n) = pow(x*x, n/2). Halves the problem each time → O(log n).
public double myPow(double x, int n) {
    long N = n;  // handle Integer.MIN_VALUE
    if (N < 0) { x = 1/x; N = -N; }
    double result = 1.0;
    while (N > 0) {
        if (N % 2 == 1) result *= x;
        x *= x;
        N /= 2;
    }
    return result;
}
// 2.0^10=1024.0  2.0^-2=0.25  0^0=1
💡 Key: use long N to handle Integer.MIN_VALUE edge case (-2^31 negated overflows int). Flipkart interviewers specifically check for this overflow handling.
Q8 Given a 2D grid, find the number of unique paths from top-left to bottom-right (only down and right moves).
Medium · Dynamic Programming · Flipkart OA
DP: dp[i][j] = dp[i-1][j] + dp[i][j-1]. First row and column are all 1s.
public int uniquePaths(int m, int n) {
    int[][] dp = new int[m][n];
    // First row and column: only one way to reach
    for (int i=0;i<m;i++) dp[i][0]=1;
    for (int j=0;j<n;j++) dp[0][j]=1;
    for (int i=1;i<m;i++)
        for (int j=1;j<n;j++)
            dp[i][j] = dp[i-1][j] + dp[i][j-1];
    return dp[m-1][n-1];
}
// 3x7 grid → 28 unique paths

// O(1) space solution: C(m+n-2, m-1) combinations formula
💡 Mention the math formula O(1) space solution. It's impressive: C(m+n-2, m-1). Flipkart evaluates mathematical thinking for senior SDET roles.
Q9 Given a binary tree, find the lowest common ancestor (LCA) of two given nodes.
Hard · Trees · Flipkart OA 2023
Recursively search both subtrees. If current node is either p or q, return it. If both left and right return non-null, current node is LCA.
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    if (root == null || root == p || root == q) return root;
    TreeNode left  = lowestCommonAncestor(root.left,  p, q);
    TreeNode right = lowestCommonAncestor(root.right, p, q);
    if (left != null && right != null) return root;  // LCA found
    return left != null ? left : right;
}
// If both found in different subtrees → root is LCA
// If one is null → LCA is in the non-null subtree
💡 LCA is a classic tree problem. The key insight: if both left and right return non-null, we've found the split point = LCA. Elegantly expressed in 8 lines.
Q10 Given a list of course prerequisites, determine if you can finish all courses (no circular dependency).
Hard · Graph · Flipkart OA 2024
Model as directed graph. Topological sort using DFS — if cycle detected, cannot finish all courses.
public boolean canFinish(int numCourses, int[][] prerequisites) {
    List<List<Integer>> adj = new ArrayList<>();
    for (int i=0;i<numCourses;i++) adj.add(new ArrayList<>());
    for (int[] p : prerequisites) adj.get(p[1]).add(p[0]);

    int[] visited = new int[numCourses]; // 0=unvisited 1=visiting 2=done
    for (int i=0;i<numCourses;i++)
        if (visited[i]==0 && hasCycle(adj, visited, i)) return false;
    return true;
}
private boolean hasCycle(List<List<Integer>> adj, int[] vis, int node) {
    vis[node] = 1;  // currently visiting
    for (int next : adj.get(node)) {
        if (vis[next]==1) return true;   // back edge = cycle
        if (vis[next]==0 && hasCycle(adj, vis, next)) return true;
    }
    vis[node] = 2;  // done
    return false;
}
// [[1,0],[0,1]] → false (cycle: 0→1→0)  [[1,0]] → true
💡 This is a cycle detection problem disguised as a scheduling problem. The 3-state visited array (0=unvisited, 1=in-stack, 2=done) is the key to detecting back edges efficiently.

🔬 Technical Round 1

Flipkart Tech Round 1 goes deep on Java OOP, Selenium internals, and your actual framework. The interviewer reads your resume and asks specifics about every project you mention. Be ready to justify every design decision.

Q1 Design and implement a complete Page Object Model framework for Flipkart checkout.
Hard · POM Framework · Flipkart SDET 2024
BasePage with driver, wait, PageFactory. Each checkout step is a separate page class. Use builder pattern for test data. Parallel execution via ThreadLocal.
// BasePage.java
public class BasePage {
    protected WebDriver driver;
    protected WebDriverWait wait;
    public BasePage(WebDriver d) {
        this.driver=d; this.wait=new WebDriverWait(d, Duration.ofSeconds(15));
        PageFactory.initElements(d, this);
    }
    protected void click(By by) {
        wait.until(ExpectedConditions.elementToBeClickable(by)).click();
    }
    protected String getText(By by) {
        return wait.until(ExpectedConditions.visibilityOfElementLocated(by)).getText();
    }
}
// CartPage.java
public class CartPage extends BasePage {
    @FindBy(css=".cart-item") private List<WebElement> items;
    @FindBy(id="proceed-to-buy") private WebElement proceedBtn;
    public CartPage(WebDriver d) { super(d); }
    public int getItemCount() { return items.size(); }
    public CheckoutPage proceedToBuy() { proceedBtn.click(); return new CheckoutPage(driver); }
}
💡 Flipkart specifically asks: "What happens if the DOM changes and your locators break?" Answer: CSS selectors tied to semantic attributes (data-testid) are more stable than visual class names.
Q2 Implement thread-safe parallel Selenium execution. Show the complete DriverFactory with ThreadLocal.
Hard · Parallel Execution · Flipkart SDET
ThreadLocal ensures each thread has its own WebDriver. CRITICAL: always call remove() in teardown to prevent memory leak.
public class DriverFactory {
    private static final ThreadLocal<WebDriver> pool = new ThreadLocal<>();
    public static WebDriver get() { return pool.get(); }
    public static void init(String browser) {
        WebDriver d = switch(browser) {
            case "firefox" -> new FirefoxDriver();
            default -> { ChromeOptions o=new ChromeOptions();
                         o.addArguments("--headless=new","--no-sandbox");
                         yield new ChromeDriver(o); }
        };
        d.manage().window().maximize();
        pool.set(d);
    }
    public static void quit() {
        if (pool.get()!=null) { pool.get().quit(); pool.remove(); } // CRITICAL
    }
}
💡 Flipkart is very specific about the memory leak: pool.remove() MUST be called in teardown. "I've seen production CI pipelines crash after 2 hours because developers forgot this" — saying this impresses interviewers.
Q3 Write dynamic XPath to find product cards on Flipkart search results page.
Medium · XPath · Flipkart Tech Screen
Use relative XPath with contains(), starts-with(), and attribute combinations for dynamic elements.
// Product card by title containing text
By.xpath("//div[contains(@class,\"_1AtVbE\")]//a[contains(text(),\"iPhone\")]")

// Product card by position (3rd result)
By.xpath("(//div[@data-id and contains(@class,\"_13oc-S\")])[3]")

// Product price using sibling navigation
By.xpath("//div[contains(text(),\"iPhone\")]/../../..//div[@class=\"_30jeq3\"]")

// Better - use data attributes (more stable):
By.cssSelector("[data-id][data-tkid]")

// Dynamic attribute with partial match:
By.xpath("//button[contains(@class,\"_2KpZ6l\") and @type=\"button\"]")

// Text contains partial match:
By.xpath("//*[contains(translate(text(),\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\",\"abcdefghijklmnopqrstuvwxyz\"),\"add to cart\")]")
💡 For production automation, ALWAYS prefer data-testid or data-qa attributes over CSS class names — class names change with redesigns, but semantic test attributes are stable by convention.
Q4 How do you handle AJAX/dynamic content loading in Selenium tests?
Medium · Synchronization · Flipkart QA
Use explicit waits with appropriate ExpectedConditions. For React/Angular single-page apps, wait for network idle.
// Wait for AJAX to complete (jQuery approach)
public void waitForAjax() {
    wait.until(d -> ((JavascriptExecutor)d)
        .executeScript("return jQuery.active==0").equals(true));
}
// Wait for network idle via CDP (Selenium 4)
public void waitForNetworkIdle() {
    Map<String,Object> params = new HashMap<>();
    params.put("timeout", 10000);
    driver.executeCdpCommand("Page.waitForNetworkIdle", params);
}
// Wait for Angular app ready
public void waitForAngular() {
    String angularReady = "return window.getAllAngularTestabilities()"+
        ".every(t => t.isStable())";
    wait.until(d -> ((JavascriptExecutor)d)
        .executeScript(angularReady).equals(true));
}
// Always prefer: wait for specific element visible
wait.until(ExpectedConditions.visibilityOf(productList));
💡 Flipkart's web app uses React/Next.js. Knowing how to handle React's asynchronous rendering (wait for specific component, not just page load) is a differentiator.
Q5 How do you implement a reusable wait helper that can be configured per environment?
Hard · Test Architecture · Flipkart Framework
Create a configurable WaitHelper that reads timeouts from properties file, allowing different timeouts per environment (dev fast, prod slow).
public class WaitHelper {
    private final WebDriverWait wait;
    private static final int DEFAULT_TIMEOUT =
        Integer.parseInt(Config.get("wait.timeout.seconds", "15"));

    public WaitHelper(WebDriver driver) {
        this(driver, DEFAULT_TIMEOUT);
    }
    public WaitHelper(WebDriver driver, int timeoutSec) {
        this.wait = new WebDriverWait(driver, Duration.ofSeconds(timeoutSec));
    }

    public WebElement forVisible(By by) {
        return wait.until(ExpectedConditions.visibilityOfElementLocated(by));
    }
    public WebElement forClickable(By by) {
        return wait.until(ExpectedConditions.elementToBeClickable(by));
    }
    public boolean forTextPresent(By by, String text) {
        return wait.until(ExpectedConditions.textToBePresentInElementLocated(by, text));
    }
    public void forUrlContains(String urlPart) {
        wait.until(ExpectedConditions.urlContains(urlPart));
    }
}
// config.properties:
// wait.timeout.seconds=15  (staging)
// wait.timeout.seconds=5   (dev - faster machines)
💡 Config-driven timeouts prevent hardcoded values scattered across 500 test files. When CI machines are upgraded and everything runs faster, you change ONE property file instead of 500 tests.
Q6 Implement a full-page screenshot strategy that captures even content below the fold.
Medium · Screenshot · Flipkart SDET
TakesScreenshot captures only visible area. For full-page, scroll and stitch, or use Selenium DevTools CDP full-page capture.
// Method 1: Selenium 4 DevTools (full page)
public byte[] takeFullPageScreenshot() {
    DevTools dt = ((HasDevTools) driver).getDevTools();
    dt.createSession();
    Optional<Page.CaptureScreenshotResponse> resp =
        dt.send(Page.captureScreenshot(
            Optional.of(Page.CaptureScreenshotFormat.PNG),
            Optional.empty(), Optional.empty(),
            Optional.of(true),  // captureBeyondViewport = true
            Optional.empty()));
    return Base64.getDecoder().decode(resp.get().getData());
}

// Method 2: Scroll and stitch (fallback)
public void scrollAndCapture(String filename) throws Exception {
    JavascriptExecutor js = (JavascriptExecutor) driver;
    long totalHeight = (long) js.executeScript("return document.body.scrollHeight");
    long viewHeight  = (long) js.executeScript("return window.innerHeight");
    long scrollY     = 0;
    List<BufferedImage> parts = new ArrayList<>();
    while (scrollY < totalHeight) {
        js.executeScript("window.scrollTo(0," + scrollY + ")");
        Thread.sleep(200); // wait for scroll
        parts.add(ImageIO.read(((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE)));
        scrollY += viewHeight;
    }
    // stitch parts into one image...
}
💡 For Flipkart product pages (very long scroll), full-page screenshots are critical for visual regression testing. CDP approach is cleaner but requires Chrome/Edge with DevTools.
Q7 How do you integrate Allure reports with GitHub Actions and publish them as a GitHub Pages deployment?
Hard · CI Integration · Flipkart DevOps
Allure generates test results in JSON. Post-test, Allure CLI generates HTML report. GitHub Actions uploads to GitHub Pages.
# .github/workflows/test.yml
name: Selenium Tests
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-java@v4
      with: { java-version: "17" }
    - name: Run Tests
      run: mvn test -Dgroups=regression -Dbrowser=chrome
      continue-on-error: true  # collect results even on failure
    - name: Generate Allure Report
      uses: simple-elf/allure-report-action@master
      with:
        allure_results: target/allure-results
        allure_history: allure-history
    - name: Deploy to GitHub Pages
      uses: peaceiris/actions-gh-pages@v3
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        publish_dir: allure-history
    - name: Post PR Comment with Report Link
      uses: actions/github-script@v7
      with:
        script: |
          github.rest.issues.createComment({ issue_number: context.issue.number,
            owner: context.repo.owner, repo: context.repo.repo,
            body: "📊 Allure Report: https://"+context.repo.owner+".github.io/"+context.repo.repo })
💡 Posting the Allure report link as a PR comment is a small but powerful touch. Reviewers can see test results without leaving the PR. Flipkart's CI pipeline uses this pattern.
Q8 Implement a TestNG listener that: captures screenshot on failure, logs test duration, and sends Slack notification on suite completion.
Medium · TestNG Listeners · Flipkart Framework
Implement ITestListener + ISuiteListener. Hook into all lifecycle events.
@SuppressWarnings("unused")
public class QAListener implements ITestListener, ISuiteListener {
    private final Map<String,Long> startTimes = new ConcurrentHashMap<>();

    @Override public void onTestStart(ITestResult r) {
        startTimes.put(r.getName(), System.currentTimeMillis());
        Allure.step("Test started: " + r.getName());
    }

    @Override public void onTestFailure(ITestResult r) {
        // Screenshot attachment
        byte[] screenshot = ((TakesScreenshot)DriverFactory.get())
            .getScreenshotAs(OutputType.BYTES);
        Allure.addAttachment("Failure Screenshot","image/png",
            new ByteArrayInputStream(screenshot), "png");
        // Duration logging
        long duration = System.currentTimeMillis() - startTimes.get(r.getName());
        System.err.printf("[FAIL] %s — %dms%n", r.getName(), duration);
    }

    @Override public void onFinish(ISuite suite) {
        // Suite summary stats
        int passed=0, failed=0;
        for(ISuiteResult r : suite.getResults().values()) {
            passed += r.getTestContext().getPassedTests().size();
            failed += r.getTestContext().getFailedTests().size();
        }
        // Slack notification
        SlackNotifier.send(String.format("Suite: %s | P:%d F:%d | %s",
            suite.getName(), passed, failed, failed==0?"✅":"❌"));
    }
}
💡 Implement IReporter for custom HTML/CSV reports. Implement IAnnotationTransformer for global retry configuration. Knowing all TestNG interfaces shows framework depth.
Q9 How do you set up Selenium Grid 4 with Docker for distributed test execution?
Hard · Selenium Grid · Flipkart Scale Testing
Selenium Grid 4 uses a hub + nodes architecture via Docker Compose. Hub manages routing, nodes run browsers.
# docker-compose.yml for Selenium Grid 4
version: "3"
services:
  selenium-hub:
    image: selenium/hub:4.18.1
    ports: [ "4444:4444","4442:4442","4443:4443" ]
    environment:
      SE_NODE_MAX_SESSIONS: "5"
      SE_SESSION_TIMEOUT: "60"

  chrome-node:
    image: selenium/node-chrome:4.18.1
    depends_on: [selenium-hub]
    environment:
      SE_EVENT_BUS_HOST: selenium-hub
      SE_EVENT_BUS_PUBLISH_PORT: "4442"
      SE_EVENT_BUS_SUBSCRIBE_PORT: "4443"
      SE_NODE_MAX_SESSIONS: "3"
    scale: 3  # 3 Chrome nodes = 9 parallel Chrome sessions

  firefox-node:
    image: selenium/node-firefox:4.18.1
    depends_on: [selenium-hub]
    environment:
      SE_EVENT_BUS_HOST: selenium-hub
    scale: 2

# In DriverFactory: use RemoteWebDriver
// WebDriver d = new RemoteWebDriver(new URL("http://localhost:4444"), opts);
💡 docker-compose scale command allows elastic scaling. "scale: 3" for chrome-node means 3 containers × 3 sessions = 9 parallel Chrome tests. Show you understand horizontal scaling.
Q10 How do you test Flipkart's product search API including pagination, filtering, and performance?
Medium · API Testing · Flipkart API Round
Test the complete search API contract: functional correctness + edge cases + pagination + performance SLAs.
@Test
public void searchAPI_WithFilters_ShouldReturnFilteredResults() {
    given()
        .baseUri(BASE_URL)
        .queryParam("q", "laptop")
        .queryParam("brand", "Apple")
        .queryParam("minPrice", 50000)
        .queryParam("maxPrice", 150000)
        .queryParam("rating", 4)
        .queryParam("page", 1)
        .queryParam("size", 20)
    .when()
        .get("/search")
    .then()
        .statusCode(200)
        .time(lessThan(500L)) // SLA
        .body("results.size()", lessThanOrEqualTo(20))
        .body("results.every { it.brand == \"Apple\" }", is(true))
        .body("results.every { it.price >= 50000 }", is(true))
        .body("results.every { it.price <= 150000 }", is(true))
        .body("results.every { it.rating >= 4.0 }", is(true))
        .body("pagination.page", equalTo(1))
        .body("pagination.totalPages", greaterThan(0));
}

@Test public void searchAPI_EmptyQuery_ShouldReturn400() {
    given().baseUri(BASE_URL).queryParam("q", "")
    .when().get("/search").then().statusCode(400);
}
💡 Flipkart has strict API SLAs. Search API < 500ms is a critical business requirement — a slow search directly impacts conversion rate. Always add SLA assertions to search tests.
🏢

TCS Interview Process

IT Services · MNC · Largest Indian IT Company · Pan-India + Global · 3–4 Rounds

📋 TCS NQT / Prime → Technical → MR → HR🎯 Test Engineer · Senior TE · QA Lead📍 Mumbai · Pune · Chennai · Hyderabad · Bangalore

📝 TCS NQT / Online Test

TCS NQT has 4 sections: Aptitude (30 min), Reasoning (25 min), Verbal (30 min), Coding (45 min — 2 problems). For QA roles, TCS Prime has additional domain-specific questions. Coding problems are Easy to Medium.

Q1 Reverse words in a sentence: "Hello World Java" → "Java World Hello".
Easy · String · TCS NQT Common
Split by spaces, reverse the array, join with spaces.
public String reverseWords(String s) {
    String[] words = s.trim().split("\s+");
    StringBuilder sb = new StringBuilder();
    for (int i=words.length-1;i>=0;i--) {
        sb.append(words[i]);
        if (i>0) sb.append(" ");
    }
    return sb.toString();
}
// "Hello World Java" → "Java World Hello"
// "  spaces  here  " → "here spaces"
💡 Use \s+ to handle multiple spaces between words. Single \s won't handle "hello world" (two spaces). Always handle edge cases.
Q2 Find if a number is Armstrong (narcissistic): sum of digits raised to power = number itself. (153 = 1³+5³+3³).
Easy · Math · TCS NQT
Count digits, then compute sum of each digit raised to count power.
public boolean isArmstrong(int n) {
    String s = String.valueOf(n);
    int len = s.length();
    int sum = 0;
    for (char c : s.toCharArray())
        sum += (int) Math.pow(c - "0", len);
    return sum == n;
}
// 153 → true (1+125+27=153)
// 9474 → true (9^4+4^4+7^4+4^4=9474)
// 100 → false
💡 TCS NQT aptitude section often has number theory questions. Know: Armstrong, palindrome, perfect number, prime. These appear in the coding section too.
Q3 Find the second largest element in an array without sorting.
Easy · Array · TCS NQT
Single pass maintaining two variables: largest and secondLargest.
public int secondLargest(int[] arr) {
    int max=Integer.MIN_VALUE, second=Integer.MIN_VALUE;
    for (int n : arr) {
        if (n > max) { second=max; max=n; }
        else if (n>second && n!=max) second=n;
    }
    return second; // Integer.MIN_VALUE if no second distinct element
}
// [1,2,3,4,5] → 4  [5,5,5] → MIN_VALUE  [1] → MIN_VALUE
💡 Handle duplicates: n != max ensures we don't use the same value as both largest and second largest. Edge case: all equal elements returns MIN_VALUE.
Q4 Check if two strings are anagrams of each other.
Easy · String · TCS NQT
Sort both strings and compare, OR use character frequency count.
// Method 1: Sorting
public boolean isAnagram(String s, String t) {
    if (s.length() != t.length()) return false;
    char[] sc=s.toCharArray(), tc=t.toCharArray();
    Arrays.sort(sc); Arrays.sort(tc);
    return Arrays.equals(sc, tc);
}
// Method 2: Frequency (O(n) time, O(1) space)
public boolean isAnagram2(String s, String t) {
    if (s.length()!=t.length()) return false;
    int[] count=new int[26];
    for (int i=0;i<s.length();i++) {
        count[s.charAt(i)-"a"]++;
        count[t.charAt(i)-"a"]--;
    }
    for (int c : count) if (c!=0) return false;
    return true;
}
// "anagram","nagaram" → true  "rat","car" → false
💡 Always mention BOTH solutions and their trade-offs. TCS evaluates whether you know multiple approaches, not just one.
Q5 Find the sum of digits of a number until it becomes a single digit (digital root).
Easy · Math · TCS NQT
Repeatedly sum digits until < 10. Or use the mathematical formula: digital root = n%9 (with special case for multiples of 9).
// Iterative approach
public int addDigits(int num) {
    while (num >= 10) {
        int sum = 0;
        while (num > 0) { sum += num % 10; num /= 10; }
        num = sum;
    }
    return num;
}
// O(1) math formula:
public int addDigitsO1(int num) {
    if (num==0) return 0;
    return num%9==0 ? 9 : num%9;
}
// 38 → 3+8=11 → 1+1=2 → answer: 2
// 0  → 0  9  → 9  18 → 9
💡 The O(1) mathematical solution impresses TCS interviewers. It's based on the "casting out nines" rule from number theory. Show you know both brute-force and optimal.
Q6 Find all pairs in an array that sum to a target value.
Medium · Array · TCS NQT
Use HashSet. For each element, check if (target - element) exists in set. Add element to set after check.
public List<int[]> findPairs(int[] arr, int target) {
    List<int[]> pairs = new ArrayList<>();
    Set<Integer> seen = new HashSet<>();
    Set<String> used = new HashSet<>();  // avoid duplicate pairs
    for (int n : arr) {
        int complement = target - n;
        if (seen.contains(complement)) {
            String key = Math.min(n,complement)+","+Math.max(n,complement);
            if (used.add(key))
                pairs.add(new int[]{complement, n});
        }
        seen.add(n);
    }
    return pairs;
}
// [1,5,3,2,4] target=6 → [[1,5],[2,4],[3,3 only if duplicate]]
💡 TCS often asks about deduplication of pairs. The canonical key (min,max) approach prevents reporting (3,3) twice in arrays with duplicates like [3,3,5].
Q7 Print the Fibonacci series up to N terms using recursion.
Easy · Recursion · TCS NQT
Base cases: fib(0)=0, fib(1)=1. Recursive: fib(n) = fib(n-1) + fib(n-2).
// Recursive (for learning - exponential time)
public int fib(int n) {
    if (n<=1) return n;
    return fib(n-1) + fib(n-2);
}

// Memoized (efficient - O(n) time)
public int fibMemo(int n, int[] memo) {
    if (n<=1) return n;
    if (memo[n]!=-1) return memo[n];
    return memo[n] = fibMemo(n-1,memo) + fibMemo(n-2,memo);
}

// Iterative (most efficient - O(1) space)
public int fibIter(int n) {
    if (n<=1) return n;
    int a=0, b=1;
    for (int i=2;i<=n;i++) { int c=a+b; a=b; b=c; }
    return b;
}
// 0,1,1,2,3,5,8,13,21,34,...
💡 Always present 3 solutions: recursive (simple, exponential), memoized (O(n) time+space), iterative (O(n) time O(1) space). TCS appreciates knowing all 3.
Q8 Count the number of vowels and consonants in a given string.
Medium · String · TCS NQT
Iterate through string, classify each character as vowel, consonant, or other.
public int[] countVowelsConsonants(String s) {
    s = s.toLowerCase();
    String vowels = "aeiou";
    int vCount=0, cCount=0;
    for (char c : s.toCharArray()) {
        if (Character.isLetter(c)) {
            if (vowels.indexOf(c) != -1) vCount++;
            else cCount++;
        }
    }
    return new int[]{vCount, cCount};
}
// "Hello World" → vowels=3, consonants=7
// "AEIOU" → vowels=5, consonants=0
💡 TCS NQT has many string manipulation questions. Practice: palindrome, reverse, count chars, anagram, pangram. These appear almost every attempt.
Q9 Find the factorial of a number using recursion and iteration.
Easy · Math · TCS NQT
Recursive: n * factorial(n-1). Iterative: multiply 1 through n.
// Recursive
public long factorialRec(int n) {
    if (n<=1) return 1;
    return n * factorialRec(n-1);
}
// Iterative
public long factorialIter(int n) {
    long result = 1;
    for (int i=2; i<=n; i++) result *= i;
    return result;
}
// 5! = 120  10! = 3628800  0! = 1

// Edge cases to mention:
// n < 0: throw IllegalArgumentException
// n > 20: result overflows long — use BigInteger
public BigInteger factorialBig(int n) {
    BigInteger result = BigInteger.ONE;
    for (int i=2;i<=n;i++) result=result.multiply(BigInteger.valueOf(i));
    return result;
}
💡 Always mention BigInteger for large n. Factorial(21) overflows long. TCS appreciates awareness of data type limits.
Q10 Rotate an array to the right by K positions.
Medium · Array · TCS NQT
Most elegant: reverse the entire array, then reverse first K elements, then reverse remaining elements.
public void rotate(int[] nums, int k) {
    k %= nums.length;          // handle k > length
    reverse(nums, 0, nums.length-1);
    reverse(nums, 0, k-1);
    reverse(nums, k, nums.length-1);
}
private void reverse(int[] arr, int lo, int hi) {
    while (lo < hi) { int t=arr[lo]; arr[lo++]=arr[hi]; arr[hi--]=t; }
}
// [1,2,3,4,5,6,7] k=3 → [5,6,7,1,2,3,4]
// Steps: reverse all →[7,6,5,4,3,2,1]
//        reverse first 3 →[5,6,7,4,3,2,1]
//        reverse rest →[5,6,7,1,2,3,4] ✓
💡 The reverse-3-times approach is O(n) time, O(1) space — the optimal solution. Always start with k %= nums.length to handle k > array length.

🔬 Technical Interview

TCS technical interview for QA focuses on SDLC/STLC theory, testing types, Selenium basics, SQL for testers, and manual testing concepts. More knowledge-based than algorithmic. Be fluent in testing terminology.

Q1 What is the difference between Smoke Testing, Sanity Testing, and Regression Testing?
Easy · Testing Types · TCS Tech Round
Smoke Testing: Shallow test of critical features after a new build. "Is this build worth testing further?" Also called Build Verification Test.\n\nSanity Testing: Narrow, deep test of a specific fix/change. "Does this specific change work?" No documentation needed — done informally.\n\nRegression Testing: Comprehensive test after any change to ensure existing features still work. "Did the new change break anything?" Typically automated.
// Timing:
// Smoke Test    → after every new build deployment
// Sanity Test   → after a specific bug fix
// Regression    → before every release

// Who runs them:
// Smoke         → QA team (quick gate check)
// Sanity        → QA engineer who fixed the bug
// Regression    → QA team (automated suite)

// Scope:
// Smoke         → broad, shallow (10-20% of features)
// Sanity        → narrow, deep (single feature)
// Regression    → broad, deep (all features)
💡 TCS asks this in 90% of QA interviews. Know the exact definition, timing, and who runs each test type. Don't confuse smoke with sanity — they test different things.
Q2 Explain the Software Testing Life Cycle (STLC). What are its phases?
Easy · STLC · TCS Technical
STLC runs in parallel with SDLC. 6 phases:\n\n1. Test Planning: scope, strategy, resources, schedule, risk analysis\n2. Test Analysis (Requirements): study requirements, identify testable features\n3. Test Design: write test cases, prepare test data, create RTM\n4. Test Environment Setup: configure servers, install tools, load test data\n5. Test Execution: run test cases, log defects, retest fixes\n6. Test Closure: quality report, lessons learned, formal sign-off
// Entry and Exit criteria per phase:
Phase          | Entry Criteria              | Exit Criteria
Test Planning  | SRS signed off              | Test Plan document approved
Test Design    | Functional specs available  | Test cases reviewed + approved
Test Execution | Test environment ready      | All P1/P2 bugs resolved
Test Closure   | All tests executed          | Closure report signed

// RTM = Requirements Traceability Matrix
// Links: Requirement → Test Cases → Bugs found
// Ensures every requirement has test coverage
💡 Draw the STLC diagram on paper. TCS expects you to explain entry/exit criteria for each phase — this shows maturity beyond just "we test the software."
Q3 Write a Selenium script to login to a website and verify successful login.
Easy · Selenium · TCS Tech Screen
Standard Selenium login test with WebDriverManager, explicit waits, and assertions.
public class LoginTest {
    WebDriver driver;
    @BeforeMethod public void setUp() {
        WebDriverManager.chromedriver().setup();
        driver = new ChromeDriver();
        driver.manage().window().maximize();
    }
    @Test public void validLogin_ShouldNavigateToDashboard() {
        driver.get("https://example.com/login");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));

        // Enter credentials
        driver.findElement(By.id("username")).sendKeys("testuser@email.com");
        driver.findElement(By.id("password")).sendKeys("Password123");
        driver.findElement(By.id("loginBtn")).click();

        // Verify login success
        wait.until(ExpectedConditions.urlContains("/dashboard"));
        WebElement welcome = wait.until(
            ExpectedConditions.visibilityOfElementLocated(By.id("welcome-msg")));
        Assert.assertTrue(welcome.isDisplayed(), "Welcome message not shown");
    }
    @AfterMethod public void tearDown() { if(driver!=null) driver.quit(); }
}
💡 TCS expects you to demonstrate WebDriverManager (not manual chromedriver path), explicit waits (not Thread.sleep), and assertions. These three are the baseline quality bar.
Q4 Write SQL to find all customers who placed more than 3 orders in the last 30 days.
Easy · SQL · TCS QA Round
JOIN customers with orders, filter by date, GROUP BY customer, HAVING count > 3.
-- Find customers with more than 3 recent orders
SELECT c.customer_id, c.name, COUNT(o.order_id) AS order_count
FROM customers c
JOIN orders o ON c.customer_id = o.customer_id
WHERE o.order_date >= CURDATE() - INTERVAL 30 DAY
  AND o.status != "CANCELLED"
GROUP BY c.customer_id, c.name
HAVING COUNT(o.order_id) > 3
ORDER BY order_count DESC;

-- Related QA use case: validate this query in test automation
@Test public void highFrequencyCustomers_ShouldHaveMoreThan3Orders() {
    Connection conn = getTestDbConnection();
    ResultSet rs = conn.createStatement().executeQuery(
        "SELECT COUNT(*) FROM customers WHERE /* same query */ ...");
    int count = rs.getInt(1);
    Assert.assertTrue(count >= 0, "Query should execute without error");
}
💡 SQL for QA is about verifying database state after test operations. Know: SELECT, JOIN, GROUP BY, HAVING, WHERE, ORDER BY, COUNT, SUM, DISTINCT. These are used to validate backend data in integration tests.
Q5 Explain the complete defect lifecycle. What are all possible states?
Easy · Defect Lifecycle · TCS Technical
States:\n• New — just filed by QA\n• Assigned — assigned to developer\n• Open — developer acknowledged, working on it\n• Fixed — developer resolved it\n• Retest — QA testing the fix\n• Verified — QA confirmed it works\n• Closed — formally closed\n\nSpecial states:\n• Rejected — developer says it's not a bug\n• Deferred — postponed to next release\n• Won't Fix — accepted risk, won't be fixed\n• Duplicate — same bug reported twice\n• Not Reproducible — cannot reproduce the issue
// Defect fields QA should always fill:
// ID        → auto-generated
// Title     → specific and descriptive
// Priority  → P1 Critical, P2 High, P3 Medium, P4 Low
// Severity  → Blocker, Critical, Major, Minor, Trivial
// Status    → from defect lifecycle
// Steps     → exact reproduction steps (numbered)
// Expected  → what should happen
// Actual    → what actually happened
// Environment → browser, OS, version, URL
// Screenshot/Video → proof of the issue
// Assignee  → developer responsible
💡 TCS interviewers distinguish Priority vs Severity. Priority = business importance (P1=fix now). Severity = technical impact (Blocker=system crash). A cosmetic bug on login page can be P1 priority but Minor severity.
Q6 Write 10 test cases for a login form.
Easy · Test Case Writing · TCS QA Interview
Cover happy path, validation, security, and UX scenarios.
// Login Form Test Cases:
TC01: Valid email + valid password → login success, redirect to dashboard
TC02: Valid email + wrong password → error "Invalid credentials"
TC03: Unregistered email → error "Email not found"
TC04: Empty email → error "Email is required"
TC05: Empty password → error "Password is required"
TC06: Both fields empty → errors on both fields
TC07: Valid email + password with leading/trailing spaces → should trim + login
TC08: SQL injection in email: "admin'--" → should be sanitized, no crash
TC09: XSS in password: "<script>alert(1)</script>" → should not execute
TC10: Remember Me checkbox → session persists after browser close
TC11: Forgot Password link → navigates to password reset page
TC12: Valid credentials after 3 failed attempts → account locked for 15 minutes
TC13: Login with keyboard (Tab to navigate, Enter to submit) → should work
TC14: Password characters masked with ● → no plain text visible
💡 TCS expects structured test cases. Always include: TC ID, title, steps, expected result. Show you cover more than just happy path — security (XSS, SQLi), accessibility (keyboard), and edge cases.
Q7 How do you validate a REST API response in Postman? Show pre-request script and test assertions.
Medium · API Testing · TCS Senior QA
Postman tests run JavaScript in the "Tests" tab. pm.test() for assertions, pm.environment.set() for chaining requests.
// Pre-request script: generate dynamic data
pm.environment.set("timestamp", Date.now());
pm.environment.set("randomEmail", "test" + Math.random()+""+"@test.com");

// Tests tab: assertions
pm.test("Status code is 200", () => pm.response.to.have.status(200));
pm.test("Response time < 1000ms", () => pm.expect(pm.response.responseTime).to.be.below(1000));
pm.test("Content-Type is JSON", () => pm.response.to.have.header("Content-Type","application/json; charset=utf-8"));
pm.test("User has required fields", () => {
    const body = pm.response.json();
    pm.expect(body).to.have.property("userId");
    pm.expect(body).to.have.property("email");
    pm.expect(body.status).to.eql("ACTIVE");
});
// Chain: extract token for next request
const token = pm.response.json().accessToken;
pm.environment.set("authToken", token);
💡 TCS clients often use Postman for manual API verification. Showing Postman test scripting shows you can bridge manual and automated API testing — valuable for service company clients.
Q8 What is TestNG and how does it improve over JUnit for Selenium test management?
Medium · Test Automation · TCS Senior Tech
TestNG advantages over JUnit:\n• Parallel execution at method/class/test level\n• @DataProvider for data-driven tests\n• @Parameters for XML-driven config\n• Better reporting (reports groups, parameters)\n• testng.xml suite configuration with groups (smoke, regression)\n• Dependency testing: dependsOnMethods\n• ITestListener for custom hooks\n\nJUnit better for:\n• Unit testing (simpler, better IDE support)\n• Spring Boot integration (@SpringBootTest)\n• Newer: JUnit 5 has many TestNG features
// TestNG features not in JUnit 4:
@Test(groups="smoke", priority=1, retryAnalyzer=RetryAnalyzer.class)
public void loginTest() { ... }

@Test(groups="regression", dependsOnMethods="loginTest")
public void dashboardTest() { ... }

@DataProvider(name="users")
public Object[][] userData() {
    return new Object[][]{{"admin","pass1"},{"user","pass2"}};
}
@Test(dataProvider="users")
public void loginWithMultipleUsers(String u, String p) { ... }

// testng.xml
// <suite parallel="methods" thread-count="5">
//   <test name="Smoke">
//     <groups><run><include name="smoke"/></run></groups>
💡 TCS QA teams use TestNG extensively for Selenium suites. Show you can configure testng.xml for parallel execution — this directly impacts how fast regression suites run in CI.
Q9 Explain the Page Object Model pattern with an example from a TCS client project.
Medium · Framework Design · TCS Senior
POM separates locators/interactions from test logic. Each web page = one class. Tests call page methods, not raw Selenium commands.
// Without POM (bad - locators in test)
@Test public void loginTest_Bad() {
    driver.findElement(By.id("user")).sendKeys("admin");
    driver.findElement(By.id("pass")).sendKeys("pass");
    driver.findElement(By.cssSelector(".btn-login")).click();
    // 500 tests all have this code → if id changes, 500 tests break!
}

// With POM (good - locators in page class)
public class LoginPage {
    private final By emailField = By.id("user");
    private final By passField  = By.id("pass");
    private final By loginBtn   = By.cssSelector(".btn-login");
    private WebDriver driver;
    public LoginPage(WebDriver d) { this.driver=d; }
    public DashboardPage login(String email, String pass) {
        driver.findElement(emailField).sendKeys(email);
        driver.findElement(passField).sendKeys(pass);
        driver.findElement(loginBtn).click();
        return new DashboardPage(driver);
    }
}
// Test becomes:
@Test public void loginTest_Good() {
    DashboardPage dash = new LoginPage(driver).login("admin","pass");
    Assert.assertTrue(dash.isLoaded());
    // If ID changes → update ONLY LoginPage, 500 tests still work
}
💡 TCS clients migrate from Excel/manual to POM frameworks. Show you can explain POM's maintenance benefit with a real example: "changing one locator breaks 1 page class, not 500 test files."
Q10 How do you integrate Selenium tests into a Jenkins CI/CD pipeline?
Medium · CI/CD · TCS DevOps
Jenkins runs Maven commands that trigger TestNG suites. Reports published via Allure/JUnit plugins. Failure notifications via email or Slack.
// Jenkins Freestyle Job configuration:
// Build Step: Invoke Maven
//   Goals: test -Dgroups=regression -Dbrowser=chrome -Dheadless=true
// Post-build: Publish TestNG Results
//   Report XMLs: target/surefire-reports/*.xml
// Post-build: Allure Report
// Post-build: Email Notification on failure

// Jenkinsfile (Pipeline as Code - preferred):
pipeline {
    agent any
    triggers { cron("0 22 * * 1-5") } // nightly Mon-Fri
    stages {
        stage("Test") {
            steps { sh "mvn test -Dgroups=regression -Dbrowser=chrome" }
        }
        stage("Report") {
            steps { allure results: [[path: "target/allure-results"]] }
        }
    }
    post {
        failure { emailext to:"qa-team@tcs.com",
                  subject:"Regression FAILED: ${env.JOB_NAME}",
                  body:"Build: ${env.BUILD_URL}" }
    }
}
💡 TCS clients use Jenkins extensively. Show you can write a Jenkinsfile (declarative pipeline) — not just configure a freestyle job through the UI. Pipeline-as-code is the industry standard.
💼

Infosys Interview Process

IT Services · MNC · Pan-India + Global · 2–3 Rounds

📋 InfyTQ / OA → Technical Interview → HR🎯 Systems Engineer · Specialist · QA Lead📍 Mysore · Pune · Bangalore · Hyderabad

💻 InfyTQ / Online Assessment

Infosys InfyTQ platform has 4 sections: Logical Reasoning (15 min), Verbal Ability (20 min), Quantitative Aptitude (25 min), and Coding (2 problems, 30 min). Coding is Easy level. Focus on DSA basics.

Q1 Find the second smallest element in an array.
Easy · Array · InfyTQ Common
Single pass: maintain smallest and second smallest.
public int secondSmallest(int[] arr) {
    int first=Integer.MAX_VALUE, second=Integer.MAX_VALUE;
    for (int n : arr) {
        if (n < first) { second=first; first=n; }
        else if (n<second && n!=first) second=n;
    }
    return second;
}
// [3,1,4,1,5,9,2,6] → 2  [1,1,1] → MAX_VALUE
💡 Handle case where all elements are the same (return MAX_VALUE or throw exception). Infosys interviewers check edge case awareness.
Q2 Check if a string is a palindrome (ignore case and non-alphanumeric characters).
Easy · String · InfyTQ
Two pointers from both ends. Skip non-alphanumeric characters. Compare case-insensitively.
public boolean isPalindrome(String s) {
    int lo=0, hi=s.length()-1;
    while (lo<hi) {
        while (lo<hi && !Character.isLetterOrDigit(s.charAt(lo))) lo++;
        while (lo<hi && !Character.isLetterOrDigit(s.charAt(hi))) hi--;
        if (Character.toLowerCase(s.charAt(lo)) !=
            Character.toLowerCase(s.charAt(hi))) return false;
        lo++; hi--;
    }
    return true;
}
// "A man, a plan, a canal: Panama" → true
// "race a car" → false
💡 The Character.isLetterOrDigit() check handles spaces, punctuation, commas. Always mention this handles the cleanup step internally.
Q3 Find the GCD (Greatest Common Divisor) of two numbers.
Easy · Math · InfyTQ
Euclidean algorithm: GCD(a,b) = GCD(b, a%b). Base case: GCD(a,0) = a.
public int gcd(int a, int b) {
    return b==0 ? a : gcd(b, a%b);
}
// Iterative version:
public int gcdIter(int a, int b) {
    while (b!=0) { int t=b; b=a%b; a=t; }
    return a;
}
// GCD(12,8)=4  GCD(100,75)=25  GCD(17,5)=1

// LCM using GCD:
public long lcm(int a, int b) { return (long)a/gcd(a,b)*b; }
// LCM(4,6)=12  LCM(3,5)=15
💡 Know the Euclidean algorithm by heart. Infosys aptitude section has GCD/LCM problems. The coding section may ask you to use GCD as a building block for another problem.
Q4 Print a right-angled triangle pattern of stars of N rows.
Easy · Pattern · InfyTQ
Nested loops: outer for rows, inner for stars.
public void printTriangle(int n) {
    for (int i=1;i<=n;i++) {
        for (int j=1;j<=i;j++) System.out.print("* ");
        System.out.println();
    }
}
// n=4:
// *
// * *
// * * *
// * * * *

// Floyd's triangle (numbers):
public void floyd(int n) {
    int num=1;
    for (int i=1;i<=n;i++) {
        for (int j=1;j<=i;j++) System.out.print(num+++" ");
        System.out.println();
    }
}
// 1 / 2 3 / 4 5 6 / 7 8 9 10
💡 Pattern problems appear in InfyTQ frequently. Practice: right triangle, inverted triangle, pyramid, diamond, Pascal's triangle. These are easy marks in the OA.
Q5 Check if a number is prime.
Easy · Math · InfyTQ
Check divisibility from 2 to √n. O(√n) time.
public boolean isPrime(int n) {
    if (n<2) return false;
    if (n==2) return true;
    if (n%2==0) return false;
    for (int i=3; i*i<=n; i+=2) // check only odd divisors
        if (n%i==0) return false;
    return true;
}
// 2→true  3→true  4→false  17→true  100→false

// Test cases to mention:
// 0, 1       → false
// 2          → true (only even prime)
// Negative   → false
// Large prime: 104729 → true
💡 i*i<=n is equivalent to i<=Math.sqrt(n) but avoids float conversion. Starting i from 3 and incrementing by 2 skips all even numbers — halves the iterations.
Q6 Find the missing number in an array containing 1 to N with one missing.
Easy · Array · InfyTQ
Expected sum = N*(N+1)/2. Actual sum = sum of array. Missing = expected - actual.
public int missingNumber(int[] nums) {
    int n = nums.length;
    int expected = n*(n+1)/2;
    int actual   = 0;
    for (int num : nums) actual += num;
    return expected - actual;
}
// [3,0,1] → 2  [9,6,4,2,3,5,7,0,1] → 8

// XOR approach (avoids overflow for large N):
public int missingXOR(int[] nums) {
    int xor = nums.length;
    for (int i=0;i<nums.length;i++) xor ^= i ^ nums[i];
    return xor;
}
💡 The XOR approach is elegant for large arrays (no integer overflow). XOR of a number with itself = 0, so all present numbers cancel out, leaving only the missing number.
Q7 Count occurrences of each character in a string.
Easy · String · InfyTQ
Use HashMap or char array for frequency count.
public Map<Character,Integer> charFrequency(String s) {
    Map<Character,Integer> freq = new LinkedHashMap<>();
    for (char c : s.toCharArray())
        freq.merge(c, 1, Integer::sum);
    return freq;
}
// "hello" → {h:1, e:1, l:2, o:1}

// Print in order of first occurrence:
void printFrequency(String s) {
    Map<Character,Integer> freq = charFrequency(s);
    freq.forEach((c,count) ->
        System.out.printf("%c: %d%n", c, count));
}

// Find most frequent character:
char maxFreqChar(String s) {
    Map<Character,Long> freq = s.chars()
        .mapToObj(c->(char)c)
        .collect(Collectors.groupingBy(c->c, Collectors.counting()));
    return freq.entrySet().stream()
        .max(Map.Entry.comparingByValue()).get().getKey();
}
💡 LinkedHashMap preserves insertion order (first appearance order). Infosys often asks for output in a specific order — use LinkedHashMap when order matters.
Q8 Find all prime numbers up to N (Sieve of Eratosthenes).
Easy · Math · InfyTQ
Create boolean array, mark composites. Remaining true values are primes.
public List<Integer> sieve(int n) {
    boolean[] isComposite = new boolean[n+1];
    List<Integer> primes = new ArrayList<>();
    for (int i=2;i<=n;i++) {
        if (!isComposite[i]) {
            primes.add(i);
            for (long j=(long)i*i; j<=n; j+=i)
                isComposite[(int)j]=true;
        }
    }
    return primes;
}
// sieve(30) → [2,3,5,7,11,13,17,19,23,29]
// Time: O(n log log n)  Space: O(n)
💡 Start inner loop at i*i (not 2*i) because smaller multiples already marked. Use long for j to prevent integer overflow when i is large.
Q9 Transpose a matrix in place.
Easy · Matrix · InfyTQ
Swap elements across the main diagonal: swap arr[i][j] with arr[j][i] for all i < j.
public void transpose(int[][] matrix) {
    int n = matrix.length;
    for (int i=0;i<n;i++)
        for (int j=i+1;j<n;j++) {  // j starts from i+1 to avoid double-swap
            int temp = matrix[i][j];
            matrix[i][j] = matrix[j][i];
            matrix[j][i] = temp;
        }
}
// [[1,2,3],[4,5,6],[7,8,9]]
// → [[1,4,7],[2,5,8],[3,6,9]]
💡 j starts from i+1 to process each (i,j) pair exactly once. Starting from j=0 would undo the swap. This is a common off-by-one error to mention.
Q10 Implement a queue using two stacks.
Medium · Stack · InfyTQ
Two stacks: inbox and outbox. Push to inbox. Pop from outbox (refill from inbox when outbox empty).
public class QueueUsingStacks {
    private Deque<Integer> inbox  = new ArrayDeque<>();
    private Deque<Integer> outbox = new ArrayDeque<>();

    public void enqueue(int val) { inbox.push(val); }

    public int dequeue() {
        if (outbox.isEmpty()) {
            while (!inbox.isEmpty()) outbox.push(inbox.pop());
        }
        if (outbox.isEmpty()) throw new NoSuchElementException();
        return outbox.pop();
    }
    public int peek() {
        if (outbox.isEmpty())
            while (!inbox.isEmpty()) outbox.push(inbox.pop());
        return outbox.peek();
    }
}
// Amortized O(1) dequeue: each element moves at most twice
💡 Amortized O(1) analysis: each element enters inbox once and outbox once. Over N operations, total cost is O(2N) = O(N). Amortized per operation = O(1). Infosys appreciates amortized analysis.
👤

Meta Interview Process

FAANG · Facebook · Instagram · WhatsApp · 5–7 Rounds

📋 Phone Screen → Coding ×2 → System Design → Behavioral🎯 SET · SDET · Software Engineer in Test📍 Bangalore · Remote

💻 Coding Round

Meta coding rounds are identical to SWE rounds — LeetCode Medium/Hard. Fast-paced. Meta values both speed and clean code. Think out loud. They specifically look for optimal solutions and clear communication.

Q1 Number of islands — count distinct islands in a 2D binary grid.
Medium · DFS · Grid · Meta Coding 2024
DFS from each unvisited 1. Mark visited by setting to 0. Count how many times you start a fresh DFS. O(m×n) time and space.
public int numIslands(char[][] grid) {
    int count = 0;
    for (int i = 0; i < grid.length; i++)
        for (int j = 0; j < grid[0].length; j++)
            if (grid[i][j] == '1') { dfs(grid, i, j); count++; }
    return count;
}
void dfs(char[][] g, int i, int j) {
    if (i < 0 || j < 0 || i >= g.length || j >= g[0].length || g[i][j] != '1') return;
    g[i][j] = '0';
    dfs(g,i+1,j); dfs(g,i-1,j); dfs(g,i,j+1); dfs(g,i,j-1);
}
// [[1,1,0],[1,0,0],[0,0,1]] → 2
💡 Meta often follows up: "What if the grid is very large (disk-based)?" Answer: BFS with explicit queue to avoid stack overflow, or process in chunks.
Q2 Clone a graph — deep copy all nodes and their neighbor connections.
Medium · Graph · HashMap · Meta Coding 2024
Use a HashMap to avoid infinite loops on cycles. BFS or DFS to traverse all nodes. For each node, create a clone if not already in map, then recursively clone all neighbors.
public Node cloneGraph(Node node) {
    if (node == null) return null;
    Map<Node, Node> map = new HashMap<>();
    return clone(node, map);
}
private Node clone(Node n, Map<Node, Node> map) {
    if (map.containsKey(n)) return map.get(n);
    Node copy = new Node(n.val);
    map.put(n, copy);
    for (Node nb : n.neighbors)
        copy.neighbors.add(clone(nb, map));
    return copy;
}
💡 Always handle null input. Explain why HashMap is needed — without it, you get infinite recursion on cycles.
Q3 Merge overlapping intervals — given a list of intervals, merge all overlapping ones.
Medium · Arrays · Sorting · Meta Coding 2024
Sort by start time. Iterate: if current interval overlaps with last in result (curr.start <= last.end), merge by updating last.end. Otherwise append. O(n log n).
public int[][] merge(int[][] intervals) {
    Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
    List<int[]> res = new ArrayList<>();
    for (int[] iv : intervals) {
        if (res.isEmpty() || res.get(res.size()-1)[1] < iv[0])
            res.add(iv);
        else
            res.get(res.size()-1)[1] = Math.max(res.get(res.size()-1)[1], iv[1]);
    }
    return res.toArray(new int[0][]);
}
// [[1,3],[2,6],[8,10],[15,18]] → [[1,6],[8,10],[15,18]]
💡 Meta follow-up: "What if intervals arrive as a stream?" Use a TreeMap for O(log n) insertion with ordered keys.
Q4 Word search — find if a word exists in a 2D character grid (up/down/left/right).
Medium · Backtracking · Meta Coding 2024
DFS with backtracking from each cell. Mark cell as visited (replace with #), explore 4 directions, restore on return. O(m×n×4^L) where L = word length.
public boolean exist(char[][] board, String word) {
    for (int i = 0; i < board.length; i++)
        for (int j = 0; j < board[0].length; j++)
            if (dfs(board, word, 0, i, j)) return true;
    return false;
}
boolean dfs(char[][] b, String w, int k, int i, int j) {
    if (k == w.length()) return true;
    if (i<0||j<0||i>=b.length||j>=b[0].length||b[i][j]!=w.charAt(k)) return false;
    char tmp = b[i][j]; b[i][j] = '#';
    boolean found = dfs(b,w,k+1,i+1,j)||dfs(b,w,k+1,i-1,j)||
                    dfs(b,w,k+1,i,j+1)||dfs(b,w,k+1,i,j-1);
    b[i][j] = tmp;
    return found;
}
Q5 Product of array except self — without using division, O(1) extra space.
Medium · Arrays · Prefix Product · Meta Coding
Two-pass approach. First pass: store left products in result array. Second pass: multiply by running right product from right to left. No division, O(n) time, O(1) extra space.
public int[] productExceptSelf(int[] nums) {
    int n = nums.length;
    int[] res = new int[n];
    res[0] = 1;
    for (int i = 1; i < n; i++)
        res[i] = res[i-1] * nums[i-1];   // left products
    int right = 1;
    for (int i = n-1; i >= 0; i--) {
        res[i] *= right;                   // multiply right product
        right *= nums[i];
    }
    return res;
}
// [1,2,3,4] → [24,12,8,6]
Q6 Longest consecutive sequence — find length of longest consecutive elements sequence in O(n).
Medium · HashSet · Arrays · Meta Coding 2023
Put all numbers in a HashSet. For each number that is the START of a sequence (num-1 not in set), count consecutive numbers forward. Track maximum length. O(n) time.
public int longestConsecutive(int[] nums) {
    Set<Integer> set = new HashSet<>();
    for (int n : nums) set.add(n);
    int max = 0;
    for (int n : set) {
        if (!set.contains(n - 1)) {   // start of sequence
            int len = 1;
            while (set.contains(n + len)) len++;
            max = Math.max(max, len);
        }
    }
    return max;
}
// [100,4,200,1,3,2] → 4 (sequence 1,2,3,4)
💡 Key insight: only start counting from the beginning of a sequence (when n-1 not in set). This prevents O(n²).
Q7 Minimum window substring — find smallest substring of s containing all chars of t.
Medium · Sliding Window · Meta Coding 2024
Sliding window with two frequency maps. Expand right pointer including chars of t. When all chars covered, shrink left to minimize window. Track minimum. O(n+m).
public String minWindow(String s, String t) {
    Map<Character,Integer> need = new HashMap<>(), window = new HashMap<>();
    for (char c : t.toCharArray()) need.merge(c, 1, Integer::sum);
    int have = 0, required = need.size(), l = 0, minLen = Integer.MAX_VALUE, start = 0;
    for (int r = 0; r < s.length(); r++) {
        char c = s.charAt(r);
        window.merge(c, 1, Integer::sum);
        if (need.containsKey(c) && window.get(c).equals(need.get(c))) have++;
        while (have == required) {
            if (r - l + 1 < minLen) { minLen = r - l + 1; start = l; }
            char lc = s.charAt(l++);
            window.merge(lc, -1, Integer::sum);
            if (need.containsKey(lc) && window.get(lc) < need.get(lc)) have--;
        }
    }
    return minLen == Integer.MAX_VALUE ? "" : s.substring(start, start + minLen);
}
Q8 Longest palindromic substring — find the longest substring that is a palindrome.
Hard · DP · String · Meta Coding Hard
Expand around each center (both odd and even length palindromes). For each center, expand outward while characters match. Track longest found. O(n²) time, O(1) space.
public String longestPalindrome(String s) {
    if (s == null || s.length() < 1) return "";
    int start = 0, maxLen = 0;
    for (int i = 0; i < s.length(); i++) {
        int odd  = expand(s, i, i);       // odd length
        int even = expand(s, i, i + 1);   // even length
        int len  = Math.max(odd, even);
        if (len > maxLen) {
            maxLen = len;
            start = i - (len - 1) / 2;
        }
    }
    return s.substring(start, start + maxLen);
}
int expand(String s, int l, int r) {
    while (l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) { l--; r++; }
    return r - l - 1;
}
// "babad" → "bab",  "cbbd" → "bb"
Q9 Design a hit counter — count hits in the past 5 minutes (300 seconds) at any given timestamp.
Medium · Design · Queue · Meta Design Coding
Use a Queue of timestamps. On hit(), add timestamp to queue. On getHits(), first remove entries older than timestamp-300, then return queue size. O(1) amortized.
class HitCounter {
    private final Deque<Integer> times = new ArrayDeque<>();

    public void hit(int timestamp) {
        times.offer(timestamp);
    }

    public int getHits(int timestamp) {
        while (!times.isEmpty() && times.peek() <= timestamp - 300)
            times.poll();
        return times.size();
    }
}
// hit(1),hit(2),hit(3),getHits(4)→3, getHits(301)→2
💡 Meta follow-up: "Handle millions of hits per second?" Use a circular buffer of size 300 (seconds) with count per second bucket — O(1) time and O(300) space regardless of hit volume.
Q10 Search in rotated sorted array — find target in array that was rotated at an unknown pivot.
Medium · Arrays · Binary Search · Meta Coding
Binary search. At each midpoint, determine which half is sorted. If target in the sorted half, search there. Else search the other half. O(log n).
public int search(int[] nums, int target) {
    int lo = 0, hi = nums.length - 1;
    while (lo <= hi) {
        int mid = (lo + hi) / 2;
        if (nums[mid] == target) return mid;
        if (nums[lo] <= nums[mid]) {             // left half sorted
            if (nums[lo] <= target && target < nums[mid]) hi = mid - 1;
            else lo = mid + 1;
        } else {                                 // right half sorted
            if (nums[mid] < target && target <= nums[hi]) lo = mid + 1;
            else hi = mid - 1;
        }
    }
    return -1;
}
// [4,5,6,7,0,1,2] target=0 → 4,  target=3 → -1

🌟 Behavioral / Googliness

Meta behavioral evaluates impact, speed, and collaboration. Always quantify impact. Meta moves fast — show you ship things. Use the STAR format but keep answers concise.

Q1 Tell me about your most impactful technical contribution. Quantify the result.
Behavioral · Impact · Meta Behavioral
Template: Before state (X% defect escape rate, Y hours of manual work). What you built (framework/tool/automation). After state (reduced to Z%, saved N hours/week). Business impact (3× faster releases, handled N more users). Always use concrete numbers.
// STAR Framework:
// Situation: "Our regression suite took 6 hours and ran manually every Friday"
// Task:       "I was asked to reduce testing cycle time"
// Action:     "Built Selenium Grid with 20 parallel threads + TestNG parallel suite"
// Result:     "Suite now runs in 22 minutes. Releases went from weekly to daily.
//              Defect escape rate dropped from 12% to 2.8%"
💡 Meta specifically scores on: (1) Scale of impact, (2) Did you do it yourself or lead a team, (3) Was the impact permanent or one-time. Prepare 3 stories at different impact levels.
Q2 Describe a time you moved fast and shipped something despite uncertainty.
Behavioral · Speed · Meta Behavioral
Meta's culture: "Move fast." Show you shipped something valuable despite incomplete information. Key: you had a clear MVP scope, tested your riskiest assumptions first, and shipped iteratively rather than waiting for perfection.
// Good answer structure:
// 1. What was uncertain? (requirements unclear, tech unproven)
// 2. How did you reduce uncertainty cheaply? (spike, prototype, user test)
// 3. What did you ship in the first week vs month?
// 4. What did you learn from early users/data?
// 5. How did you iterate?
💡 Meta values "Bias for Action" heavily. The worst answer is waiting for perfect requirements. Show you shipped a v0.1 to learn, then iterated.
Q3 Tell me about a time you had to work with a difficult teammate to deliver a project.
Behavioral · Collaboration · Meta Behavioral
Don't make the person sound terrible — focus on the situation, not character. Show you tried to understand their perspective, found common ground, and delivered together. Meta values psychological safety and inclusive teamwork.
// Do NOT say:
// "They were difficult and I had to work around them"
// DO say:
// "We had different approaches — I suggested we each build a POC,
//  present to the team, and let data decide. They agreed.
//  Their approach turned out better for part A, mine for part B.
//  We shipped a hybrid solution that neither of us would have built alone."
Q4 Tell me about a technical decision you made that turned out to be wrong. What did you do?
Behavioral · Learning · Meta Behavioral
Own the mistake completely. Describe the decision, why it seemed right at the time, what signal told you it was wrong, how quickly you pivoted, and what permanent change you made. Meta values intellectual honesty.
// Strong answer pattern:
// "I chose Tool X because [valid reason at the time].
//  After 3 weeks, we saw [specific problem metric].
//  I ran a 2-day spike on Tool Y as an alternative.
//  Within 5 days of the spike, we migrated.
//  I also added a decision log so future choices have documented trade-offs."
💡 Meta follows up: "What would you do differently today?" Have a specific process change ready — not just "I would be more careful."
Q5 Describe a time you improved something outside your core responsibilities.
Behavioral · Ownership · Meta Behavioral
Show you noticed a problem that wasn't technically "yours," quantified its cost, fixed it proactively, and measured the result. Meta values engineers who think beyond their ticket queue.
// Example:
// "I noticed the onboarding docs were causing every new SDET to spend
//  3 days on environment setup. Not my job officially.
//  I spent one weekend documenting it properly with screenshots.
//  New hire ramp-up time dropped from 3 days to 4 hours.
//  The docs are now the official onboarding guide."
Q6 How do you think about testing at Meta's scale — 3 billion users?
Behavioral · Scale · Meta Behavioral
Key points: (1) You can't test every permutation — risk-based selection. (2) Production monitoring IS testing — real users at scale catch things test environments can't. (3) Feature flags let you test with 0.1% of real traffic before full rollout. (4) A/B testing validates quality metrics (engagement, errors) not just functional correctness.
// Meta-scale testing philosophy:
// - Canary deploys: 0.1% → 1% → 10% → 100%
// - Feature flags: test in production with limited exposure
// - Dark launch: backend changes get real traffic, users see old UI
// - Chaos: kill services deliberately to test resilience
// - SLO-based: automate rollback when error rate exceeds threshold
💡 Meta loves this question for SDET roles. Show you understand that at their scale, production IS your test environment. Traditional QA environments can't replicate 3B users.
Q7 Tell me about a time you disagreed with your manager. What happened?
Behavioral · Conflict · Meta Behavioral
Show you raised the concern with data and a clear alternative. Had a direct conversation, not passive resistance. If overruled, you committed fully. Meta values "Be Direct" — disagreeing is respected as long as you do it professionally and back it with evidence.
// Good structure:
// 1. What was the disagreement? (technical, process, priority)
// 2. What data did you bring to the conversation?
// 3. How did you raise it? (1-on-1, written proposal, team meeting?)
// 4. What was the outcome? (your view won / their view won / compromise)
// 5. How did you commit after the decision?
Q8 Tell me about a time you helped someone grow technically.
Behavioral · Mentoring · Meta Behavioral
Specific example with measurable growth: junior engineer who went from struggling with test automation to presenting at an internal tech talk. Describe your approach: pair programming, stretch assignments, weekly check-ins, letting them own something real.
💡 Meta values engineering culture — they want people who grow the team, not just themselves. Strong answer includes what THEY did (not just what you did) and how you measured their growth.
Q9 You have 5 things to do and time for 3. How do you decide?
Behavioral · Prioritization · Meta Behavioral
Framework: (1) Align with team OKRs — which 3 move the needle most? (2) Impact × urgency matrix. (3) Communicate the trade-off explicitly to stakeholders — "I can do A, B, C. D and E will slip to next sprint. Confirming this is OK." Never silently drop work.
// Meta prioritization signals:
// - User impact: affects how many users? how severely?
// - Revenue impact: is this on the critical path to a launch?
// - Dependency: is someone blocked on this?
// - Reversibility: easy to do later, or now-or-never?
// - Time-sensitivity: deadline-driven vs evergreen?
Q10 Why Meta? Why this SDET role specifically?
Behavioral · Why Meta · Meta Final Round
Be specific. Meta builds products used by 3B+ people daily — quality issues affect the world. Name the specific team if you know it. Show you understand their unique testing challenges: scale, mobile-first, real-time systems, A/B testing infrastructure.
// Strong answer elements:
// 1. Specific product/team you're joining
// 2. Why their scale is uniquely interesting to you as a QA engineer
// 3. Something specific you've read about their engineering culture
//    (e.g., Meta Engineering blog, their testing framework papers)
// 4. What you'd bring that they don't currently have
💡 Read at least 3 posts from Meta's Engineering blog before the interview. Referencing specific technical decisions they've made shows genuine interest.
💜

PhonePe Interview Process

Indian FinTech · UPI Payments · Bangalore · 4–5 Rounds

📋 Coding Screen → Technical ×2 → System Design → HR🎯 SDET · QA Engineer · Automation Engineer📍 Bangalore

💳 Technical Round 1

PhonePe Tech 1: Payment domain knowledge + automation skills. Domain knowledge directly determines shortlisting. Know UPI, payment flows, and fintech testing.

Q1 List all test cases for a UPI money transfer — happy path, failures, and edge cases.
Hard · UPI Testing · PhonePe Real Q
Happy Path: Send ₹100 to valid VPA, sender debited, receiver credited instantly, both notified, history updated correctly. Validation: Invalid VPA format (no @), amount=0, amount>₹1L daily limit, insufficient balance, wrong UPI PIN ×3 locks account. Failures: Network drops mid-transfer (idempotency — no double debit), receiver's bank down (auto-refund T+1), PENDING state auto-resolves in 3 business days. Security: PIN never transmitted in plaintext, device binding enforced.
// Test categories:
// 1. HAPPY PATH: valid VPA, valid amount, correct PIN → success
// 2. VALIDATION: invalid VPA, zero amount, over-limit, wrong PIN
// 3. BANK FAILURES: receiver bank down → PENDING → auto-refund
// 4. NETWORK: drop after debit, before credit → idempotency check
// 5. SECURITY: PIN in logs? Device binding? Rate limiting?
// 6. CONCURRENCY: same amount sent twice within 1 second — 1 debit only
💡 PhonePe signature question. Always mention idempotency — "If network drops after NPCI debit but before credit, the user must not be double-charged." This shows payment domain depth.
Q2 How do you test API idempotency for a payment endpoint? Write the automation code.
Hard · Idempotency · PhonePe Tech1
Send POST with same Idempotency-Key twice. First call returns 201 with a paymentId. Second call with same key must return 200 (already processed) with the SAME paymentId. Verify the database has only 1 charge.
@Test
public void testPaymentIdempotency() {
    String idempotencyKey = UUID.randomUUID().toString();
    String requestBody = "{\"amount\":500,\"vpa\":\"test@upi\"}";

    // First call - creates payment
    String paymentId1 = given()
        .header("Idempotency-Key", idempotencyKey)
        .header("Authorization", "Bearer " + getToken())
        .body(requestBody).contentType(ContentType.JSON)
    .when().post("/v1/payments")
    .then().statusCode(201)
    .extract().path("paymentId");

    // Second call - same key, must return SAME paymentId
    String paymentId2 = given()
        .header("Idempotency-Key", idempotencyKey)
        .header("Authorization", "Bearer " + getToken())
        .body(requestBody).contentType(ContentType.JSON)
    .when().post("/v1/payments")
    .then()
        .statusCode(200)    // NOT 201 - already processed
        .body("idempotent", equalTo(true))
    .extract().path("paymentId");

    Assert.assertEquals(paymentId1, paymentId2,
        "Same Idempotency-Key must return same paymentId - no double charge");
}
💡 Critical: always use UUID.randomUUID() for idempotency keys in tests — never hardcode. Also verify the wallet balance was only debited ONCE by querying the balance before and after.
Q3 Write comprehensive test cases for OTP delivery and verification in UPI login.
Medium · OTP Testing · PhonePe Tech1
Delivery: OTP received within 10s, correct 6-digit format, correct sender ID. Verification: Correct OTP → logged in, wrong OTP → error, expired OTP (5 min) → "OTP expired" message. Rate limiting: Wrong OTP 3× → temporary block (30 min). Security: OTP not in API response body, not in server logs, not reusable after successful use, brute force rate limiting. Resend: Resend works, previous OTP invalidated after resend.
// OTP Test Matrix:
// TC1: Correct OTP within 5 min → 200 logged in
// TC2: Wrong OTP → 401 with "Invalid OTP"
// TC3: Correct OTP after 5 min 1 sec → 401 "OTP expired"
// TC4: Same OTP used twice → 401 on second use
// TC5: Wrong OTP 3 times → account locked 30 min
// TC6: Resend OTP → old OTP now invalid
// TC7: OTP in /send-otp response body? → SECURITY FAIL
// TC8: OTP visible in network logs? → SECURITY FAIL
Q4 Test cases for "Add Money to Wallet" — sources, limits, failures, notifications.
Medium · Wallet Testing · PhonePe Tech1
Sources: UPI, Debit/Credit card, Net Banking. Validation: min ₹1, max ₹10K per txn, daily limit ₹50K, KYC-based limits (non-KYC max ₹10K total). Failures: bank server down (clean error, no partial credit), payment gateway timeout (retry with idempotency). Success: instant credit, notification, balance update on reload. Edge: add exactly at limit, add 1 rupee above limit.
Q5 How do you validate HMAC-SHA256 webhook signature verification in Java?
Hard · Webhook Testing · PhonePe Tech1
Compute HMAC-SHA256 of the raw request body using the shared secret. Compare the computed signature with the X-PhonePe-Signature header. If mismatch: reject with 400. Test: valid signature passes, tampered body fails, wrong secret fails.
public void validateWebhookSignature(String rawBody, String receivedSig, String secret)
        throws Exception {
    Mac mac = Mac.getInstance("HmacSHA256");
    SecretKeySpec key = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
    mac.init(key);
    byte[] hash = mac.doFinal(rawBody.getBytes(StandardCharsets.UTF_8));
    String computed = Base64.getEncoder().encodeToString(hash);
    Assert.assertEquals(computed, receivedSig, "Webhook signature mismatch!");
}

// Test cases:
// 1. Valid body + valid secret → signatures match → accept
// 2. Tampered body (amount changed) + valid secret → mismatch → 400
// 3. Valid body + wrong secret → mismatch → 400
// 4. Missing X-PhonePe-Signature header → reject immediately
💡 PhonePe uses HMAC-SHA256 + Base64 encoding for webhooks. Always validate the raw body, not the parsed JSON — even whitespace differences will cause signature mismatch.
Q6 Design test cases for payment refund flow in a UPI application.
Medium · Refund Testing · PhonePe Tech1
Full refund: exact original amount refunded to source account. Partial refund: specified amount less than original, balance correct. Timing: refund within T+5 business days, notification on initiation and completion. Edge: refund when original bank account closed (alternate method), double refund request (idempotent — 1 refund only). Status: refund trackable in history, status transitions (INITIATED→PROCESSING→COMPLETED).
Q7 How do you test concurrent payment requests — 1000 users paying simultaneously?
Hard · Concurrency Testing · PhonePe Tech1
Use JMeter with 1000 threads, 1-second ramp-up. Test: each request has unique Idempotency-Key. Assert: all 1000 return 201 (no race condition failures), zero duplicate charges in database, total debit from wallets = 1000 × payment_amount, response time p95 < 3s. Also test: 1000 users all paying from same account simultaneously — only balance amount should be charged.
// JMeter thread group config:
// Threads: 1000
// Ramp-up: 1 second (all at once)
// Loop: 1

// Each request:
// Header: Idempotency-Key = ${__UUID()}  <- unique per thread
// Body: {"amount":100, "vpa":"merchant@upi"}

// Assertions:
// Response Code: 200 or 201
// Response Time: < 3000ms

// Post-test DB validation:
// SELECT COUNT(*) FROM payments WHERE batch_id = ? → should = 1000
// SELECT SUM(amount) FROM wallet_debits WHERE batch_id = ? → should = 100000
Q8 Write REST Assured tests for PhonePe transaction history API with pagination.
Medium · API Testing · PhonePe Tech1
Test: first page returns 20 items with correct total count, page 2 returns next 20 non-overlapping items, last page returns remaining items (< 20), page beyond total returns empty array, date filter reduces correctly, sort by date desc is default.
@Test
public void testTransactionHistoryPagination() {
    // Get page 1
    Response page1 = given()
        .header("Authorization", "Bearer " + getToken())
        .queryParam("page", 1)
        .queryParam("size", 20)
    .when().get("/v1/transactions")
    .then()
        .statusCode(200)
        .body("data.size()", equalTo(20))
        .body("total", greaterThan(0))
        .body("hasMore", equalTo(true))
    .extract().response();

    // Collect all IDs from page 1
    List<String> page1Ids = page1.path("data.transactionId");

    // Get page 2 - must be different records
    List<String> page2Ids = given()
        .header("Authorization", "Bearer " + getToken())
        .queryParam("page", 2).queryParam("size", 20)
    .when().get("/v1/transactions")
    .then().statusCode(200).extract().path("data.transactionId");

    // No overlap between pages
    page1Ids.retainAll(page2Ids);
    Assert.assertTrue(page1Ids.isEmpty(), "Pages must not contain duplicate transactions");
}
Q9 How do you test for common security vulnerabilities in a payment API?
Hard · Security Testing · PhonePe Tech1
IDOR: Login as user A, attempt to GET /transactions/{id} where id belongs to user B → must return 403. Auth bypass: Access protected endpoints without token → 401, with expired token → 401, with manipulated JWT (change user_id) → 401. Injection: SQL injection payloads in amount field, XSS in description field. Rate limiting: 100 requests/minute — 101st should return 429. Sensitive data: Card numbers masked in responses, CVV never stored or returned.
// IDOR Test:
String userBToken = loginAsUserB();
String userATransactionId = createTransactionAsUserA();

given()
    .header("Authorization", "Bearer " + userBToken)  // User B's token
    .pathParam("id", userATransactionId)               // User A's transaction
.when().get("/v1/transactions/{id}")
.then().statusCode(403);  // MUST be 403, not 200

// JWT Manipulation Test:
String validToken = loginAsUserA();
String manipulatedToken = manipulateJwtUserId(validToken, "admin");
given().header("Authorization", "Bearer " + manipulatedToken)
.when().get("/v1/account/balance")
.then().statusCode(401);  // Signature validation must catch this
💡 IDOR (Insecure Direct Object Reference) is the #1 API vulnerability in payment apps. Always test: "Can user B access user A's data just by guessing/incrementing the ID?"
Q10 Design your API test automation framework architecture for payment testing.
Hard · Framework Design · PhonePe Tech1
Tech stack: REST Assured + TestNG + Java. Structure: BaseApiTest (auth token management, RequestSpecification setup), service-layer classes (PaymentService, WalletService, TransactionService) with typed methods. Test data: JSON fixture files per test scenario. Reporting: Allure with request/response attached on failure. Config: environment-specific properties (sandbox/staging/prod). Security: API keys in environment variables, never in code. CI: GitHub Actions running smoke on PR, full regression nightly.
public class BaseApiTest {
    protected static RequestSpecification authSpec;

    @BeforeClass
    public static void setup() {
        // Get auth token once per class
        String token = AuthHelper.getToken();
        authSpec = new RequestSpecBuilder()
            .setBaseUri(Config.getBaseUrl())
            .addHeader("Authorization", "Bearer " + token)
            .addHeader("Content-Type", "application/json")
            .addFilter(new AllureRestAssured())  // attach to Allure report
            .build();
    }
}

// Service class
public class PaymentService {
    public String createPayment(String vpa, int amount) {
        return given(authSpec)
            .header("Idempotency-Key", UUID.randomUUID().toString())
            .body(String.format("{\"vpa\":\"%s\",\"amount\":%d}", vpa, amount))
        .when().post("/v1/payments")
        .then().statusCode(201)
        .extract().path("paymentId");
    }
}
💡 PhonePe interviews heavily on framework design. Key differentiators: Idempotency-Key auto-generation, Allure integration for payment test evidence, environment-aware token caching.
🔷

Razorpay Interview Process

Indian FinTech · API-First Payments · Bangalore · 3–4 Rounds

📋 Coding Screen → Technical ×2 → HM Round🎯 SDET · QA Engineer📍 Bangalore

🔌 API + Domain Round

Razorpay is API-first. This round is the most important — show deep REST API testing, payment webhook validation, and SDK testing knowledge. Every question ties back to payments.

Q1 How do you automate testing of Razorpay webhook signature verification?
Hard · Webhook Security · Razorpay Real Q
Razorpay webhook signature = HMAC-SHA256(razorpay_order_id + "|" + razorpay_payment_id) using webhook_secret. Test: valid payload+secret → signatures match, tampered body → mismatch, wrong secret → mismatch, replay attack (old timestamp) → reject.
@Test
public void testWebhookSignatureValid() throws Exception {
    String orderId = "order_test123";
    String paymentId = "pay_test456";
    String secret = "whsec_test";

    // Compute expected signature (what Razorpay sends)
    String body = orderId + "|" + paymentId;
    Mac mac = Mac.getInstance("HmacSHA256");
    mac.init(new SecretKeySpec(secret.getBytes(), "HmacSHA256"));
    String expectedSig = Hex.encodeHexString(mac.doFinal(body.getBytes()));

    // Verify your handler accepts it
    Assert.assertTrue(WebhookValidator.verify(orderId, paymentId, expectedSig, secret));
}

@Test
public void testWebhookSignatureTampered() throws Exception {
    // Change the amount in the payload AFTER signing
    Assert.assertFalse(
        WebhookValidator.verify("order_TAMPERED", "pay_test456", validSignature, secret)
    );
}
💡 Razorpay signature uses order_id|payment_id (note the pipe | separator). HMAC-SHA256 with hex encoding (not Base64). Get this wrong and your integration is insecure.
Q2 Design test cases for Razorpay Payment Links — create, share, pay, expire.
Medium · Payment Links · Razorpay Tech
Create: Valid amount → link generated with unique short URL, customer name/email populated. Pay: Link opens checkout, accepts UPI/card, success notification via webhook. Partial payment: Pay less than full amount (if enabled) — link remains active for remainder. Expiry: Link expires after set time → 410 Gone. Security: Link amount cannot be modified by customer-side JS manipulation. Idempotency: Paying same link twice → second attempt rejected.
Q3 How do you test Razorpay's JavaScript checkout SDK embedded in a React app?
Hard · SDK Testing · Razorpay Unique Q
Use Cypress with cy.intercept() to mock Razorpay's API responses. Test the entire payment flow without real money: SDK renders → customer selects method → mock API confirms payment → success callback fires → UI shows confirmation.
describe('Razorpay Checkout SDK', () => {
    beforeEach(() => {
        // Mock Razorpay payment success
        cy.intercept('POST', 'https://api.razorpay.com/v1/payments/create/ajax', {
            statusCode: 200,
            body: {
                razorpay_payment_id: 'pay_test123',
                razorpay_order_id:   'order_test456',
                razorpay_signature:  'sig_abc'
            }
        }).as('razorpayPayment');
    });

    it('completes payment and shows success screen', () => {
        cy.visit('/checkout');
        cy.get('[data-testid="pay-button"]').click();
        // Razorpay modal opens (injected iframe)
        cy.frameLoaded('.razorpay-checkout-frame');
        cy.iframe().find('[data-testid="submit-button"]').click();
        cy.wait('@razorpayPayment');
        cy.get('[data-testid="success-message"]').should('be.visible');
        cy.get('[data-testid="order-id"]').should('contain', 'order_test456');
    });
});
💡 Razorpay SDK loads in an iframe — use cy-iframe library or cy.frameLoaded() to interact inside the iframe. This is a unique challenge not found in standard Selenium/Cypress courses.
Q4 Write REST Assured tests for Razorpay Order API — create, fetch, and validate.
Hard · Order API · Razorpay Tech
POST /v1/orders creates order with amount in paise (not rupees). GET /v1/orders/{id} returns full details. Test: amount in paise correctly stored, currency defaults to INR, receipt field preserved, status starts as "created".
public class RazorpayOrderTest {
    private static final String BASE_URL = "https://api.razorpay.com";

    private String encodeCredentials() {
        return Base64.getEncoder().encodeToString(
            (KEY_ID + ":" + KEY_SECRET).getBytes()
        );
    }

    @Test
    public void createOrder_ValidInput_Returns200WithOrderId() {
        String orderId = given()
            .baseUri(BASE_URL)
            .header("Authorization", "Basic " + encodeCredentials())
            .body("{\"amount\":50000,\"currency\":\"INR\",\"receipt\":\"order_rcpt_001\"}")
            .contentType(ContentType.JSON)
        .when().post("/v1/orders")
        .then()
            .statusCode(200)
            .body("status", equalTo("created"))
            .body("amount", equalTo(50000))    // 50000 paise = ₹500
            .body("currency", equalTo("INR"))
            .body("receipt", equalTo("order_rcpt_001"))
            .body("id", startsWith("order_"))
        .extract().path("id");

        // Fetch the created order
        given()
            .baseUri(BASE_URL)
            .header("Authorization", "Basic " + encodeCredentials())
        .when().get("/v1/orders/" + orderId)
        .then()
            .statusCode(200)
            .body("id", equalTo(orderId))
            .body("status", equalTo("created"));
    }
}
💡 Critical Razorpay gotcha: amounts are in PAISE not RUPEES. ₹500 = 50000 paise. Test this explicitly — many integrations have bugs because of this unit mismatch.
Q5 How do you test Razorpay subscription recurring billing?
Hard · Subscription Testing · Razorpay Tech
Create subscription: plan validation, mandate creation via bank auth. First charge: correct amount on start_at date, user notified. Subsequent charges: on schedule per billing cycle (weekly/monthly), correct amount. Failed charge: retry logic (Razorpay retries 3× over 3 days), notification to merchant. Cancellation: no future charges after cancel_at, pro-ration if mid-cycle. Pause/resume: charge skipped during pause, resumes correctly.
Q6 How do you test payment failures and error codes from different bank scenarios?
Medium · Error Codes · Razorpay Tech
Use Razorpay test card numbers to trigger specific error codes. Test card 4111111111111111 with CVV 123 succeeds. Special test cards trigger: INSUFFICIENT_FUNDS, INVALID_CVV, EXPIRED_CARD, BLOCKED_CARD. Verify: correct error code in API response, user-friendly message shown, amount NOT deducted, retry possible.
// Razorpay test cards for specific failures:
// Success:           4111 1111 1111 1111  CVV: 123  Expiry: any future date
// Insufficient Funds: Use test card with specific last 4 digits per Razorpay docs
// Expired Card:       Any past expiry date
// Invalid CVV:        CVV: 000

// REST Assured test for declined payment:
given().body("{\"card\":{\"number\":\"4000000000000002\"," +   // Decline card
              "\"cvv\":\"123\",\"expiry_month\":12,\"expiry_year\":30}," +
              "\"amount\":10000,\"currency\":\"INR\"}")
.when().post("/v1/payments")
.then()
    .statusCode(400)
    .body("error.code", equalTo("BAD_REQUEST_ERROR"))
    .body("error.description", containsString("Your payment has been declined"))
    .body("error.reason", equalTo("payment_failed"));
Q7 Test the Razorpay Payout API — fund transfers to bank accounts.
Hard · Payout Testing · Razorpay Tech
Success: Payout to valid bank account/UPI VPA — amount debited from Razorpay balance, recipient credited (verify via bank statement in staging), status=processed, webhook fires. Validation: Invalid IFSC code → 400, invalid account number → 400, amount exceeding available balance → 400. Scheduling: Future-dated payouts process on correct date, not before. Cancellation: Cancel within processing window → cancelled, after processing → cannot cancel.
Q8 How do you set up a CI pipeline for Razorpay API integration tests?
Medium · CI/CD · Razorpay Tech
GitHub Actions: trigger on PR merge to main. Stage 1: unit tests (no network). Stage 2: API smoke against Razorpay test environment (5 critical endpoints, <5 min). Stage 3: nightly full regression (all APIs, edge cases). Secrets: RAZORPAY_KEY_ID and KEY_SECRET in GitHub Secrets, never in code. Report: Allure HTML uploaded as artifact with request/response logs.
name: Razorpay API Tests
on:
  push:
    branches: [main]
  schedule:
    - cron: '0 2 * * *'    # Nightly 2 AM

jobs:
  api-tests:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - uses: actions/setup-java@v3
      with: { java-version: '17', distribution: 'temurin' }
    - name: Run API Tests
      env:
        RAZORPAY_KEY_ID: ${{ secrets.RAZORPAY_KEY_ID }}
        RAZORPAY_KEY_SECRET: ${{ secrets.RAZORPAY_KEY_SECRET }}
        ENV: test
      run: mvn test -Dgroups=api-smoke -Denv=${{ env.ENV }}
    - name: Upload Allure Report
      if: always()
      uses: actions/upload-artifact@v3
      with: { name: allure-results, path: target/allure-results }
Q9 Explain Razorpay's payment flow end-to-end. Trace a ₹500 UPI transaction.
Medium · Domain Knowledge · Razorpay HR
Step 1: Merchant server calls POST /v1/orders → order_id returned. Step 2: Customer opens Razorpay checkout (JS SDK) → selects UPI. Step 3: Razorpay sends collect request to customer's UPI app via NPCI. Step 4: Customer approves in UPI app → NPCI confirms. Step 5: Razorpay receives confirmation → sends webhook to merchant server. Step 6: Merchant server verifies webhook signature → fulfills order. Test each hop.
// Integration test points:
// 1. POST /v1/orders    → assert order_id returned, status="created"
// 2. Checkout opens     → assert order_id embedded correctly in SDK init
// 3. Payment attempt    → mock NPCI success, assert payment_id returned
// 4. Webhook received   → assert signature valid, payload matches order
// 5. Order fulfilled    → assert order status updated to "paid"
// 6. E2E amount check   → ₹500 charged = ₹500 credited (minus Razorpay fee)
💡 Razorpay takes a fee (typically 2% + GST). Test that the net amount received by merchant matches expected after fee deduction. Many integration bugs hide here.
Q10 How do you handle sensitive test data (API keys, card numbers) securely in your framework?
Medium · Test Data Security · Razorpay Tech
Never: hardcode in source code, commit to git, log in CI output. Local dev: .env file excluded via .gitignore, loaded via dotenv library. CI/CD: GitHub Secrets / AWS Secrets Manager / HashiCorp Vault. Test cards: only use officially documented Razorpay test card numbers — never use real card numbers even in test environments. Masking: configure logging to mask Authorization header and card fields.
// Load secrets safely
public class Config {
    public static String getRazorpayKey() {
        String key = System.getenv("RAZORPAY_KEY_ID");
        if (key == null || key.isBlank())
            throw new IllegalStateException(
                "RAZORPAY_KEY_ID not set. Add to .env or CI secrets.");
        return key;
    }
}

// Mask sensitive fields in REST Assured logs
RestAssured.filters(new RequestLoggingFilter(
    LogDetail.ALL, true,
    new PrintStream(new FilterOutputStream(System.out) {
        // Mask Authorization header
    })
));
💡 Security audit tip: run "git log --all --full-history -- *.properties" to check if secrets were ever accidentally committed. If yes, rotate them immediately — git history is public even if deleted.
🍕

Swiggy Interview Process

Indian Product · Food Tech · Bangalore · 4 Rounds

📋 Coding → Technical ×2 → System Design → HR🎯 SDET · QA Engineer📍 Bangalore

🔬 Technical Round

Swiggy Technical: Selenium, API Testing, Java, real-time testing. Swiggy values domain knowledge of food-tech delivery systems. Real-time order tracking and GPS-based testing are unique to Swiggy.

Q1 How do you test Swiggy's real-time order tracking from placement to delivery?
Hard · Real-Time Testing · Swiggy Signature Q
State machine test: ORDER_PLACED → RESTAURANT_ACCEPTED → BEING_PREPARED → PICKED_UP → OUT_FOR_DELIVERY → DELIVERED. For each transition: correct status update (within SLA), push notification sent to customer, ETA updated on map, GPS coordinates of delivery partner updated every 10s. Edge cases: restaurant rejects order (refund triggered), delivery partner app crashes mid-delivery (order reassigned), GPS signal lost in tunnel (last known location shown).
// State transition test
@Test
public void orderTracking_CompleteFlow_AllStateTransitionsVerified() {
    String orderId = placeTestOrder();

    // State 1: ORDER_PLACED
    assertOrderStatus(orderId, "ORDER_PLACED");
    assertPushNotificationSent(orderId, "ORDER_PLACED");

    // Simulate restaurant accepting
    simulateRestaurantAccept(orderId);
    waitForStatusChange(orderId, "RESTAURANT_ACCEPTED", 30);
    assertETAUpdated(orderId);

    // Simulate dispatch
    simulatePickup(orderId);
    waitForStatusChange(orderId, "OUT_FOR_DELIVERY", 60);

    // Verify GPS tracking active
    GPSCoordinates coords = getDeliveryPartnerLocation(orderId);
    Assert.assertNotNull(coords, "GPS coordinates must be available during delivery");

    // Simulate delivery
    simulateDelivery(orderId);
    waitForStatusChange(orderId, "DELIVERED", 30);
    assertOrderCompletionNotification(orderId);
}
💡 Swiggy signature question. Always structure your answer as a state machine — it shows systematic thinking. Mention real-time challenges: "How do you assert GPS coordinates are within 50m of actual location?"
Q2 Test cases for Swiggy restaurant search and discovery.
Medium · Search Testing · Swiggy Tech
Basic search: keyword returns restaurants serving that cuisine, case-insensitive, partial match works. Location-based: only restaurants within delivery radius shown, sorted by delivery time. Filters: rating filter, max delivery time, min order value, pure-veg toggle. Edge: restaurant closed (shows next opening time, not orderable), out-of-stock items greyed out, brand new restaurant with 0 reviews. Performance: search results in <500ms.
Q3 Write REST Assured tests for Swiggy cart API — add, update, remove items.
Medium · API Testing · Swiggy Tech
POST /cart/items → adds item with correct price and restaurant. PUT /cart/items/{id} → updates quantity, total recalculated. DELETE /cart/items/{id} → item removed, total updated. Edge: add item from different restaurant (reject — Swiggy doesn't allow multi-restaurant carts). Add out-of-stock item → 400.
@Test
public void addItemToCart_ValidItem_CartUpdatedCorrectly() {
    String itemId = "ITEM_PIZZA_MARGHERITA";
    int qty = 2;

    given()
        .header("Authorization", "Bearer " + userToken)
        .body(String.format("{\"itemId\":\"%s\",\"quantity\":%d,\"restaurantId\":\"REST_001\"}", itemId, qty))
        .contentType(ContentType.JSON)
    .when().post("/v2/cart/items")
    .then()
        .statusCode(200)
        .body("cart.itemCount", equalTo(1))
        .body("cart.items[0].itemId", equalTo(itemId))
        .body("cart.items[0].quantity", equalTo(qty))
        .body("cart.totalPrice", greaterThan(0f))
        .body("cart.restaurantId", equalTo("REST_001"));
}

@Test
public void addItemFromDifferentRestaurant_ShouldReject() {
    // Cart already has item from REST_001
    addItemToCart("ITEM_001", "REST_001");
    // Trying to add from REST_002
    given()
        .header("Authorization", "Bearer " + userToken)
        .body("{\"itemId\":\"ITEM_002\",\"quantity\":1,\"restaurantId\":\"REST_002\"}")
        .contentType(ContentType.JSON)
    .when().post("/v2/cart/items")
    .then()
        .statusCode(409)  // Conflict - multi-restaurant cart not allowed
        .body("error.code", equalTo("MULTI_RESTAURANT_CART_NOT_ALLOWED"));
}
💡 Swiggy-specific rule: only ONE restaurant per cart. This is a unique business constraint — always test it explicitly.
Q4 How do you test Swiggy's dynamic surge pricing algorithm?
Hard · Surge Pricing · Swiggy Tech
No surge: normal demand period → base price shown. Surge triggers: high demand threshold crossed → surge multiplier (1.5×, 2×) applied. Price cap: maximum surge cap respected (Swiggy caps at 2× base). Transparency: surge amount visible to user BEFORE order confirmation. Price lock: price locked when order placed (even if surge ends). Removal: demand drops → surge removed within 5 minutes.
Q5 Test Swiggy's push notification system for order status updates.
Medium · Notification Testing · Swiggy Tech
Delivery: all 5 state transitions trigger correct push notification. Timing: notification within 30s of state change. Content: correct order ID, status, ETA in notification payload. Deep link: tapping notification opens correct order tracking screen. Opt-out: user who disabled notifications doesn't receive them. Retry: if device offline, notification delivered when device comes back online (within 24h).
Q6 How do you load test Swiggy during IPL match nights (peak order volume)?
Hard · Performance Testing · Swiggy Tech
Baseline: normal 5K orders/min → p95 <2s for order confirmation. Peak simulation: IPL match night = 3× surge = 15K orders/min, spike at 7:30 PM IST. JMeter: 15K TPS against /orders/place, /restaurants/search, /cart/checkout. Assert: p95 <2s maintained, no orders lost, inventory decremented correctly (no overselling). Chaos: kill one DB replica during load — requests route to another, no failures.
💡 Swiggy engineering blog covers their IPL load handling in detail — read it before the interview. Mentioning specific numbers from their published case studies shows genuine preparation.
Q7 Test cases for Swiggy restaurant reviews and ratings.
Medium · Review Testing · Swiggy Tech
Eligibility: only delivered orders can be rated. Rating: 1–5 stars, required before text review optional. Editing: review editable within 48 hours of posting. Average update: restaurant average rating recalculates within 5 minutes of new review. Validation: profanity filter on review text, max 500 characters. Display: most recent reviews shown first, pagination works.
Q8 Design an Appium test framework for Swiggy's Android app.
Hard · Mobile Automation · Swiggy Tech
Stack: Appium 2.x + UIAutomator2 driver + TestNG + Java. Structure: Page Objects for each screen (HomeScreen, RestaurantScreen, CartScreen, OrderTrackingScreen). Device pool: real devices for critical paths (payment), emulators for regression. Network tests: use Android network emulation for 2G/offline scenarios. Parallel: multiple devices via Appium Grid. CI: emulator started in GitHub Actions, real devices via AWS Device Farm.
// AppiumDriver setup for Android
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability("platformName", "Android");
caps.setCapability("deviceName", "emulator-5554");
caps.setCapability("appPackage", "in.swiggy.android");
caps.setCapability("appActivity", ".SplashActivity");
caps.setCapability("automationName", "UIAutomator2");
caps.setCapability("newCommandTimeout", 120);
caps.setCapability("noReset", false);   // fresh install per test run

driver = new AndroidDriver(new URL("http://localhost:4723"), caps);

// Network condition simulation
((AndroidDriver)driver).setNetworkConnection(
    new NetworkConnectionSetting(false, true, false) // WiFi only (no mobile data)
);
Q9 How do you test delivery partner assignment logic?
Hard · Delivery Partner Testing · Swiggy Tech
Assignment: nearest available partner assigned within 60s. Rejection: partner rejects → next nearest assigned within 30s. No response: auto-assigned to next partner after 60s timeout. Concurrent orders: same partner not assigned two simultaneous long-distance orders. Cancellation: partner cancels mid-way → order reassigned, customer notified, ETA updated. Radius: partner must be within configurable radius for assignment.
Q10 How do you test Swiggy's app for accessibility compliance?
Medium · Accessibility · Swiggy Tech
Screen reader: TalkBack (Android) / VoiceOver (iOS) — all interactive elements have meaningful content descriptions. Touch targets: minimum 44×44 dp for all tappable elements. Color contrast: WCAG AA minimum 4.5:1 ratio for text. Font scaling: app usable at 200% font size without layout breaking. Automation: axe-core or Applitools Contrast Analyzer for automated checks in CI.
// axe-core accessibility test via Selenium WebDriver (web)
JavascriptExecutor js = (JavascriptExecutor) driver;
Object result = js.executeAsyncScript(
    "var cb = arguments[arguments.length-1];" +
    "axe.run({ runOnly: ['wcag2a','wcag2aa'] }, cb);"
);
@SuppressWarnings("unchecked")
Map<String, Object> axeResult = (Map<String, Object>) result;
List<?> violations = (List<?>) axeResult.get("violations");
Assert.assertEquals(violations.size(), 0,
    "Accessibility violations found: " + violations.toString());
🍽️

Zomato Interview Process

Indian Product · Food Tech · Gurugram HQ · 3–4 Rounds

📋 Online Test → Technical ×2 → HR🎯 SDET · QA Engineer📍 Gurugram · Bangalore

🔬 Technical Round

Zomato Tech: Java, Selenium, API testing, and food-tech domain knowledge. Fast-paced interviews — be concise and structured. Zomato values engineers who understand their core challenges: food discovery, dynamic pricing, and live order tracking.

Q1 What is BDD? Implement a Cucumber scenario for Zomato restaurant search.
Medium · BDD · Zomato Tech
BDD (Behavior-Driven Development) = writing tests in business language using Gherkin (Given/When/Then). Bridges communication between BA, Dev, and QA. Feature files understood by non-technical stakeholders. Cucumber maps Gherkin to Java step definitions.
// Feature file: restaurant_search.feature
Feature: Restaurant Search
  Background:
    Given I am logged into Zomato app
    And my delivery location is "Koramangala, Bangalore"

  Scenario: Search returns relevant cuisine results
    When I search for "Pizza" in the search bar
    Then I should see at least 5 restaurants serving pizza
    And all results should be within 10km delivery radius
    And results should be sorted by delivery time by default

  Scenario: Filter by rating
    Given I search for "Burger"
    When I apply rating filter "4 stars and above"
    Then all displayed restaurants should have rating >= 4.0

// Step Definition (Java):
@When("I search for {string} in the search bar")
public void searchForRestaurant(String cuisine) {
    searchPage.enterSearchQuery(cuisine);
    searchPage.tapSearch();
}

@Then("I should see at least {int} restaurants serving pizza")
public void verifyMinimumResults(int minCount) {
    Assert.assertTrue(searchPage.getResultCount() >= minCount,
        "Expected at least " + minCount + " results");
}
💡 Zomato interview tip: always write the feature file FIRST before the step definitions. Interviewers check whether you write BDD from the business perspective or the technical perspective.
Q2 Design test cases for Zomato's dynamic delivery fee and surge pricing.
Hard · Dynamic Pricing · Zomato Tech
Base fee: calculated by distance (first 2km free, ₹5/km after). Rain surge: 1.5× base during rain detected in customer's city. Peak hours: 12–2 PM and 7–10 PM = 1.2× base. Max cap: delivery fee never exceeds ₹99 regardless of multipliers. Transparency: fee shown before order, not added at checkout surprise. Price lock: fee locked when order placed, weather change after that doesn't affect it.
Q3 Write Selenium test for Zomato live order tracking page.
Hard · Order Tracking · Zomato Tech
Navigate to active order page. Wait for map to load (GPS iframe). Assert: delivery partner marker is visible on map, ETA countdown is ticking, status bar shows current state, "Call partner" button visible. Verify status updates when mocked backend fires state change.
@Test
public void liveTracking_ActiveOrder_MapAndStatusVisible() {
    // Place a test order (via API to skip UI setup)
    String orderId = orderApi.placeTestOrder();

    // Navigate to tracking page
    driver.get(BASE_URL + "/order-tracking/" + orderId);

    WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(20));

    // Map container visible
    WebElement mapContainer = wait.until(
        ExpectedConditions.visibilityOfElementLocated(By.id("tracking-map"))
    );
    Assert.assertTrue(mapContainer.isDisplayed());

    // Delivery partner marker on map
    WebElement partnerMarker = wait.until(
        ExpectedConditions.presenceOfElementLocated(By.cssSelector(".delivery-partner-marker"))
    );
    Assert.assertTrue(partnerMarker.isDisplayed(), "Partner location marker should be on map");

    // ETA should show time remaining
    WebElement eta = driver.findElement(By.cssSelector("[data-testid='eta-countdown']"));
    String etaText = eta.getText();
    Assert.assertTrue(etaText.matches("\d+ min(s?)"), "ETA should show minutes: " + etaText);

    // Call partner button
    Assert.assertTrue(
        driver.findElement(By.cssSelector("[data-testid='call-partner-btn']")).isEnabled()
    );
}
Q4 Test cases for Zomato restaurant listing page — menu, reviews, ordering.
Medium · Restaurant Listing · Zomato Tech
Menu: categories displayed, items with name/price/description/image, veg/non-veg badge correct, customization options available. Reviews: rating shown as X.X/5, review count accurate, top reviews by helpful votes. Ordering: Add to Cart works, quantity selector, special instructions field. Closed restaurant: add to cart disabled, next opening time shown.
Q5 Test strategy for Zomato Hyperpure — the B2B ingredient supply platform for restaurants.
Hard · Hyperpure B2B · Zomato Tech
Supplier onboarding: GST/FSSAI document upload, verification workflow. Catalog: search ingredients, bulk ordering with tiered pricing. Order flow: cart → checkout → delivery scheduling. Invoice: GST invoice auto-generated, downloadable PDF. Inventory alerts: low stock notification to restaurant manager. Access control: manager vs staff role permissions correctly enforced.
💡 Hyperpure is Zomato's less-known but strategically important product. Mentioning domain knowledge of Hyperpure shows you've done your homework beyond just the consumer app.
Q6 Write REST Assured tests for Zomato order placement API.
Medium · API Testing · Zomato Tech
POST /api/v2/orders with restaurant_id, items[], delivery_address_id, payment_method. Assert: 201 with order_id, estimated_delivery_time, total_amount correct. Negative: restaurant closed → 400, item unavailable → 400, invalid address → 400, expired payment token → 401.
@Test
public void placeOrder_ValidInput_Returns201WithOrderDetails() {
    String requestBody = """
        {
            "restaurantId": "REST_TEST_001",
            "items": [
                {"itemId": "ITEM_001", "quantity": 2, "customization": "no onion"},
                {"itemId": "ITEM_002", "quantity": 1}
            ],
            "deliveryAddressId": "ADDR_TEST_001",
            "paymentMethod": "UPI",
            "couponCode": "FIRST10"
        }""";

    given()
        .header("Authorization", "Bearer " + getUserToken())
        .body(requestBody).contentType(ContentType.JSON)
    .when().post("/api/v2/orders")
    .then()
        .statusCode(201)
        .body("orderId", startsWith("ZOM"))
        .body("status", equalTo("ACCEPTED"))
        .body("estimatedDeliveryMinutes", both(greaterThan(15)).and(lessThan(90)))
        .body("totalAmount", greaterThan(0f))
        .body("discountApplied", greaterThan(0f))  // coupon applied
        .time(lessThan(2000L));  // order placement SLA
}
Q7 Test Zomato Pro / Gold membership benefits — discounts, free delivery, priority support.
Medium · Subscription Testing · Zomato Tech
Discount: Pro member sees correct discount at checkout (verify it's applied, not just shown). Free delivery: delivery fee waived for eligible orders. Benefit limit: only N free deliveries per month — N+1 charged normally. Expiry: membership expired → benefits removed immediately. Renewal: auto-renewal charge on correct date, notifications sent.
Q8 How do you performance test Zomato during Diwali (peak food orders)?
Hard · Performance Testing · Zomato Tech
Diwali = 5× normal order volume. JMeter: 5× baseline TPS across search/order APIs. Identify: hotspot restaurants (top 50 by volume) pre-warm cache. Test: search p95 <500ms, order placement p95 <2s. Soak test: sustained 3× load for 4 hours — check for memory leaks in order service. Chaos: kill recommendation service — order flow must continue (graceful degradation).
Q9 How do you structure your Selenium framework for Zomato's web application?
Medium · Automation Framework · Zomato Tech
Page Object Model + TestNG + Java. BaseTest handles driver init (ThreadLocal WebDriver for parallel). Page classes: HomePage, RestaurantPage, CartPage, CheckoutPage, OrderTrackingPage. Utilities: WaitHelper, ScreenshotHelper, AllureReporter. testng.xml: parallel="methods" thread-count=5. Config: environment (prod/staging/dev) via System.getProperty("env").
public class RestaurantPage extends BasePage {
    @FindBy(css = "[data-testid='restaurant-name']")
    private WebElement restaurantName;
    
    @FindBy(css = "[data-testid='add-to-cart-btn']")
    private List<WebElement> addToCartButtons;
    
    @FindBy(css = "[data-testid='menu-category']")
    private List<WebElement> menuCategories;

    public RestaurantPage(WebDriver driver) { super(driver); }

    public String getRestaurantName() {
        return waitForVisible(restaurantName).getText();
    }

    public CartPage addFirstItemToCart() {
        waitForElements(addToCartButtons).get(0).click();
        return new CartPage(driver);
    }

    public int getMenuCategoryCount() {
        return waitForElements(menuCategories).size();
    }
}
💡 Zomato interviewers move fast — give concise, structured answers. They prefer 2 strong points with examples over 5 vague points.
Q10 Where do you see QA automation heading in 3 years? How are you preparing for it?
Behavioral · Career Goals · Zomato HR
Trend 1: AI-assisted test generation — tools like GitHub Copilot already suggest test cases. SDETs will shift from writing boilerplate to reviewing and curating AI-generated tests. Trend 2: Shift-further-left — QA embedded in design and requirements, not just code review. Trend 3: Production as test environment — canary deploys, feature flags, and real user monitoring replace traditional test environments at scale. My preparation: learning k6 for performance-as-code, exploring Playwright's AI locators, contributing to open-source test tools.
💡 Zomato values engineers with genuine intellectual curiosity about the future of their craft. Don't give a generic answer — mention 1 specific tool or technique you've been exploring recently.
🔵

Atlassian Interview Process

Global Product · Jira · Confluence · Remote-First · 4 Rounds

📋 Take-Home → Technical ×2 → Values Round🎯 SDET · QA Engineer · SET📍 Sydney AU · Remote Global

💻 Coding Round

Atlassian prioritizes code quality over speed. They do code reviews during the interview. Write clean, readable, well-named code. Comment non-obvious logic. They test algorithmic thinking and OOP design.

Q1 Find minimum number of sprints to complete all Jira tickets given their dependencies.
Hard · Topological Sort · Atlassian Coding
Build directed graph from dependencies. Topological sort using BFS (Kahn's algorithm). Each BFS level = 1 sprint. Count levels. If cycle exists → impossible (return -1). O(V+E).
public int minSprints(int n, int[][] deps) {
    int[] indegree = new int[n + 1];
    List<List<Integer>> adj = new ArrayList<>();
    for (int i = 0; i <= n; i++) adj.add(new ArrayList<>());

    for (int[] dep : deps) {
        adj.get(dep[1]).add(dep[0]);   // dep[1] must complete before dep[0]
        indegree[dep[0]]++;
    }

    Queue<Integer> queue = new LinkedList<>();
    for (int i = 1; i <= n; i++)
        if (indegree[i] == 0) queue.offer(i);

    int sprints = 0, processed = 0;
    while (!queue.isEmpty()) {
        int size = queue.size();
        sprints++;
        for (int i = 0; i < size; i++) {
            int ticket = queue.poll();
            processed++;
            for (int next : adj.get(ticket))
                if (--indegree[next] == 0) queue.offer(next);
        }
    }
    return processed == n ? sprints : -1;  // -1 if cycle detected
}
// 6 tickets, deps=[[2,1],[3,1],[4,2],[5,3]] → 3 sprints
💡 Atlassian domain context: "Jira tickets" makes this feel real. Always handle the cycle case (circular dependency = impossible to complete). Atlassian values this edge case handling.
Q2 Design a custom HashMap from scratch (without using Java's HashMap).
Medium · Design · OOP · Atlassian Coding
Array of LinkedLists (separate chaining). hashCode() % capacity for bucket index. Handle collision by chaining. Resize when load factor > 0.75 — new array double size, rehash all entries.
class MyHashMap<K, V> {
    private static final int DEFAULT_CAPACITY = 16;
    private static final float LOAD_FACTOR = 0.75f;
    private LinkedList<Entry<K,V>>[] buckets;
    private int size;

    @SuppressWarnings("unchecked")
    public MyHashMap() { buckets = new LinkedList[DEFAULT_CAPACITY]; }

    public void put(K key, V value) {
        int idx = getIndex(key);
        if (buckets[idx] == null) buckets[idx] = new LinkedList<>();
        for (Entry<K,V> e : buckets[idx]) {
            if (e.key.equals(key)) { e.value = value; return; }
        }
        buckets[idx].add(new Entry<>(key, value));
        size++;
        if ((float) size / buckets.length > LOAD_FACTOR) resize();
    }

    public V get(K key) {
        int idx = getIndex(key);
        if (buckets[idx] == null) return null;
        for (Entry<K,V> e : buckets[idx])
            if (e.key.equals(key)) return e.value;
        return null;
    }

    private int getIndex(K key) {
        return Math.abs(key.hashCode()) % buckets.length;
    }

    private void resize() {
        LinkedList<Entry<K,V>>[] old = buckets;
        buckets = new LinkedList[old.length * 2];
        size = 0;
        for (LinkedList<Entry<K,V>> bucket : old)
            if (bucket != null) for (Entry<K,V> e : bucket) put(e.key, e.value);
    }

    static class Entry<K,V> { K key; V value; Entry(K k, V v){key=k;value=v;} }
}
💡 Atlassian code review note: they'll ask "What happens if key is null?" and "What's the worst case for get()?" Have answers ready: null keys need special handling (like Java's HashMap), worst case O(n) if everything hashes to same bucket.
Q3 Given a list of Jira issues, return only those that have ALL specified labels.
Medium · Java Streams · Atlassian Domain Coding
Use Java Streams with filter. Issue's label set must containsAll(required labels). Efficient: O(n × |required|) where n = issue count.
public List<Issue> filterByAllLabels(List<Issue> issues, Set<String> required) {
    if (required == null || required.isEmpty()) return issues;
    return issues.stream()
        .filter(issue -> issue.getLabels() != null &&
                         issue.getLabels().containsAll(required))
        .sorted(Comparator.comparing(Issue::getPriority))
        .collect(Collectors.toList());
}

// Test cases:
// Issue with labels {bug, backend, critical} - required {bug, backend} → INCLUDED
// Issue with labels {bug, frontend}          - required {bug, backend} → EXCLUDED
// Issue with labels {}                       - required {bug}          → EXCLUDED
// required = {}                              - all issues              → ALL INCLUDED
💡 Clean code note: extract the filter predicate to a named method for readability. Atlassian values self-documenting code.
Q4 Implement a thread-safe test execution counter — running, completed, failed counts.
Medium · Concurrency · Atlassian Coding
Use AtomicInteger for each counter — lock-free, thread-safe for single operations. Or use synchronized if multiple fields must update atomically.
public class TestExecutionCounter {
    private final AtomicInteger running   = new AtomicInteger(0);
    private final AtomicInteger completed = new AtomicInteger(0);
    private final AtomicInteger failed    = new AtomicInteger(0);

    public void onTestStart()  { running.incrementAndGet(); }
    public void onTestPass()   { running.decrementAndGet(); completed.incrementAndGet(); }
    public void onTestFail()   { running.decrementAndGet(); failed.incrementAndGet(); }

    public void printSummary() {
        System.out.printf("Running: %d | Passed: %d | Failed: %d | Total: %d%n",
            running.get(), completed.get(), failed.get(),
            completed.get() + failed.get());
    }

    public double getPassRate() {
        int total = completed.get() + failed.get();
        return total == 0 ? 0.0 : (double) completed.get() / total * 100;
    }
}
// Thread-safe: AtomicInteger guarantees visibility and atomicity
Q5 Implement a sliding window rate limiter — allow max N requests per minute per user.
Hard · Rate Limiting · Atlassian Coding
Use a ConcurrentHashMap of user → Deque of timestamps. On each request, evict timestamps older than 60 seconds, then check if size >= N. If yes, reject. If no, add current timestamp and allow.
public class SlidingWindowRateLimiter {
    private final ConcurrentHashMap<String, Deque<Long>> userRequests = new ConcurrentHashMap<>();
    private final int maxRequests;
    private final long windowMs;

    public SlidingWindowRateLimiter(int maxRequests, long windowMs) {
        this.maxRequests = maxRequests;
        this.windowMs = windowMs;
    }

    public synchronized boolean allow(String userId) {
        long now = System.currentTimeMillis();
        userRequests.putIfAbsent(userId, new ArrayDeque<>());
        Deque<Long> timestamps = userRequests.get(userId);

        // Remove timestamps outside the window
        while (!timestamps.isEmpty() && now - timestamps.peekFirst() >= windowMs)
            timestamps.pollFirst();

        if (timestamps.size() >= maxRequests) return false;

        timestamps.addLast(now);
        return true;
    }
}
// SlidingWindowRateLimiter limiter = new SlidingWindowRateLimiter(100, 60_000);
// limiter.allow("user123") → true (if < 100 requests in last 60s)
💡 Atlassian follow-up: "How would you make this work across multiple servers?" Answer: use Redis with ZADD + ZREMRANGEBYSCORE + ZCARD for distributed rate limiting.
Q6 Flatten a nested JSON structure to dot-notation keys.
Medium · Recursion · Atlassian Coding
Recursive DFS through the map. When value is another Map, recurse with prefix. When value is primitive, add to result with full dotted key.
public Map<String, Object> flatten(Map<String, Object> nested, String prefix) {
    Map<String, Object> flat = new LinkedHashMap<>();
    nested.forEach((key, value) -> {
        String fullKey = prefix.isEmpty() ? key : prefix + "." + key;
        if (value instanceof Map) {
            @SuppressWarnings("unchecked")
            Map<String, Object> nestedMap = (Map<String, Object>) value;
            flat.putAll(flatten(nestedMap, fullKey));
        } else {
            flat.put(fullKey, value);
        }
    });
    return flat;
}

// Input:  {"a": {"b": {"c": 1}, "d": 2}, "e": 3}
// Output: {"a.b.c": 1, "a.d": 2, "e": 3}

// Test cases:
// Empty map → empty map
// Single level → keys unchanged
// Deep nesting → all leaf keys with full path
// List values → stored as-is (not recursed)
💡 Atlassian uses this pattern for config management and Jira field mapping. Showing domain context ("useful for Jira custom field flattening") earns points.
Q7 Implement the Observer pattern — used for Jira notification system.
Medium · Design Pattern · Atlassian Coding
Subject (IssueTracker) maintains list of observers. When issue state changes, notifies all observers. Observers implement update() interface.
public interface JiraObserver {
    void onIssueUpdate(String issueId, String newStatus, String assignee);
}

public class IssueTracker {
    private final List<JiraObserver> observers = new ArrayList<>();
    private final Map<String, String> issueStatus = new HashMap<>();

    public void subscribe(JiraObserver observer)   { observers.add(observer); }
    public void unsubscribe(JiraObserver observer) { observers.remove(observer); }

    public void updateIssueStatus(String issueId, String newStatus, String assignee) {
        issueStatus.put(issueId, newStatus);
        // Notify all observers
        observers.forEach(o -> o.onIssueUpdate(issueId, newStatus, assignee));
    }
}

// Usage:
IssueTracker tracker = new IssueTracker();
tracker.subscribe((id, status, assignee) ->
    System.out.println("Email sent: " + id + " → " + status));
tracker.subscribe((id, status, assignee) ->
    slackBot.notify("#eng-channel", id + " assigned to " + assignee));
tracker.updateIssueStatus("PROJ-123", "In Progress", "john.doe");
Q8 Parse a JQL (Jira Query Language) filter string: "project = MYPROJ AND status = Open".
Medium · String Processing · Atlassian Coding
Tokenize by AND/OR. Each condition: split on first space+operator+space. Build a list of Condition objects (field, operator, value). Return as a query object that can be applied to filter issues.
public class JQLParser {
    record Condition(String field, String operator, String value) {}

    public List<Condition> parse(String jql) {
        List<Condition> conditions = new ArrayList<>();
        // Split on AND/OR (simplified - treats all as AND)
        String[] parts = jql.split("\s+(?i)AND\s+");
        for (String part : parts) {
            // Split on operator: =, !=, ~, in, not in
            String[] tokens = part.trim().split("\s+", 3);
            if (tokens.length == 3) {
                conditions.add(new Condition(
                    tokens[0].trim(),
                    tokens[1].trim(),
                    tokens[2].trim().replaceAll("^\"|\"$", "") // remove quotes
                ));
            }
        }
        return conditions;
    }
}
// "project = MYPROJ AND status = Open AND assignee = john"
// → [{project,=,MYPROJ}, {status,=,Open}, {assignee,=,john}]
Q9 Given sprint velocity history, predict next sprint velocity using weighted moving average.
Hard · Algorithm · Atlassian Coding
Weighted Moving Average: more recent sprints get higher weights. Weight = position in window (oldest=1, newest=n). Weighted sum / sum of weights.
public double predictVelocity(double[] history, int windowSize) {
    if (history.length == 0) return 0.0;
    int start = Math.max(0, history.length - windowSize);
    double weightedSum = 0.0, totalWeight = 0.0;

    for (int i = start; i < history.length; i++) {
        double weight = i - start + 1;  // 1, 2, 3, ... (most recent = highest)
        weightedSum += history[i] * weight;
        totalWeight += weight;
    }
    return Math.round(weightedSum / totalWeight * 10.0) / 10.0;
}

// history = [20, 22, 18, 25, 23], windowSize = 3
// Uses [18, 25, 23] with weights [1, 2, 3]
// = (18×1 + 25×2 + 23×3) / (1+2+3) = (18+50+69)/6 = 137/6 ≈ 22.8
💡 Atlassian context: this is used in Jira Advanced Roadmaps for sprint planning. The weighted average prevents one outlier sprint from skewing the forecast.
Q10 How do you decide when to automate a test vs keep it manual?
Medium · Testing Strategy · Atlassian Values
Automate when: test runs frequently (every regression), inputs are well-defined and stable, test is deterministic, ROI positive within 3 sprints (creation time < time saved over 3 months). Keep manual when: exploratory testing, one-time feature validation, highly dynamic UI that breaks locators constantly, visual aesthetics judgment. ROI formula: (Time saved per run × runs per year) - (creation time + annual maintenance). If > 0, automate.
// ROI Calculation Example:
// Manual test time:     20 minutes per run
// Runs per year:        52 (weekly regression)
// Manual total:         20 × 52 = 1040 min/year

// Automation creation:  3 hours = 180 min
// Automation run time:  2 min per run
// Automation total:     3h create + (2 × 52) = 180 + 104 = 284 min/year

// Year 1 savings:       1040 - 284 = 756 min (12.6 hours)
// Year 2+ savings:      1040 - 104 = 936 min/year (15.6 hours)
// → Automate: ROI positive from year 1
💡 Atlassian interviewers appreciate candidates who think about ROI and maintenance cost, not just "automate everything." The maintenance cost of bad automation is often worse than manual testing.

🌟 Values Round

Atlassian evaluates 5 core values: Open company no bullshit · Don't #@!% the customer · Play as a team · Be the change you seek · Build with heart and balance.

Q1 Give an example where you were "the change you sought" — improved something proactively.
Behavioral · Be the Change · Atlassian Values
Show you noticed a problem, quantified its cost, fixed it without being asked, measured the result, and shared the improvement with others. The key is proactivity — you didn't wait for someone to assign you a ticket.
// Strong answer pattern:
// "I noticed our onboarding docs caused every new SDET to spend
//  3 days on environment setup. Not in my JIRA backlog.
//  Spent one weekend documenting it with screenshots and video walkthroughs.
//  New hire ramp-up time dropped from 3 days to 4 hours.
//  The docs became the official onboarding guide — now maintained by the team."

// Key elements:
// 1. Problem: specific, with a cost (3 days × N people)
// 2. Action: you took it personally (one weekend)
// 3. Result: measurable (3 days → 4 hours)
// 4. Leverage: others now benefit (team maintains it)
💡 Atlassian scores on: (1) Did you act without being asked? (2) Did you measure the improvement? (3) Did you make it sustainable for others? Numbers matter.
Q2 Tell me about a time you prioritized the customer's experience over internal convenience.
Behavioral · Customer First · Atlassian Values
Example: delayed a release to fix a customer-facing bug even though it pushed the sprint, OR spent extra time writing user-friendly error messages instead of technical stack traces, even under deadline pressure. Show the trade-off was real and you chose the customer.
💡 Atlassian's "Don't #@!% the customer" value is literal — they hold it sacred. Your story must involve a genuine sacrifice (time, effort, comfort) for the customer benefit.
Q3 Describe a time you helped a teammate who was struggling.
Behavioral · Teamwork · Atlassian Values
Specific person, specific struggle, how you helped (pair programming, shadowing, documentation, emotional support), measurable outcome. Show you invested your own time unprompted. "We" succeeded, not just "I helped them."
Q4 How do you maintain work-life balance on a demanding project?
Behavioral · Balance · Atlassian Values
Be genuinely honest — Atlassian walks the talk on balance (TEAM Anywhere, flexible hours). Show you set real boundaries, communicate proactively about capacity, take proper breaks. If you've had burnout, mention what you learned and what you changed.
💡 Atlassian TEAM Anywhere (remote-first) means they genuinely care about this. The wrong answer is "I work as hard as needed until it's done" — that signals future burnout problems.
Q5 Tell me about a time you made a mistake that affected others. What did you do?
Behavioral · Transparency · Atlassian Values
Own it completely. Immediately notify those affected (no hiding). Fix the issue. Do a blameless post-mortem. Add a permanent safeguard so it can't happen again. Atlassian's "open company no BS" value means they want transparent ownership, not defensive excuses.
// Post-mortem structure (blameless):
// 1. Timeline of what happened
// 2. Impact: who was affected, for how long
// 3. Root cause (the system/process, not a person)
// 4. Contributing factors
// 5. What we fixed immediately
// 6. What we changed permanently (process/test/alert)
// 7. Key learnings for the team
Q6 Describe a time you gave difficult feedback that was hard to deliver.
Behavioral · Direct Feedback · Atlassian Values
Show you gave direct, kind feedback — not passive aggressive, not via manager. Describe how you framed it as impact on the team, not attack on the person (SBI: Situation-Behaviour-Impact). How the person received it. What changed.
// SBI Feedback Model:
// Situation: "In yesterday's code review for PR-442..."
// Behaviour: "you approved the PR without running the tests locally..."
// Impact: "...which caused the main branch to fail, blocking 4 other engineers for 2 hours."
// Then: "I'd like us to agree on a definition of done for code reviews. Can we talk about it?"

// NOT: "You always do this" or "Your code quality is bad"
Q7 Tell me about a time you had to make progress on a project with unclear requirements.
Behavioral · Ambiguity · Atlassian Values
Show you didn't wait for perfect clarity. Identified the 2-3 key assumptions, documented them, validated the riskiest ones cheaply (spike/prototype/stakeholder interview), shipped iteratively. Updated stakeholders as understanding evolved.
Q8 What's the most interesting technical thing you've learned in the last 6 months?
Behavioral · Learning · Atlassian Values
Be specific and genuine. Pick something you actually explored — a new testing framework, a paper on distributed testing, a production incident post-mortem from another company's engineering blog. Show intellectual curiosity, not rote learning.
💡 Atlassian teams include some of the industry's best engineers — they want colleagues who learn continuously and share knowledge. If you can't name something specific from the last 6 months, that's a flag.
Q9 Describe a time you collaborated with people outside engineering (PM, Design, Customer Success).
Behavioral · Cross-functional · Atlassian Values
Show you bridge communication gaps between technical and non-technical stakeholders. Translated test results into business impact for PM. Worked with UX to identify usability issues during testing. Helped Customer Success reproduce a customer-reported bug.
Q10 Why Atlassian? What specifically excites you about improving Jira or Confluence?
Behavioral · Why Atlassian · Atlassian Values
Be specific to their products. Jira/Confluence are used by 300K+ companies — quality issues you fix affect millions of engineers daily. Name something specific from their engineering blog or a product decision you admire. Show you use their tools and have opinions about making them better.
// Strong answer elements:
// 1. Specific product/team you're joining (not just "Atlassian")
// 2. Scale argument: quality in Jira → impact on millions of dev teams
// 3. Reference something from Atlassian Engineering blog
// 4. A specific product pain point you want to help solve
// 5. How your background uniquely fits their challenges
💡 Read the Atlassian Engineering blog and Team Anywhere blog before the interview. Mentioning a specific engineering decision or blog post shows genuine interest — not just "great company culture."
🌐

Wipro Interview Process

IT Services · MNC · Bangalore HQ · 2–3 Rounds

📋 WILP/OA → Technical → HR🎯 Test Engineer · QA Lead📍 Pan-India + Global

🔬 Technical Interview

Wipro Technical: QA fundamentals, STLC, testing types, basic Selenium, SQL. More theory-oriented than product companies. Communication skills are assessed equally with technical knowledge.

Q1 Explain the Software Testing Life Cycle (STLC) — all 6 phases with QA's role in each.
Easy · STLC · Wipro Technical
(1) Test Planning: QA writes test strategy, estimates resources and timeline, defines scope and entry/exit criteria. (2) Test Analysis: QA reviews requirements for testability, identifies what to test, creates traceability matrix. (3) Test Design: QA writes test cases, prepares test data, defines test environment requirements. (4) Test Environment Setup: QA/DevOps installs and configures test environment, loads test data. (5) Test Execution: QA runs tests, logs defects in Jira/JIRA, tracks defect lifecycle, re-tests fixes. (6) Test Closure: QA analyzes metrics (defect density, coverage), writes test summary report, archives test artifacts.
💡 Wipro asks this in almost every QA interview. Know all 6 phases with entry/exit criteria for each. Common mistake: starting STLC only after code is ready — correct answer is QA involvement starts from requirements phase.
Q2 Explain the complete defect life cycle with all states and transitions.
Easy · Defect Lifecycle · Wipro Technical
States: New (just logged) → Assigned (to developer) → Open (dev working on it) → Fixed (dev marks resolved) → Retest (QA verifies fix) → Verified (fix confirmed working) → Closed (officially done). Other paths: Rejected (not a defect / cannot reproduce / duplicate) → Closed. Deferred (postponed to future release). Won't Fix (accepted risk, business decision). Reopened (fix didn't work → back to Assigned).
💡 Draw the state diagram mentally. The most confused state is Verified vs Closed — Verified means the fix works, Closed is the final state after sign-off.
Q3 Find the second largest element in an array without sorting.
Easy · Java Basics · Wipro OA
Single pass with two variables: first (largest) and second (second largest). For each element: if larger than first, update both. If between first and second, update only second.
public int secondLargest(int[] arr) {
    int first = Integer.MIN_VALUE;
    int second = Integer.MIN_VALUE;
    for (int n : arr) {
        if (n > first) {
            second = first;
            first = n;
        } else if (n > second && n != first) {
            second = n;
        }
    }
    if (second == Integer.MIN_VALUE)
        throw new IllegalArgumentException("No second largest element");
    return second;
}
// [1,2,3,4,5] → 4
// [5,5,5,5]   → throws exception (no distinct second largest)
// [1]          → throws exception
💡 Edge case that Wipro specifically looks for: n != first condition prevents same value counting as second. Also handle array with all identical elements.
Q4 What is the difference between Functional and Non-Functional testing? Give 3 examples of each.
Medium · Testing Types · Wipro Technical
Functional testing: Tests what the system DOES — features, business logic, data handling. Examples: (1) Login with valid credentials succeeds. (2) Shopping cart calculates total correctly. (3) Search returns relevant results. Non-functional testing: Tests how WELL the system performs. Examples: (1) Performance — page loads in <2s for 1000 concurrent users. (2) Security — SQL injection attempt returns error, not data. (3) Usability — new user can complete checkout without instructions.
Q5 Write SQL to find employees with salary above department average.
Easy · SQL · Wipro Technical
Correlated subquery or window function. Correlated subquery: for each employee, check if salary > average salary of their department.
-- Method 1: Correlated subquery
SELECT e.name, e.department, e.salary
FROM employees e
WHERE e.salary > (
    SELECT AVG(salary)
    FROM employees
    WHERE department = e.department
);

-- Method 2: Window function (more efficient)
SELECT name, department, salary FROM (
    SELECT name, department, salary,
           AVG(salary) OVER (PARTITION BY department) AS dept_avg
    FROM employees
) t
WHERE salary > dept_avg;
Q6 Write Selenium code to handle a dropdown and verify selected value.
Easy · Selenium · Wipro Technical
Use the Select class for native HTML HTML elements. If it's a custom component, always use click + wait + click.
Q7 Write test cases for a Login page — cover positive, negative, and edge cases.
Easy · Test Design · Wipro Technical
Positive: Valid email + valid password → logged in, redirected to dashboard. Negative: Wrong password → error message (don't reveal whether email exists). Wrong email format → validation error. Empty username → "required" error. Empty password → "required" error. Security: SQL injection in username ('OR 1=1--) → error, not logged in. XSS in username () → sanitized. Max failed attempts (5) → account lock. Edge: Password with special characters. Very long input (10,000 chars). Password with spaces.
Q8 What is Agile? What is your role as a QA in an Agile team?
Easy · Agile · Wipro Technical
Agile = iterative development in 2-4 week sprints. QA's role in each ceremony: Backlog Grooming: review stories for testability, write acceptance criteria. Sprint Planning: estimate test effort, flag unclear requirements. Daily Standup: report blockers, test progress. Sprint Review: demo sign-off, verify acceptance criteria. Retrospective: suggest quality improvements, celebrate quality wins.
Q9 Write SQL to find duplicate email addresses in a users table.
Medium · SQL · Wipro Technical
Use GROUP BY with HAVING COUNT > 1 to find duplicates.
-- Find duplicate emails with count
SELECT email, COUNT(*) as cnt
FROM users
GROUP BY email
HAVING COUNT(*) > 1
ORDER BY cnt DESC;

-- Find all user records that are duplicates
SELECT * FROM users
WHERE email IN (
    SELECT email FROM users
    GROUP BY email
    HAVING COUNT(*) > 1
)
ORDER BY email;

-- Delete duplicates keeping lowest id
DELETE FROM users
WHERE id NOT IN (
    SELECT MIN(id) FROM users GROUP BY email
);
Q10 How do you write a good bug report? What fields must it contain?
Easy · Bug Reporting · Wipro Technical
Mandatory fields: (1) Title — clear and specific ("Login fails with valid Gmail credentials on Chrome 120 mobile"). (2) Steps to Reproduce — numbered, precise steps. (3) Expected Result — what should happen. (4) Actual Result — what actually happened. (5) Severity and Priority. (6) Environment — OS, browser, app version. (7) Screenshots/videos. (8) Frequency — always/intermittent. Good vs Bad title: Bad: "Login not working". Good: "Login fails with error 500 when password contains special characters on iOS 17".
// Bug Report Template:
// Title: [Component] Brief description of issue
// Severity: Critical/Major/Minor/Trivial
// Priority: High/Medium/Low
//
// Environment:
//   OS: Windows 11 / macOS 14 / iOS 17
//   Browser: Chrome 120 / Safari 17
//   App Version: v2.4.1
//
// Steps to Reproduce:
//   1. Navigate to https://app.example.com/login
//   2. Enter email: test@gmail.com
//   3. Enter password: Test@123!
//   4. Click "Sign In" button
//
// Expected: User is logged in and redirected to dashboard
// Actual: Error "Invalid credentials" shown despite correct credentials
//
// Frequency: 100% reproducible
// Attachment: screenshot_login_error.png
💡 Wipro values well-structured bug reports. A complete, clear bug report is one of the top skills they test for QA roles.
🧠

Cognizant Interview Process

IT Services · MNC · Chennai / Pan-India · 2–3 Rounds

📋 GenC OA → Technical → HR🎯 Test Analyst · QA Engineer📍 Chennai · Bangalore · Pune

🔬 Technical Interview

Cognizant Technical: QA concepts, manual testing, basic automation, and project discussion. Be ready to discuss a full testing project end-to-end. Cognizant values structured communication.

Q1 What are the 4 levels of software testing? Explain each with an example.
Easy · Testing Levels · Cognizant Technical
Unit Testing: Test individual functions in isolation. Developer-owned. Example: test that calculateTax(100, 18) returns 118. Integration Testing: Test interaction between modules. Example: test that the Login service correctly calls the Database service and returns the right user. System Testing: Test the complete integrated system. Example: test the entire e-commerce flow from search to checkout. Acceptance Testing (UAT): End users verify the system meets business requirements. Example: client verifies that all specified features work as described in requirements.
💡 Remember the order: unit (smallest) → integration → system → acceptance (largest scope). Each level catches different types of defects.
Q2 Explain Equivalence Partitioning and Boundary Value Analysis with an example.
Easy · Test Design · Cognizant Technical
Equivalence Partitioning (EP): Divide inputs into groups (partitions) where all values behave the same. Test 1 value from each partition. Example (age field 1–120): Valid partition (1–120) → test 60. Below valid (<1) → test 0. Above valid (>121) → test 150. Boundary Value Analysis (BVA): Test values at the edges of partitions where bugs most often occur. For the same example: test 0, 1, 2 (lower boundary), 119, 120, 121 (upper boundary). Together EP+BVA give maximum coverage with minimum test cases.
// Example: password length must be 8-20 characters
// EP Partitions:
//   Valid:       8–20 chars   → test "Password1"  (9 chars)
//   Too short:   1–7 chars    → test "Pass" (4 chars)
//   Too long:    >20 chars    → test 25-char string

// BVA (at boundaries):
//   7 chars   → INVALID (just below lower bound)
//   8 chars   → VALID   (lower bound)
//   9 chars   → VALID   (just above lower bound)
//   20 chars  → VALID   (upper bound)
//   21 chars  → INVALID (just above upper bound)
Q3 Find all pairs in an array that sum to a given target value.
Easy · Java · Cognizant OA
Use a HashSet. For each element, check if target-element exists in the set. If yes, found a pair. If no, add element to set.
public void findPairs(int[] arr, int target) {
    Set<Integer> seen = new HashSet<>();
    Set<String> printed = new HashSet<>();  // avoid duplicate pairs
    for (int n : arr) {
        int complement = target - n;
        if (seen.contains(complement)) {
            // Create canonical pair representation (smaller first)
            String pair = Math.min(n, complement) + "+" + Math.max(n, complement);
            if (printed.add(pair)) {
                System.out.println(complement + " + " + n + " = " + target);
            }
        }
        seen.add(n);
    }
}
// [1,2,3,4,5,6] target=7 → (1,6), (2,5), (3,4)
// [1,1,2,4,4] target=5  → (1,4)
Q4 What is regression testing? When and why do you perform it?
Easy · Testing Types · Cognizant Technical
Regression testing verifies that existing functionality still works correctly after any change to the codebase (new feature, bug fix, refactoring, config change). When: after every code change, before every release, after environment updates. Why: changes in one area can unknowingly break other areas — "ripple effect." Scope: depends on risk — full regression (all features) vs selective regression (only areas affected by the change). Usually automated because regression tests run frequently.
Q5 Describe the SDLC phases and QA's involvement in each phase.
Easy · SDLC · Cognizant Technical
Requirements: QA reviews for testability, ambiguity, and completeness. Creates requirements traceability matrix. System Design: QA creates test strategy and master test plan. Reviews architecture for testability hooks. Implementation: QA writes detailed test cases, prepares test data, sets up test environment. Testing: QA executes tests, logs defects, retests fixes, tracks progress. Deployment: QA performs smoke tests in production/UAT. Maintenance: QA performs regression on patches and updates.
Q6 Write SQL queries using GROUP BY, HAVING, and window functions.
Medium · SQL · Cognizant Technical
GROUP BY groups rows with same values. HAVING filters groups (like WHERE for aggregates). Window functions operate on a set of rows without collapsing them.
-- GROUP BY + HAVING: departments with more than 3 employees
SELECT department, COUNT(*) as emp_count, AVG(salary) as avg_salary
FROM employees
GROUP BY department
HAVING COUNT(*) > 3
ORDER BY avg_salary DESC;

-- Window function: rank employees by salary within department
SELECT name, department, salary,
       RANK()       OVER (PARTITION BY department ORDER BY salary DESC) AS rank_in_dept,
       DENSE_RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dense_rank,
       ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS row_num,
       SUM(salary)  OVER (PARTITION BY department) AS dept_total_salary
FROM employees;

-- Running total of sales by date
SELECT date, amount,
       SUM(amount) OVER (ORDER BY date) AS running_total
FROM sales;
💡 Know the difference: RANK() leaves gaps (1,2,2,4), DENSE_RANK() no gaps (1,2,2,3), ROW_NUMBER() always unique (1,2,3,4).
Q7 What is a test plan? What does it contain?
Easy · Test Documentation · Cognizant Technical
A test plan is a formal document describing the testing approach for a project. It contains: (1) Test scope — what will and won't be tested. (2) Test objectives — what the testing aims to achieve. (3) Test strategy — types of testing, techniques, tools. (4) Resources — team members, roles, responsibilities. (5) Schedule — timeline, milestones. (6) Entry/Exit criteria — when testing starts and when it's complete. (7) Risk assessment — potential risks and mitigations. (8) Test deliverables — test cases, reports, metrics.
Q8 What are the advantages and disadvantages of test automation?
Easy · Automation Basics · Cognizant Technical
Advantages: Faster execution (minutes vs hours for regression), consistent (no human error), runs 24/7 unattended, reusable across releases, better ROI for repetitive tests, enables faster release cycles. Disadvantages: High initial setup cost (time and skill), maintenance required when UI changes, doesn't replace exploratory/usability testing, can give false confidence (green tests with poor coverage), requires programming skills.
Q9 Describe a project you tested end-to-end. What was your approach?
Medium · Project Discussion · Cognizant Technical
Structure your answer: Project overview (domain, technology, team size). Your role and responsibilities. Testing approach: types of testing performed, tools used, test design techniques. Challenges faced (unclear requirements, tight timeline, flaky tests). How you resolved challenges. Metrics: test coverage %, defects found, defect escape rate. Lessons learned.
// Answer template:
// "I tested a [domain] application using [tech stack].
//  My responsibilities included [specific tasks].
//  Testing types: functional (Selenium), API (REST Assured), performance (JMeter).
//  Key challenge: [specific challenge].
//  Resolution: [how I solved it].
//  Outcome: found [N] defects, [X]% escaped to production (down from [Y]%).
//  What I'd do differently: [specific improvement]."
💡 Prepare 2 project examples before the interview — one automation-focused, one manual testing focused. Cognizant interviewers often ask follow-up questions about specific tools and metrics.
Q10 Why do you want to join Cognizant? What are your strengths?
Easy · HR Basics · Cognizant HR
Why Cognizant: Multi-domain exposure (banking, healthcare, retail, manufacturing) from a single company. Cognizant's learning platforms (Cognizant Academy, external training budget). Global delivery model for international project exposure. Large QA practice with established methodology and tools. Strength format: Pick one that directly helps QA — "attention to detail that catches edge cases developers miss." Give a specific example. Avoid generic strengths like "hardworking."
💡 Research Cognizant's specific service lines (NextGen, Intelligent Automation, etc.) before the interview. Mentioning their specific AI testing tools or methodology shows preparation.

HCL Technologies Interview Process

IT Services · MNC · Noida HQ · 2–3 Rounds

📋 Online Test → Technical → HR🎯 Test Engineer · QA Engineer📍 Noida · Bangalore · Chennai

🔬 Technical Interview

HCL Technical: QA theory, manual testing, basic automation, and SQL. HCL appreciates candidates who ask good questions about the role and domain. Show genuine interest in their specific industry verticals (banking, telecom, healthcare).

Q1 What is the difference between a test plan and a test case? Give examples of each.
Easy · Test Documentation · HCL Technical
Test Plan: High-level strategy document. Created by Test Lead. Answers "What will we test, how, when, and with what resources?" Contains: scope, strategy, tools, timeline, risks. Example: Test Plan for "Bank Account Module v2.0" — scope includes login, account creation, fund transfer; excludes mobile app (separate plan). Test Case: Detailed execution document. Created by QA Engineer. Contains: test case ID, title, preconditions, steps, expected result, actual result, pass/fail. Example: TC-001 "Verify login with valid credentials" — steps: open URL, enter email, enter password, click login; expected: dashboard displayed.
Q2 Reverse a linked list iteratively and write test cases for it.
Easy · Java Basics · HCL OA
Three pointers: prev=null, curr=head. For each node: save next, reverse the pointer (curr.next=prev), advance both. Return prev as new head.
public ListNode reverseList(ListNode head) {
    ListNode prev = null;
    ListNode curr = head;
    while (curr != null) {
        ListNode next = curr.next;  // save next
        curr.next = prev;           // reverse pointer
        prev = curr;                // advance prev
        curr = next;                // advance curr
    }
    return prev;   // prev is now the new head
}

// Test cases to mention:
// TC1: [1,2,3,4,5] → [5,4,3,2,1]   (normal case)
// TC2: [1,2]       → [2,1]          (two elements)
// TC3: [1]         → [1]            (single element)
// TC4: null        → null           (empty list)
// TC5: [1,1,1]     → [1,1,1]       (all same values)
💡 HCL follow-up: "What is the time and space complexity?" Answer: O(n) time, O(1) space — this is the optimal solution.
Q3 What is the difference between White Box, Black Box, and Grey Box testing?
Easy · Testing Types · HCL Technical
Black Box: Tester has NO knowledge of internal code. Tests based on requirements/specs only. Techniques: EP, BVA, decision tables. Done by independent QA team. White Box: Tester has FULL knowledge of internal code. Tests code paths, branches, conditions. Techniques: statement coverage, branch coverage, path coverage. Done by developers or specialized QA. Grey Box: Partial knowledge — tester knows the architecture and data flow but not the full code. Combines both approaches. Good for integration testing where you know API contracts but not internal implementation.
Q4 What is performance testing? Explain the 5 types with examples.
Easy · Testing Types · HCL Technical
Performance testing evaluates system behavior under workload. Types: Load test: expected traffic — does system meet SLAs? (e.g., 1000 users → response time <2s). Stress test: push beyond limit — where does it break? (e.g., increase users until errors spike). Soak test: normal load for hours — memory leaks? (e.g., 500 users for 8 hours). Spike test: sudden burst — recovery behavior? (e.g., 100 → 1000 users in 1 minute). Volume test: large data sets — query performance? (e.g., 10M records in DB).
Q5 Write SQL to find the top 3 highest-paid employees per department.
Medium · SQL · HCL Technical
Use window functions — DENSE_RANK() partitioned by department, ordered by salary descending.
-- Using DENSE_RANK (handles ties correctly)
SELECT department, name, salary, rank_in_dept
FROM (
    SELECT
        department,
        name,
        salary,
        DENSE_RANK() OVER (
            PARTITION BY department
            ORDER BY salary DESC
        ) AS rank_in_dept
    FROM employees
) ranked
WHERE rank_in_dept <= 3
ORDER BY department, rank_in_dept;

-- If two employees have the same salary, DENSE_RANK gives them same rank
-- [VP: 100K, 100K, 90K] → ranks 1,1,2 (two people tied at rank 1)
-- vs RANK: 1,1,3 (skips rank 2)
Q6 What is REST API testing? What do you validate in an API response?
Easy · API Testing · HCL Technical
REST API testing verifies that APIs work correctly without a UI. What to validate: (1) Status code — 200 OK, 201 Created, 400 Bad Request, 401 Unauthorized, 404 Not Found, 500 Server Error. (2) Response body — JSON/XML structure, field values, data types. (3) Response time — within SLA (e.g., <500ms). (4) Headers — Content-Type, Cache-Control, CORS headers. (5) Schema validation — fields match spec. (6) Error messages — clear and appropriate for 4xx responses. Tools: Postman, REST Assured, cURL.
// Basic REST Assured example
given()
    .baseUri("https://api.example.com")
    .header("Authorization", "Bearer " + token)
.when()
    .get("/users/123")
.then()
    .statusCode(200)
    .header("Content-Type", containsString("application/json"))
    .body("id", equalTo(123))
    .body("name", notNullValue())
    .body("email", matchesPattern("[^@]+@[^@]+\.[^@]+"))
    .time(lessThan(500L));   // response time SLA
Q7 What is the Page Object Model? Why should you use it?
Easy · Automation Basics · HCL Technical
Page Object Model (POM): Design pattern where each web page has a corresponding Java class. The class contains: locators (private) and actions/methods (public). Benefits: Maintainability — locator change requires update in only 1 place. Reusability — multiple tests use the same page methods. Readability — test reads like a user story: loginPage.login("user", "pass"). Separation of concerns — locators/actions in page class, assertions in test class. Golden rule: No assertions inside page classes.
public class LoginPage {
    private final WebDriver driver;
    @FindBy(id="email")    private WebElement emailField;
    @FindBy(id="password") private WebElement passwordField;
    @FindBy(id="loginBtn") private WebElement loginButton;

    public LoginPage(WebDriver driver) {
        this.driver = driver;
        PageFactory.initElements(driver, this);
    }

    public DashboardPage login(String email, String password) {
        emailField.sendKeys(email);
        passwordField.sendKeys(password);
        loginButton.click();
        return new DashboardPage(driver);   // returns next page
    }
}

// Test class - clean and readable
@Test
public void validLogin_ShouldShowDashboard() {
    DashboardPage dashboard = loginPage.login("user@test.com", "Pass123");
    Assert.assertTrue(dashboard.isDisplayed());  // assertion in test, not in page
}
Q8 How do you decide which test cases to automate and which to keep manual?
Medium · Test Strategy · HCL Technical
Automate: Tests run frequently (regression, smoke), stable and well-defined inputs, repetitive data-driven tests, positive ROI within 3 months (creation time < time saved). Keep manual: Exploratory testing (discovering unknown unknowns), one-time validation, highly volatile UI (locators break constantly), visual aesthetic checks, usability testing, tests requiring human judgment. ROI formula: (manual_time_per_run × runs_per_year) vs (automation_creation_time + annual_maintenance). If savings > costs, automate.
Q9 What is UAT (User Acceptance Testing)? Who performs it and when?
Easy · Testing Types · HCL Technical
UAT is the final testing phase where actual end-users or business stakeholders verify that the system meets business requirements and is fit for purpose. Who performs: actual end users, business analysts, clients — NOT the development or QA team (to ensure unbiased evaluation). When: after system testing is complete and all critical defects are fixed. Immediately before production deployment. Types: Alpha testing (internal users at developer site), Beta testing (real users in their own environment), Contract acceptance testing (verifies contractual requirements). Goal: "Does this system do what the business needs it to do?"
Q10 Where do you see yourself in 3 years? Why HCL specifically?
Easy · Career Goals · HCL HR
3-year goal: Senior Test Engineer or Test Lead, ISTQB Foundation certified, owning automation framework for a vertical (banking/telecom/healthcare). Contributing to team quality culture, not just executing tests. Possibly exploring test architecture role. Why HCL: Be specific to their verticals. "HCL's HiTech practice focuses on semiconductor testing — a niche area I want to specialize in." OR "HCL's BFSI practice handles tier-1 banking clients — the domain complexity excites me." Research HCL's service lines and mention one specifically.
💡 HCL appreciates candidates who show genuine interest in their specific domain. Look up HCL's industry verticals (HiTech, Banking, Manufacturing, Retail) and mention one that aligns with your background or interest.