UI टेस्ट ऑटोमेशन
UI टेस्ट ऑटोमेशन एक असली ब्राउज़र को वैसे ही चलाता है जैसे यूज़र चलाता है — एलिमेंट खोजना, क्लिक करना, टाइप करना, स्क्रीन पर जो है उसे पढ़ना — और जाँचता है कि नतीजा requirement से मेल खाता है। यह अकेला ऑटोमेटेड टेस्ट है जो पूरे स्टैक को एक साथ चलाता है: markup, styles, client code, API, डेटाबेस और इनके बीच का जोड़। यही इसकी क़ीमत भी है और लागत भी: UI टेस्ट किसी टीम के सबसे धीमे, सबसे महँगे और सबसे आसानी से फ़ेल होने वाले टेस्ट होते हैं।
यह गाइड इस विषय का प्रवेश द्वार है। इसमें बताया गया है कि UI ऑटोमेशन किसमें अच्छा है और किसमें कमज़ोर, maintainable फ़्रेमवर्क की परतें कैसी होती हैं, Selenium/WebDriver, Playwright और Cypress में क्या फ़र्क़ है, synchronization और assertions, page और component objects, टेस्ट डेटा, cross-browser और parallel रन, CI, और यह कैसे तय करें कि UI लेवल पर क्या आना चाहिए। दो छोटी गाइड और गहराई में जाती हैं: एक locator रणनीतियों पर, और एक flaky टेस्ट की जाँच और उन्हें ठीक करने पर।
UI ऑटोमेशन किसलिए है — और किसमें कमज़ोर है
UI टेस्ट एक ऐसे सवाल का जवाब देता है जिसका जवाब कोई और टेस्ट नहीं देता: क्या यूज़र असली ब्राउज़र में यह journey शुरू से अंत तक पूरी कर सकता है? यह उन defects को पकड़ता है जो परतों के बीच रहते हैं — गलत handler से जुड़ा बटन, ऐसा फ़ॉर्म जो वह फ़ील्ड भेजता है जिसे API रिजेक्ट करता है, redirect के बाद ही दिखने वाली script error, या layout बदलाव जो submit बटन को cookie banner के पीछे छिपा देता है।
बाक़ी लगभग हर चीज़ में यह कमज़ोर है। हर validation rule, हर calculation branch या हर error code को ब्राउज़र से जाँचना धीमा है, और जब UI टेस्ट फ़ेल होता है तो वह बताता है कि journey टूटी, यह नहीं कि कहाँ। ये जाँचें unit और API टेस्ट की जगह हैं, जो मिलीसेकंड में चलते हैं और सीधे गड़बड़ कोड की ओर इशारा करते हैं।
- सही फ़िट — critical user journeys (sign-up, login, search, checkout, payment confirmation), front end और back end का integration, कुछ चुने हुए flows का cross-browser व्यवहार, और उन flows का regression जो पहले टूट चुके हैं।
- ख़राब फ़िट — बहुत सारे input combinations वाले business rules, validation matrices, visual design का आकलन, usability, exploratory सवाल (“क्या यह उलझाने वाला है?”), और ऐसी screens जिनका डिज़ाइन हर sprint बदलता है।
- चेतावनी के संकेत — ऐसा suite जो टीम के इंतज़ार की सीमा से ज़्यादा समय लेता है, ऐसे टेस्ट जो प्रोडक्ट से असंबंधित कारणों से फ़ेल होते हैं, और ऐसी failures जिनकी कोई जाँच नहीं करता क्योंकि “शायद flaky है”।
Maintainable ऑटोमेशन फ़्रेमवर्क की परतें
जो UI suites maintain करने लायक नहीं रहते, वे ज़्यादातर एक ही वजह से बिगड़ते हैं: टेस्ट का इरादा, पेज की बनावट और टूल calls एक ही function में मिले होते हैं, इसलिए markup का एक बदलाव पचास टेस्ट तोड़ देता है। इलाज है परतों में बाँटना, जिनमें हर परत के बदलने का एक ही कारण हो। ISTQB का Advanced Level Test Automation Engineering (CTAL-TAE) syllabus इसी विचार पर बना एक generic test automation architecture बताता है — क्या टेस्ट हो रहा है, उसे इससे अलग रखना कि system under test को कैसे चलाया जाता है। नीचे परतों के वे नाम हैं जो ज़्यादातर टीमें रोज़ इस्तेमाल करती हैं।
- Test layer — specs ख़ुद। हर टेस्ट में एक scenario, business भाषा में लिखा (“ग्राहक सेव्ड कार्ड से पेमेंट करता है”)। कोई selector नहीं, कोई wait नहीं, कोई driver call नहीं।
- Page और component objects (या Screenplay tasks जैसा कोई बराबर abstraction) — अकेली जगह जो जानती है कि screen कैसी बनी है और कौन से locators इस्तेमाल होते हैं।
- Driver / framework layer — WebDriver bindings, Playwright या Cypress, साथ में आपकी conventions के लिए पतले wrappers (fixtures, custom commands)। Wrappers पतले रखें: फ़्रेमवर्क को दोबारा बनाने से उसकी features और documentation छिप जाते हैं।
- Test data layer — factories और API clients जो टेस्ट के लिए ज़रूरी users, orders और products बनाते हैं, और बाद में उन्हें हटाते हैं।
- Configuration — हर environment के लिए base URLs, browsers, timeouts, credentials और feature flags, environment variables या config files से पढ़े जाएँ, टेस्ट में कभी hard-code न हों।
- Reporting — हर टेस्ट का pass/fail और failure debug करने के सबूत: screenshots, videos, traces, console और network logs, जिन्हें CI pipeline publish करे।
e2e/
tests/ checkout.spec.ts, login.spec.ts <- test layer (intent only)
pages/ login-page.ts, checkout-page.ts <- page objects
components/ header.ts, date-picker.ts <- component objects
api/ orders-client.ts, users-client.ts <- set up state via API
fixtures/ auth.ts, test-data.ts <- data + setup/teardown
config/ playwright.config.ts, env/staging.env <- configuration
reports/ (generated) html report, traces, junit.xml <- reportingCalls ऊपर से नीचे जाती हैं
- 1Test layerहर टेस्ट में business भाषा में एक scenario; क्या सही है यह टेस्ट तय करता है
Scenario बदलने पर बदलती है
- 2Page और component objectsया Screenplay tasks जैसा बराबर abstraction: अकेली जगह जो screen की बनावट और locators जानती है
Markup बदलने पर बदलती है: एक class, हर टेस्ट नहीं
- 3Driver / framework layerWebDriver bindings, Playwright या Cypress, साथ में पतले wrappers (fixtures, custom commands)
Automation टूल बदलने पर बदलती है
- 4ब्राउज़र और system under testसिर्फ़ ऊपर वाली परत के ज़रिए चलाया जाता है
Test layer से Driver / framework layer तक:अनुमति नहीं: टेस्ट में selector, wait या driver call
Call stack के बगल में: api/ और fixtures/ में test data layer (टेस्ट की ज़रूरत की चीज़ें बनाए, बाद में हटाए), config/ में हर environment का configuration (टेस्ट में hard-code नहीं) और reports/ में reporting (CI publish करे)।
ब्राउज़र ऑटोमेशन: WebDriver, Playwright और Cypress
WebDriver ब्राउज़र को remote से कंट्रोल करने की W3C specification है: एक client library HTTP पर commands किसी ब्राउज़र-विशेष driver (chromedriver, geckodriver, safaridriver आदि) को भेजती है, और driver ब्राउज़र को चलाता है। Selenium इसका सबसे जाना-माना client है, जिसकी Java, Python, C#, JavaScript और Ruby के लिए official bindings हैं, और Selenium Grid sessions को कई मशीनों पर बाँटता है। क्योंकि ब्राउज़र vendors अपने drivers ख़ुद देते हैं, WebDriver सबसे portable विकल्प है, और यही protocol दूसरे टूल्स जैसे mobile apps के लिए Appium का भी आधार है।
Playwright, Microsoft की open-source library है जो Chromium, Firefox और WebKit को WebDriver के बजाय अपने ब्राउज़र connection से चलाती है। इसका test runner actions से पहले auto-waiting, retry करने वाले (“web-first”) assertions, isolated browser contexts, parallel workers, network interception और trace viewer देता है। यह TypeScript/JavaScript, Python, Java और .NET को सपोर्ट करती है।
Cypress टेस्ट कोड को ब्राउज़र के अंदर ऐप के साथ चलाता है, जिससे उसे पेज और network तक सीधी पहुँच, queries और assertions का automatic retry, और एक interactive runner मिलता है जो हर command को DOM के snapshot पर दिखाता है। टेस्ट JavaScript या TypeScript में लिखे जाते हैं। ब्राउज़र के अंदर चलने वाली बनावट के कुछ trade-offs हैं जिन्हें इसका documentation बताता है, जैसे कई tabs और cross-origin navigation से जुड़े।
इनमें से कोई भी “सबसे अच्छा” नहीं है। अपनी टीम की भाषा, यूज़र्स असल में जो ब्राउज़र चलाते हैं, grid या mobile infrastructure की ज़रूरत, और टूल failure को कितनी साफ़ रिपोर्ट करता है — इनके आधार पर चुनें। इस गाइड की बाक़ी अवधारणाएँ तीनों पर लागू होती हैं।
Locators: टेस्ट एलिमेंट कैसे खोजते हैं
Locator वह query है जिससे टेस्ट किसी एलिमेंट को खोजता है, और इसकी क्वालिटी suite की maintenance लागत का बड़ा हिस्सा तय करती है। Playwright और Testing Library का documentation पहले यूज़र को दिखने वाले attributes — एलिमेंट का role और accessible name, उसका label, उसका दिखने वाला text — और उनके बाद एक dedicated test id सुझाता है; इसमें CSS और फिर आख़िरी विकल्प के रूप में XPath जोड़ने से ऐसा क्रम बनता है जो हर टूल में काम करता है।
यूज़र-आधारित locators refactoring में टिके रहते हैं क्योंकि वे तभी बदलते हैं जब यूज़र को दिखने वाला interface बदले, और जब कोई एलिमेंट अपना accessible name खो देता है तो वे फ़ेल होते हैं — accessibility के लिए एक उपयोगी साइड-चेक। Locator रणनीतियों वाली गाइड पूरा क्रम, CSS बनाम XPath, dynamic ids, iframes, shadow DOM और absolute XPath व index-आधारित selectors जैसे anti-patterns विस्तार से बताती है।
// Playwright — in order of preference
page.getByRole("button", { name: "Place order" })
page.getByLabel("Email")
page.getByText("Order confirmed")
page.getByTestId("order-total")
page.locator("form#checkout button[type=submit]") // CSS: only when nothing above fits
// Selenium (Java)
driver.findElement(By.cssSelector("[data-testid=order-total]"));
// Cypress
cy.get("[data-cy=order-total]");Waits और synchronization: कभी fixed sleep नहीं
UI टेस्ट की flakiness का बड़ा हिस्सा एक race है: ऐप तैयार होने से पहले टेस्ट action या assertion कर देता है। Fixed sleep (Thread.sleep, time.sleep, cy.wait(5000)) आपके लैपटॉप पर अंदाज़े से इसे “ठीक” कर देता है, फिर धीमे CI runner पर फ़ेल होता है — और हर तेज़ रन में अपनी पूरी अवधि बर्बाद करता है। इसके बजाय timeout के साथ किसी condition का इंतज़ार करें।
- Selenium implicit wait — driver-स्तर की setting जिससे हर element lookup तब तक poll करता है जब तक एलिमेंट मौजूद न हो जाए या timeout ख़त्म न हो। यह सिर्फ़ मौजूदगी देखता है, visibility या clickability नहीं।
- Selenium explicit wait — WebDriverWait किसी condition (visible, clickable, text present, या आपका अपना function) के साथ, ठीक वहीं लगाया जाए जहाँ ज़रूरत है। Selenium documentation implicit और explicit waits को मिलाने से मना करता है, क्योंकि मिले हुए timeouts अनुमान से बाहर हो जाते हैं।
- Playwright auto-waiting — click या fill जैसे action से पहले Playwright जाँचता है कि एलिमेंट actionable है (visible, stable, events receive कर सकता है, enabled, और inputs के लिए editable) और तब तक इंतज़ार करता है जब तक ऐसा न हो या timeout ख़त्म न हो।
- Cypress retry-ability — cy.get और cy.contains जैसी queries अपने बाद जुड़े assertion के साथ तब तक retry होती हैं जब तक assertion pass न हो या command time out न हो। .click() जैसे actions दोबारा नहीं चलते, इसलिए action से पहले ज़रूरी state को assert करें।
- ऐप के अपने संकेतों का इंतज़ार करें — कोई ख़ास network response, spinner का ग़ायब होना, “Saved” status — समय या generic “network idle” state के बजाय।
// Selenium (Java) — explicit wait for a condition, not a sleep
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement status = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.cssSelector("[data-testid=order-status]")));
// Playwright (TypeScript) — click auto-waits; the assertion retries
await page.getByRole("button", { name: "Pay now" }).click();
await expect(page.getByTestId("order-status")).toHaveText("Paid");
// Cypress — the query retries until the assertion passes or times out
cy.get("[data-cy=order-status]").should("have.text", "Paid");
// Never: Thread.sleep(5000) / time.sleep(5) / cy.wait(5000)Assertions: वह जाँचें जो यूज़र देखता है, और उन्हें retry करने दें
Assertion को वह नतीजा बताना चाहिए जिसकी यूज़र या बिज़नेस को परवाह है: confirmation heading दिख रहा है, order total 199.20 SAR है, error message गलत फ़ील्ड का नाम बताता है, URL order page का है। अंदरूनी चीज़ों पर assertion — कोई CSS class, divs की संख्या, किसी component की state — टेस्ट को implementation से बाँध देता है और हानिरहित refactoring पर टूट जाता है।
जहाँ फ़्रेमवर्क देता है वहाँ retry करने वाले assertions इस्तेमाल करें। Playwright में expect(locator).toBeVisible(), toHaveText() और expect(page).toHaveURL() pass होने या time out होने तक retry करते हैं, जबकि expect(await locator.textContent()).toBe(…) एक बार पढ़ता है और पेज से race करता है। Cypress में .should() अपने से पहले की query को retry करता है। Selenium में पहले condition का explicit wait करें, फिर assert करें।
- हर टेस्ट में एक व्यवहार assert करें, उतने assertions के साथ जितने उस व्यवहार को साबित करने के लिए चाहिए।
- पैसे, गिनती और status के लिए सटीक values इस्तेमाल करें; patterns सिर्फ़ सच में बदलने वाले हिस्सों के लिए, जैसे ORD-2026-000184 जैसा order number या timestamp।
- जब UI किसी API का डेटा दिखाता है, तो UI टेस्ट में दिखाया गया नतीजा और API टेस्ट में पूरा response assert करें — हर JSON फ़ील्ड को ब्राउज़र से दोबारा न जाँचें।
- Failure messages को bug title जैसा बनाएँ: order ORD-2026-000184 के लिए अपेक्षित “Paid”, मिला “Pending”।
Page objects और component objects
Page object एक class है जो एक पेज या screen को दर्शाती है। यूज़र वहाँ जो कर सकता है उसे methods (signIn, addToCart) के रूप में देती है और locators व interaction की बारीकियाँ छिपाती है। Markup बदलने पर आप हर टेस्ट के बजाय एक class ठीक करते हैं। Selenium documentation इस pattern को बताता है और सुझाव देता है कि page object methods दूसरे page objects या डेटा लौटाएँ, और page objects में assertions न हों — क्या सही है यह टेस्ट तय करता है।
Component objects यही विचार उन हिस्सों पर लागू करते हैं जो कई पेजों पर आते हैं: header, date picker, data table, modal dialog। तब checkout page object उनके locators दोहराने के बजाय header component और address-form component को जोड़कर बनता है।
Page objects छोटे और व्यवहार पर केंद्रित रखें। Generic helpers से भरा 900 लाइन का “BasePage” संकेत है कि abstraction दूसरा फ़्रेमवर्क बन गया है। कुछ टीमें Screenplay pattern (actors जो tasks करते हैं) या domain-स्तर के सीधे helper functions पसंद करती हैं; जब तक वे वही अलगाव देते हैं, ठीक हैं। नीचे का उदाहरण TypeScript के साथ Playwright में है।
// pages/orders-page.ts
import type { Page, Locator } from "@playwright/test";
export class OrdersPage {
readonly heading: Locator;
constructor(page: Page) {
this.heading = page.getByRole("heading", { name: "My orders" });
}
}
// pages/login-page.ts
import type { Page, Locator } from "@playwright/test";
import { OrdersPage } from "./orders-page";
export class LoginPage {
readonly email: Locator;
readonly password: Locator;
readonly submit: Locator;
constructor(private readonly page: Page) {
this.email = page.getByLabel("Email");
this.password = page.getByLabel("Password");
this.submit = page.getByRole("button", { name: "Sign in" });
}
async goto() {
await this.page.goto("/login");
}
async signIn(email: string, password: string): Promise<OrdersPage> {
await this.email.fill(email);
await this.password.fill(password);
await this.submit.click();
return new OrdersPage(this.page);
}
}
// tests/login.spec.ts
import { test, expect } from "@playwright/test";
import { LoginPage } from "../pages/login-page";
test("customer sees their orders after signing in", async ({ page }) => {
const login = new LoginPage(page);
await login.goto();
const orders = await login.signIn("layla.h@example.com", process.env.TEST_USER_PASSWORD!);
await expect(orders.heading).toBeVisible();
await expect(page).toHaveURL(/\/orders$/);
});टेस्ट डेटा और isolation
हर UI टेस्ट को अपनी ज़रूरत की चीज़ें ख़ुद बनानी चाहिए और किसी दूसरे टेस्ट की बनाई चीज़ पर निर्भर नहीं रहना चाहिए। साझा accounts और साझा orders उन टेस्ट की सबसे आम वजह हैं जो अकेले pass और suite में fail होते हैं: एक टेस्ट वह order cancel कर देता है जिसे दूसरा टेस्ट जाँच रहा है, या दो parallel टेस्ट एक ही profile बदल देते हैं।
State को UI से नहीं, API या database seed से बनाएँ। हर टेस्ट में फ़ॉर्म से login करना, या दस product pages पर क्लिक करके cart भरना, हर टेस्ट को धीमा करता है और उसे उन screens की failures के सामने खड़ा करता है जिन्हें वह टेस्ट ही नहीं कर रहा। Login फ़ॉर्म को एक बार अपने अलग टेस्ट में जाँचें; बाक़ी जगह API से session लें और उसे दोबारा इस्तेमाल करें — Playwright authenticated browser state को फ़ाइल में सेव कर सकता है, और Cypress इसी काम के लिए cy.session देता है।
- हर टेस्ट का अलग डेटा — emails और नामों में run id या UUID जोड़ें (जैसे layla.h+run8412@example.com) ताकि parallel रन टकराएँ नहीं।
- सिर्फ़ काल्पनिक डेटा — production के ग्राहकों को कभी test environments में कॉपी न करें; इसके बजाय वास्तविक-से दिखने वाले records generate करें।
- जो आपका नहीं है उसे stub करें — payment gateways, SMS providers और map services को ज़्यादातर UI टेस्ट में mocked responses से बदला जा सकता है (Playwright में page.route, Cypress में cy.intercept), और provider के असली sandbox के ख़िलाफ़ एक अलग जाँच रखें।
- Cleanup करें, या डेटा को disposable बनाएँ — टेस्ट के बाद बने records हटाएँ, या ऐसा environment इस्तेमाल करें जो हर रन में reset होता हो।
आज़माएँ: API रिक्वेस्ट बिल्डर आज़माएँ: फ़ेक यूज़र जनरेटर आज़माएँ: टेस्ट डेटा फ़ैक्टरी आज़माएँ: Mock API रिस्पॉन्स जनरेटर
Cross-browser टेस्टिंग और parallel execution
Cross-browser टेस्टिंग जाँचती है कि वही journeys उन browser engines में चलती हैं जो आपके यूज़र्स असल में इस्तेमाल करते हैं: Chromium-आधारित ब्राउज़र (Chrome, Edge), Firefox और Safari (WebKit), desktop और mobile चौड़ाई पर। Matrix analytics से तय करें; हर टेस्ट हर ब्राउज़र पर चलाना कम फ़ायदे में लागत कई गुना कर देता है। एक आम बँटवारा है: पूरा suite एक ब्राउज़र पर और critical journeys का smoke set बाक़ी पर।
Playwright का WebKit build, macOS या iOS के Safari जैसा ही प्रोडक्ट नहीं है। अगर Safari यूज़र्स आपके लिए अहम हैं, तो सबसे ज़रूरी flows के लिए असली Safari रन जोड़ें — safaridriver या किसी device cloud से।
Parallel execution बढ़ते suite को तेज़ रखता है, और यह तभी काम करता है जब टेस्ट isolated हों। Runners टेस्ट को workers में बाँटते हैं: Playwright workers और sharding, TestNG, JUnit या pytest-xdist parallelism के साथ Selenium Grid nodes, और CI मशीनों पर बँटी Cypress spec files। हर worker को अपना browser context और अपना डेटा चाहिए।
- किसी भी क्रम के लिए डिज़ाइन करें — कभी-कभी suite को random order में चलाएँ ताकि साबित हो कि टेस्ट के बीच कोई छिपी निर्भरता नहीं है।
- लंबे suites को कई CI jobs में shard करें और reports को एक में merge करें।
- साझा resources पर नज़र रखें — एक test tenant, एक rate-limited API या एक mailbox “parallel” suite को क्रमिक बना सकता है या flaky कर सकता है।
CI में UI टेस्ट चलाना
CI में ब्राउज़र साफ़ runners पर headless (बिना दिखने वाली window) चलते हैं, आमतौर पर ऐसे containers में जिनमें ब्राउज़र पहले से installed होते हैं। Browser और framework versions pin करें ताकि runner image का update चुपचाप नतीजे न बदल दे, और report में टेस्ट हो रहे ऐप का version दर्ज करें।
फ़ेल हुआ CI रन तभी काम का है जब कोई उसे लोकल दोबारा चलाए बिना debug कर सके। Suite को ऐसे configure करें कि failure पर सबूत रखे — screenshots, videos, Playwright traces, browser console और network logs — और HTML report व JUnit XML को build artifacts के रूप में publish करें ताकि pipeline हर टेस्ट का नतीजा दिखा सके। उदाहरण Playwright smoke set के लिए GitHub Actions job है; GitLab CI और Jenkins pipelines भी इसी ढाँचे पर चलती हैं।
- Pull request — unit और API टेस्ट के साथ UI journeys का तेज़ smoke set (मिनट, एक घंटा नहीं)।
- Main branch या nightly — browser matrix पर पूरा UI regression।
- Deployment के बाद — live environment पर कुछ read-only journeys।
- Failures merge रोकते हैं। Flaky टेस्ट ठीक किए जाते हैं या किसी owner के साथ quarantine होते हैं, हरा होने तक दोबारा नहीं चलाए जाते; flaky टेस्ट वाली गाइड जाँच, retries और quarantine बताती है।
name: ui-smoke
on: [pull_request]
jobs:
ui-smoke:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 24
- run: npm ci
- run: npx playwright install --with-deps chromium
- run: npx playwright test --grep @smoke
env:
BASE_URL: ${{ vars.STAGING_URL }}
- uses: actions/upload-artifact@v7
if: ${{ !cancelled() }}
with:
name: playwright-report
path: playwright-report/व्यावहारिक रणनीति: UI लेवल पर क्या ऑटोमेट करें
Test pyramid, जिसे मैनुअल बनाम ऑटोमेटेड टेस्टिंग वाली गाइड समझाती है, नीचे बहुत सारे तेज़ unit टेस्ट, बीच में कम API और service टेस्ट, और ऊपर थोड़े से UI टेस्ट रखता है। UI ऑटोमेशन का व्यावहारिक नियम: किसी journey को UI से तभी ऑटोमेट करें जब जोखिम ख़ुद journey में हो — screens, front end और back end के बीच की wiring — और बाक़ी हर जाँच को उस सबसे निचले लेवल पर ले जाएँ जो उसे पकड़ सकता है।
उदाहरण के लिए, बारह rule combinations वाली discount calculation unit और API टेस्ट की जगह है; “checkout पर discount के बाद का total दिखता है और payment पर वही charge होता है” एक UI टेस्ट की जगह है।
- जोखिम से शुरू करें: उन journeys की सूची बनाएँ जिनके फ़ेल होने से पैसा, डेटा या भरोसा जाता है (payment, sign-up, login, मुख्य search) और पहले उन्हें ऑटोमेट करें।
- हर journey को पहले Given/When/Then acceptance criteria के रूप में लिखें; criteria ही टेस्ट के नाम और assertions बनते हैं।
- Suite का बजट तय करें: pull-request smoke set और पूरे रन की अधिकतम अवधि पर सहमति बनाएँ, और सीमा पार होने पर टेस्ट हटाएँ या नीचे के लेवल पर ले जाएँ।
- टेस्ट को production code जैसा मानें: code review, naming conventions, कोई copy-paste नहीं, और हर हिस्से का एक नामित owner।
- लगातार maintain करें: UI बदलाव वाले उसी pull request में page objects अपडेट करें, developers के साथ test ids तय करें, हटाई गई features के टेस्ट हटाएँ, और framework व browser versions अलग बदलाव में upgrade करें।
- जो मायने रखता है वह मापें: feedback मिलने का समय, flaky rate, और रिलीज़ से पहले suite के पकड़े defects — टेस्ट की कच्ची गिनती नहीं।
आज़माएँ: एक्सेप्टेंस क्राइटेरिया जनरेटर आज़माएँ: टेस्ट केस जनरेटर
अक्सर पूछे जाने वाले सवाल
UI टेस्ट ऑटोमेशन क्या है?
यह Selenium, Playwright या Cypress जैसे टूल से असली ब्राउज़र को user journeys में चलाना और दिखने वाले नतीजों को अपने-आप जाँचना है। यह पुष्टि करता है कि front end, back end और integrations साथ काम करते हैं, और तेज़ unit व API टेस्ट का पूरक है।
Selenium, Playwright या Cypress — कौन चुनें?
अपनी टीम की भाषा, जिन ब्राउज़र को सपोर्ट करना है, आपका infrastructure (grid, device cloud, mobile) और टूल failures को कितनी अच्छी तरह रिपोर्ट करता है — इनसे चुनें। तीनों maintainable suite चला सकते हैं; टूल से ज़्यादा फ़्रेमवर्क डिज़ाइन और टेस्ट डेटा का अनुशासन मायने रखता है।
हमारे पास कितने UI टेस्ट होने चाहिए?
कोई सही संख्या नहीं है। Critical journeys और वे integration points कवर करें जिन्हें सिर्फ़ ब्राउज़र जाँच सकता है, बाक़ी को API और unit लेवल पर रखें। अगर suite हर pull request पर चलाने के लिए बहुत धीमा है, तो वह बहुत बड़ा है या ठीक से बँटा नहीं है।
हमारे UI टेस्ट बेतरतीब ढंग से क्यों फ़ेल होते हैं?
आम कारण हैं timing (पेज तैयार होने से पहले action), टेस्ट के बीच साझा डेटा, अस्थिर environments, third-party services और animations। Sleeps को condition-आधारित waits और retry करने वाले assertions से बदलें, डेटा isolate करें, और असली कारण खोजने के लिए traces और screenshots इस्तेमाल करें।
क्या page objects में assertions होने चाहिए?
आमतौर पर नहीं। Selenium documentation assertions को टेस्ट में रखने की सलाह देता है ताकि page objects दोबारा इस्तेमाल हो सकें। Page object यह जाँच सकता है कि वह अपेक्षित पेज पर पहुँचा, लेकिन व्यवहार की पुष्टि टेस्ट में होनी चाहिए।
क्या recorded टेस्ट फ़्रेमवर्क की जगह ले सकते हैं?
Playwright codegen या Selenium IDE जैसे recorders पेज समझने और शुरुआती locators बनाने में उपयोगी हैं। लंबे चलने वाले suite में maintainable होने से पहले recorded scripts को आमतौर पर page objects, बेहतर locators और सही waits में refactor करना पड़ता है।
क्या CI में UI टेस्ट headless चलाने ज़रूरी हैं?
CI में headless ही आम है क्योंकि यह तेज़ है और display नहीं चाहिए, और आधुनिक ब्राउज़र ज़्यादातर कामों में headless mode में भी वैसा ही व्यवहार करते हैं। Screenshots, videos या traces रखें ताकि failures फिर भी दिखें।
संदर्भ
- Certified Tester Advanced Level Test Automation Engineering (CTAL-TAE) v2.0टेस्ट ऑटोमेशन समाधान और उनकी आर्किटेक्चर के डिज़ाइन, कार्यान्वयन और रखरखाव पर ISTQB का advanced पाठ्यक्रम।
- WebDriver (W3C)वह W3C प्रोटोकॉल जिसे ब्राउज़र Selenium जैसे ऑटोमेशन टूल से रिमोट कंट्रोल के लिए लागू करते हैं (Level 2 संस्करण Working Draft है)।
- Selenium DocumentationWebDriver से ब्राउज़र ऑटोमेशन का आधिकारिक दस्तावेज़, वेट, लोकेटर और Grid सहित।
- Playwright DocumentationPlaywright का आधिकारिक दस्तावेज़ — Chromium, WebKit और Firefox चलाने वाला end-to-end टेस्ट फ़्रेमवर्क।
- Cypress DocumentationCypress से ब्राउज़र में एंड-टू-एंड और कंपोनेंट टेस्टिंग का आधिकारिक दस्तावेज़।
- Best Practices — Playwrightयूज़र को दिखने वाला व्यवहार टेस्ट करें, टेस्ट अलग-थलग रखें, मज़बूत locator और web-first assertions अपनाएँ, और trace से डिबग करें।
- Page object models — SeleniumPage object पैटर्न: हर पेज या कंपोनेंट के लिए एक क्लास जो locator छिपाती है और टेस्ट को चाहिए वे एक्शन देती है, जिससे दोहराव घटता है।
- The Practical Test Pyramid (Ham Vocke)ऑटोमेटेड टेस्ट पोर्टफ़ोलियो में unit, integration, contract और UI टेस्ट का संतुलन कैसे रखें — व्यापक रूप से उद्धृत व्याख्या।
अभ्यास
एक recorded checkout टेस्ट को review करें और UI suite की योजना बनाएँ
आप एक online furniture shop (काल्पनिक) के QA engineer हैं। Release 3.4 checkout में "Pay with a saved card" जोड़ती है और तीन हफ़्ते में live होती है। नादिया, एक automation engineer जो दो महीने पहले जुड़ी, ने checkout का पहला Playwright टेस्ट codegen से record किया, उसे edit किया और pull request खोला; उसने बाक़ी release के लिए एक योजना भी लिखी। पिछले हफ़्ते 11 pull-request runs में से 3 CI में फ़ेल हुए और उसके लैपटॉप पर pass हुए। Material में टीम, browser analytics, वह staging API जिसे suite इस्तेमाल कर सकता है, line numbers के साथ टेस्ट, और योजना दी गई है।
गाइड के layers, locators, waits, assertions, टेस्ट डेटा, cross-browser runs, CI और strategy वाले sections के साथ काग़ज़ पर काम करें। Line numbers का हवाला दें, और अपनी findings ऐसे review comments के रूप में लिखें जिन पर नादिया काम कर सके। इसके लिए 45–60 मिनट रखें।
Online furniture shop (काल्पनिक) - web shop, staging: https://staging.furnish.example
Release 3.4 checkout में "Pay with a saved card" जोड़ती है। Go-live तीन हफ़्ते में।
टीम: नादिया (automation engineer, 2 महीने पहले जुड़ी), उमर (front end),
सारा (back end), यूसुफ़ (release manager), QA: आप।
Analytics, पिछले 90 दिन (काल्पनिक): Chromium ब्राउज़र (Chrome, Edge) 74%,
Safari 21% (iOS 17%, macOS 4%), Firefox 4%, अन्य 1%।
Staging API
POST /api/auth/session sign in; session cookie सेट करता है
POST /api/cart/items { sku, qty } signed-in cart में item जोड़ता है
POST /api/test-support/customers सिर्फ़ test environments में: एक disposable
customer बनाता है, चाहें तो saved card के साथ;
id, email, password लौटाता है
DELETE /api/test-support/customers/{id}
Checkout page payment gateway के sandbox को सीधे ब्राउज़र से कॉल करता है:
POST https://sandbox.paygate.example/v1/charges (2-9 s; लगभग 20 में से 1 decline)
Checkout का address form: 7 fields, 23 validation rules (required, format, length),
ब्राउज़र में जाँचे जाते हैं और फिर POST /api/addresses से दोबारा।
नादिया का पहला टेस्ट, codegen से record करके edit किया गया:
tests/checkout.spec.ts
1 import { test, expect } from '@playwright/test';
2
3 test('test 1', async ({ page }) => {
4 await page.goto('https://staging.furnish.example/login');
5 await page.locator('#email').fill('qa.shared@example.com');
6 await page.locator('#password').fill('Furnish2026!');
7 await page.locator('.MuiButton-root.css-1x2y3z').click();
8 await page.waitForTimeout(3000);
9 await page.goto('https://staging.furnish.example/p/oak-desk-140');
10 await page.locator('xpath=//div[3]/div[2]/button').click();
11 await page.goto('https://staging.furnish.example/p/desk-lamp-led');
12 await page.locator('xpath=//div[3]/div[2]/button').click();
13 await page.goto('https://staging.furnish.example/cart');
14 expect(await page.locator('.total').textContent()).toBe('1,249.00 SAR');
15 await page.locator('text=Checkout').click();
16 await page.locator('input').nth(3).fill('');
17 await page.locator('text=Continue').click();
18 expect(await page.locator('.error').count()).toBe(1);
19 await page.locator('input').nth(3).fill('Riyadh');
20 await page.locator('text=Continue').click();
21 await page.locator('text=Pay now').click();
22 await page.waitForTimeout(8000); // the gateway sandbox is slow
23 await expect(page.locator('.alert')).toHaveClass(/success/);
24 });
3.4 के लिए नादिया की योजना
1. Address form के 23 validation rules में हर एक के लिए इसी जैसा एक टेस्ट।
2. हर pull request पर पूरा suite Chromium, Firefox, WebKit और Edge पर चलाना।
3. CI में screenshots, videos और traces बंद ताकि job तेज़ रहे; failure debug करने
के लिए लोकल दोबारा चलाना।
पिछले हफ़्ते: 11 pull-request runs में से 3 CI में फ़ेल हुए, नादिया के लैपटॉप पर pass हुए।- टेस्ट को गाइड के नियमों के सामने line-by-line review करें। हर समस्या के लिए line numbers, वह नियम जो टूटता है (layers, locators, waits, assertions, टेस्ट डेटा और isolation, configuration) और यह लिखें कि CI के तीन फ़ेल हुए runs का उससे सबसे संभावित संबंध क्या है।
- तय करें कि UI लेवल पर क्या आता है। 23 validation rules कहाँ टेस्ट होते हैं (unit, API, UI)? फिर release 3.4 के लिए suite को जिन UI journeys की ज़रूरत है, उन्हें Given/When/Then के रूप में लिखें, हर एक अपने assertions के साथ।
- Layers डिज़ाइन करें: इस journey के लिए suite के folders और files (tests, page और component objects, API clients और fixtures, configuration, reports), हर एक में क्या है और उसमें क्या कभी नहीं होना चाहिए।
- Checkout journey को test layer में एक टेस्ट के रूप में दोबारा लिखें — Playwright के साथ TypeScript में, या वह क्या करता है इसकी numbered list के रूप में: state API से set up हो, gateway stub हो, locators user-facing हों, assertions retry करें, और पीछे कुछ न छूटे।
- Runs की योजना बनाएँ: दिए गए analytics के लिए browser matrix; pull request पर, main या nightly पर और deployment के बाद क्या चलता है; failure पर CI कौन-से सबूत रखता है; और नादिया की योजना के तीन बिंदुओं पर आपका जवाब।
मॉडल उत्तर दिखाएँ
Review, भाग एक: बनावट और डेटा। Line 3: नाम "test 1" कुछ नहीं बताता, और टेस्ट चार व्यवहार जाँचता है — sign-in, cart total, address validation और payment — इसलिए फ़ेल होने पर किसी को पता नहीं चलता कि कौन-सी journey टूटी; हर टेस्ट में एक व्यवहार, business भाषा में नाम के साथ। Lines 4, 9, 11 और 13: base URL टेस्ट में hard-code है। इसकी जगह configuration layer है (playwright.config.ts में baseURL, जो BASE_URL जैसे environment variable से पढ़ा जाए), ताकि वही suite किसी भी environment पर चले। Lines 5–6: एक साझा account और उसका password source में। Password किसी secret में होना चाहिए (गाइड के उदाहरण में process.env.TEST_USER_PASSWORD), और साझा account isolation तोड़ता है: एक साथ चल रहे दो रन — आज दो pull requests की pipelines, suite बढ़ने पर दो parallel workers — एक ही server-side cart में items जोड़ते हैं, और line 14 का total उनमें से एक के लिए ग़लत होता है। Line 18 ठीक एक error की उम्मीद करती है, जबकि टेस्ट सात में से सिर्फ़ एक field को छूता है; यानी वह इस पर भी निर्भर है कि साझा account का saved address बाक़ी छह fields भर दे — ऐसा डेटा जो टेस्ट ने नहीं बनाया। Lines 4–8 फ़ॉर्म से sign in करती हैं, और lines 9–12 product pages पर क्लिक करके cart बनाती हैं; दोनों टेस्ट को धीमा करती हैं और उसे उन screens की failures के सामने खड़ा करती हैं जिन्हें वह टेस्ट नहीं कर रहा। API से sign in करें और POST /api/cart/items से cart बनाएँ। बाद में कुछ नहीं हटाया जाता, इसलिए हर रन पीछे एक order छोड़ जाता है, और payment से पहले रुका रन cart में ऐसे items छोड़ जाता है जो अगले रन का total ग़लत कर देते हैं।
Review, भाग दो: locators, waits और assertions। Line 7: generated CSS class (css-1x2y3z) एक hash है जो front end के किसी भी build के साथ बदल सकता है — CSS selector का सबसे नाज़ुक रूप; getByRole("button", { name: "Sign in" }) इस्तेमाल करें। Lines 10 और 12: positions से बना XPath (div[3]/div[2]) एक wrapper div जुड़ते ही या layout बदलते ही टूट जाता है; "Add to cart" बटन का accessible name इस्तेमाल करें, या उमर के साथ तय किया गया test id। Lines 16 और 19: input.nth(3) पेज पर inputs के क्रम पर निर्भर है; getByLabel("City") इस्तेमाल करें। Lines 15, 17, 20 और 21 दिखने वाला text इस्तेमाल करती हैं, जो user-facing है, लेकिन text= selector हर उस element से मेल खाता है जिसके text में वह शब्द हो, case की परवाह किए बिना: अगर पेज पर "Continue shopping" link हो तो text=Continue उससे भी मेल खाता है, और तब दो elements मिलने पर click फ़ेल हो जाता है। getByRole("button", { name: "Continue", exact: true }) सटीक है। Line 8: एक fixed sleep जो अंदाज़ा लगाता है कि sign-in में कितना समय लगेगा; धीमे runner पर line 9 session बनने से पहले ही दूसरे पेज पर चली जाती है। किसी condition का इंतज़ार करें — वह पेज जिस पर यूज़र पहुँचता है — या बेहतर, API से sign in करें। Lines 10–13: हर "Add to cart" क्लिक के तुरंत बाद टेस्ट cart अपडेट होने का इंतज़ार किए बिना navigate करता है, इसलिए navigation add-to-cart request को बीच में काट सकता है; cart count या उस request के response का इंतज़ार करें। Line 22: एक sleep जो gateway के 2–9 सेकंड का अंदाज़ा लगाता है। Line 23 का toHaveClass assertion पहले से retry करता है (default 5 सेकंड), इसलिए sleep किसी चीज़ से नहीं बचाता और हर रन में 8 सेकंड जोड़ता है; इसके बजाय gateway को stub करें। Lines 14 और 18: expect(await …textContent()) और count() एक बार पढ़ते हैं और पेज से race करते हैं, और elements को styling classes (.total, .error) से खोजते हैं; cart-total जैसे test id पर await expect(locator).toHaveText(…) इस्तेमाल करें, और .error elements की संख्या नहीं बल्कि वह error message assert करें जो field का नाम बताता है। Line 23: CSS class एक implementation detail है; वह assert करें जो यूज़र देखता है — confirmation heading, order number और URL। लोकल pass और CI में फ़ेल हुए तीन runs इसी तस्वीर में फ़िट होते हैं: CI runner लैपटॉप से धीमा है, इसलिए 3 सेकंड का sleep और कटे हुए cart requests वहीं पहले दिखते हैं; एक साथ चल रही दो pipelines एक ही account और एक ही cart साझा करती हैं; और sandbox के अपने declines (लगभग 20 में से 1) टेस्ट को ऐसे कारण से फ़ेल करते हैं जिसका release 3.4 से कोई लेना-देना नहीं। Traces के बिना कोई नहीं बता सकता कि इनमें से कौन-सा कारण था।
UI लेवल पर क्या आता है। 23 validation rules बहुत सारे inputs वाले business rules हैं — गाइड का "ख़राब फ़िट"। Browser-side जाँचें front end के unit टेस्ट में जाती हैं (हर rule के लिए एक case, हर एक मिलीसेकंड में) और server-side जाँचें POST /api/addresses के API टेस्ट में (हर rule की invalid value, status code और error body); server अलग से टेस्ट होता है क्योंकि कोई client ब्राउज़र को bypass कर सकता है। UI में एक टेस्ट रहता है जो wiring साबित करता है: एक invalid field, field का नाम बताने वाला message दिखाता है और "Continue" आगे नहीं बढ़ता — एक rule काफ़ी है, जैसे ख़ाली city। नादिया के 23 UI टेस्ट 1 बन जाते हैं। 3.4 के लिए UI journeys: (1) ग्राहक sign in करता है और account page देखता है — अकेला टेस्ट जो sign-in फ़ॉर्म इस्तेमाल करता है; (2) saved card वाला ग्राहक checkout पूरा करता है — Given एक signed-in ग्राहक जिसके पास saved card और दो items का cart है, When वह address confirm करके saved card से pay करता है, Then confirmation page order number और total 1,249.00 SAR दिखाता है; (3) declined payment — Given वही, When gateway decline करता है, Then checkout decline message दिखाता है और "Pay now" फिर से इस्तेमाल हो सकता है; (4) address validation की wiring, ऊपर जैसा। चार टेस्ट, हर एक में एक व्यवहार।
Layers। tests/checkout.spec.ts और tests/login.spec.ts — specs: सिर्फ़ इरादा; कोई selectors नहीं, कोई waits नहीं, कोई URLs नहीं। pages/login-page.ts, pages/cart-page.ts, pages/checkout-page.ts, pages/confirmation-page.ts — page objects: locators और actions (checkout(), continueWithAddress(), payWithSavedCard()) जो अगला page object या डेटा लौटाते हैं; कोई assertions नहीं। components/address-form.ts और components/header.ts — उन हिस्सों के component objects जो कई pages पर आते हैं। api/customers-client.ts और api/cart-client.ts — /api/test-support/customers, /api/auth/session और /api/cart/items पर पतले clients। fixtures/customer.ts — एक fixture (test.extend) जो टेस्ट से पहले saved card वाला disposable customer बनाता है और बाद में हटाता है; fixtures/gateway.ts — sandbox.paygate.example के लिए page.route stub, एक approved और एक declined response के साथ। playwright.config.ts — baseURL, projects (browsers और एक mobile width), timeouts, trace, screenshot, video और reporters; environment के लिए env/staging.env, secrets CI के secret store से। playwright-report/ और junit.xml — generated, कभी commit नहीं होते। Wrappers पतले रखें: कोई "BasePage" नहीं जो Playwright को दोबारा बनाए।
टेस्ट। test("customer pays with a saved card", async ({ page, customer, cart, gateway }) => { … })। customer fixture POST /api/test-support/customers कॉल करता है और saved card माँगता है; response एक नए customer का id, e-mail और password देता है, इसलिए हर टेस्ट का अपना account होता है (जब टेस्ट ख़ुद e-mail चुनता है, तो उसमें run id या UUID जोड़ता है, जैसे layla.h+run8412@example.com)। फिर fixture page.request.post("/api/auth/session", { data: { email, password } }) से sign in करता है — page.request पेज के साथ cookie jar साझा करता है, इसलिए कोई फ़ॉर्म नहीं भरा जाता — और अपने teardown में customer हटाता है। cart POST /api/cart/items से दोनों products जोड़ता है। gateway page.route("**/sandbox.paygate.example/v1/charges", route => route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify(approved) })) register करता है, जहाँ approved sandbox के एक असली approved response की कॉपी है। route.fulfill intercept हुई request का जवाब दिए गए status और body से देता है, इसलिए request gateway तक पहुँचती ही नहीं (Cypress में यही काम cy.intercept करता है)। Body: const cartPage = new CartPage(page); await cartPage.goto(); const checkout = await cartPage.checkout(); await checkout.continueWithAddress(testAddress); const confirmation = await checkout.payWithSavedCard(); await expect(confirmation.heading).toBeVisible(); await expect(confirmation.total).toHaveText("1,249.00 SAR"); await expect(confirmation.orderNumber).toHaveText(/^ORD-\d{4}-\d{6}$/); await expect(page).toHaveURL(/\/orders\/ORD-/); — testAddress test data layer का एक काल्पनिक address है। कोई waitForTimeout नहीं: click() actionable element का auto-wait करता है, और हर expect pass होने या time out होने तक retry करता है। Declined-payment टेस्ट वही fixtures इस्तेमाल करता है, stub एक declined response लौटाता है (जैसे insufficient funds), और decline message तथा "Pay now" के फिर से enabled होने को assert करता है। जब टेस्ट सिर्फ़ डेटा पढ़ते हैं, तो setup project सस्ता विकल्प है: playwright.config.ts का एक project जो बाकी projects से पहले चलता है, एक बार sign in करता है और cookies व storage को एक storageState file में सेव करता है, जिसे टेस्ट फिर load करते हैं (Cypress में इसका समकक्ष cy.session है)। एक अलग, धीमा टेस्ट nightly असली sandbox के ख़िलाफ़ चलता है ताकि साबित हो कि integration अब भी काम करता है; वह approval या decline दोनों स्वीकार करता है, बशर्ते पेज मेल खाता नतीजा दिखाए, ताकि sandbox के random declines उसे flaky न बनाएँ।
Runs। Matrix analytics के पीछे चलता है: Chromium 74% कवर करता है, और Edge उसी engine पर बना है, इसलिए अलग Edge project बहुत कम जोड़ता है; WebKit Safari के 21% की जगह लेता है, mobile viewport पर क्योंकि उसका ज़्यादातर हिस्सा iOS है; Firefox के 4% को smoke set मिलता है। Playwright का WebKit Safari नहीं है, इसलिए checkout journey असली Safari पर भी चलती है — safaridriver या device cloud से — हर release candidate पर एक बार। Pull request: Chromium पर smoke set (चारों journeys), कुछ मिनट, unit और API टेस्ट के साथ; failure merge रोकती है। Main और nightly: Chromium पर और mobile width पर WebKit पर पूरा UI regression, Firefox पर smoke set, CI jobs में shard किया हुआ और reports merge किए हुए; असली sandbox वाला payment टेस्ट nightly चलता है। Deployment के बाद: production पर read-only journeys — home page खोलना, search करना, एक product page खोलना — order या payment कभी नहीं। सबूत: trace: "retain-on-failure", screenshot: "only-on-failure", video: "retain-on-failure", HTML report और junit.xml build artifacts के रूप में upload, job फ़ेल होने पर भी; Playwright और browser versions pinned; और टेस्ट हो रहे 3.4 के build का नाम report में दर्ज।
नादिया की योजना पर जवाब। बिंदु 1: 23 rule टेस्ट suite को मिनटों धीमा कर देंगे और टीम को ऐसा कुछ नहीं बताएँगे जो unit या API टेस्ट तेज़ और ज़्यादा सटीक ढंग से न बता दे — इसके बजाय एक UI wiring टेस्ट, और 23 rules unit और API लेवल पर टेस्ट हों; API टेस्ट पर साथ बैठकर (pair) काम करने की पेशकश करें। बिंदु 2: हर pull request पर चार ब्राउज़र अवधि चार गुना कर देते हैं, जबकि Edge Chromium के ऊपर बहुत कम जोड़ता है और Firefox वह 4% जोड़ता है जिसे nightly रन पहले ही कवर करता है — हर pull request पर Chromium पर smoke, matrix nightly। बिंदु 3: traces या screenshots के बिना CI के तीन फ़ेल हुए runs का सिर्फ़ अंदाज़ा लगाया जा सकता था, इसीलिए उन्हें लोकल दोबारा चलाया गया, वे pass हुए और उनका कारण आज तक पता नहीं — सबूत सिर्फ़ failure पर रखें, जिसकी लागत हरे रन में बहुत कम है। और टेस्ट production code की तरह code review से गुज़रता है: steps 1 और 2 की findings ही review comments हैं, page objects उसी pull request में अपडेट होते हैं जिसमें UI बदलता है, और उमर उन elements के लिए test ids तय करता है जिनका कोई accessible name नहीं है।
अगर आपका जवाब अलग है, तो उसे गाइड के नियमों से मिलाएँ: UI टेस्ट सिर्फ़ वहाँ जहाँ जोखिम ख़ुद journey में हो; state API से बने, हर टेस्ट के लिए unique हो और बाद में हट जाए; user-facing locators; conditions का इंतज़ार, समय का कभी नहीं; उस पर assertions जो यूज़र देखता है, retry के साथ; configuration और secrets टेस्ट से बाहर। कारण के साथ अलग बँटवारा ठीक है — जैसे decline message को UI टेस्ट के बजाय front end के component टेस्ट में जाँचना, क्योंकि ब्राउज़र सीधे gateway से बात करता है और decline संभालना सिर्फ़ front end का logic है — लेकिन fixed sleep, साझा account या hard-coded URL ठीक नहीं।
इस topic में आपकी प्रगति
प्रगति ट्रैक करने के लिए साइन इन करें
Topics पूर्ण चिह्नित करें, जहाँ छोड़ा था वहीं से जारी रखें और specialisation परीक्षाएँ खोलें।
QA रोडमैप का हिस्सा
इस topic से पहले
इस मॉड्यूल के दूसरे topics
इस गाइड में बताए गए टूल्स
HTTP रिक्वेस्ट (method, URL, हेडर, auth, बॉडी) बनाएँ और भेजें, फिर रिस्पॉन्स जाँचें — आपके ब्राउज़र में हल्का-फुल्का Postman।
टेस्ट अकाउंट के लिए फ़ेक यूज़र रिकॉर्ड (नाम, username, ईमेल, पासवर्ड, avatar seed, role) जनरेट करें।
सिंथेटिक टेस्ट डेटा की एक ही जगह पर फ़ैक्टरी: users, customers, companies, पते, संख्याएँ, तारीख़ें और स्ट्रिंग — JSON, CSV, SQL या XML में।
किसी user story से Given/When/Then acceptance criteria और definition-of-done चेकलिस्ट जनरेट करें।
फ़ीचर के विवरण और फ़ील्ड सूची से संरचित टेस्ट केस (id, शीर्षक, पूर्व-शर्तें, स्टेप, अपेक्षित परिणाम, प्राथमिकता) जनरेट करें।
रेगुलर एक्सप्रेशन को लाइव टेस्ट करें — मैच हाइलाइटिंग, कैप्चर ग्रुप और रिप्लेस प्रीव्यू के साथ।
success, list, detail, error और empty केस के लिए पूरे mock API रिस्पॉन्स (स्टेटस, हेडर, JSON बॉडी) बनाएँ।