सेलेनियम: @FindBy और PageFactory का उपयोग करके पृष्ठ तत्वों के साथ काम करना

यह आलेख पृष्ठ पर तत्वों को खोजने के लिए @FindBy एनोटेशन का उपयोग करने की संभावना पर चर्चा करेगा, साथ ही तत्वों और कंटेनरों के साथ काम करने के लिए अपनी खुद की कक्षाएं बनायेगा जैसे कि फॉर्म, टेबल आदि।

@FindBy का परिचय


सबसे पहले, आइए एक परीक्षण देखें जो यस पर एक वाक्यांश की खोज करता है
public class SearchTest { @Test(dataProvider = "pageObjects") public void testSearch(final SearchPage searchPage) { searchPage.init(driver); driver.get("http://ya.ru"); searchPage.search("Bolek i Lolek"); } @DataProvider private Object[][] pageObjects() { return new Object[][]{ {new SimpleSearchPage()}, {new AnnotatedSearchPage()}, {new ExtendedSearchPage()}, {new SearchPageWithSearchForm()} }; } private WebDriver driver; @BeforeClass public void beforeClass() { driver = new FirefoxDriver(); } @AfterClass public void afterClass() { driver.quit(); } } 

जैसा कि आप देख सकते हैं, परीक्षण बहुत सरल है और वास्तव में कुछ भी परीक्षण नहीं करता है, यह सिर्फ 4 बार अलग-अलग पेज ऑब्जेक्ट्स के साथ शुरू होता है, जिसके विकास को देखते हुए हम @FindBy का अध्ययन करेंगे।
प्रारंभ में, खोज पृष्ठ के लिए पृष्ठ वर्ग इस तरह दिखता था:
 public class SimpleSearchPage implements SearchPage { private WebDriver driver; @Override public void search(final String query) { driver.findElement(By.id("text")).sendKeys(query); driver.findElement(By.cssSelector("input[type=\"submit\"]")).click(); } @Override public void init(final WebDriver driver) { this.driver = driver; } } 

यहां हम तत्वों की खोज के लिए वेब ड्राइवर का उपयोग करने के लिए एक सुंदर मानक दृष्टिकोण देखते हैं, अर्थात्। Driver.findElement (By.something ())।
कलाई के एक गुच्छे के साथ, आप एनोटेशन का उपयोग करके इस वर्ग को बदल सकते हैं
 public class AnnotatedSearchPage implements SearchPage { @FindBy(id = "text") private WebElement searchField; @FindBy(css = "input[type=\"submit\"]") @CacheLookup private WebElement searchButton; @Override public void search(final String query) { searchField.sendKeys(query); searchButton.click(); } @Override public void init(final WebDriver driver) { PageFactory.initElements(driver, this); } } 

यह कैसे काम करता है ?! Init () विधि में, हम PageFactory.initElements(driver, this); । ड्राइवर तुरंत पृष्ठ पर तत्वों की तलाश शुरू नहीं करता है, लेकिन जैसे ही हम क्लास फ़ील्ड का उपयोग करते हैं, उनके लिए खोज करता है। उदाहरण के लिए, स्ट्रिंग searchButton.click(); driver.findElement(By.cssSelector("input[type=\"submit\"]")).click(); में "बदल जाता है" driver.findElement(By.cssSelector("input[type=\"submit\"]")).click();
ऐसा लगता है कि इस दृष्टिकोण से प्लसस पर्याप्त नहीं हैं, लेकिन वे हैं:
  1. ड्राइवर की खोज करने की कोई आवश्यकता नहीं है। ई-कॉमर्स (...) और इस खोज को कॉपी-पेस्ट करें;
  2. आप @CacheLookup एनोटेशन का उपयोग कर सकते हैं: जब कोई तत्व पहली बार पाया जाता है, तो ड्राइवर इसे कैश करता है और पहले से ही भविष्य में कैश्ड ऑब्जेक्ट का उपयोग करता है, जो परीक्षणों की गति में थोड़ी वृद्धि देता है;
  3. आप WebElement इंटरफ़ेस का उपयोग करने से दूर हो सकते हैं और पृष्ठ तत्वों जैसे कि Button, TextField आदि के लिए अपनी कक्षाएं बना सकते हैं।

पृष्ठ तत्वों के लिए कस्टम कक्षाएं बनाना


मैं बार-बार इस तथ्य पर चलता हूं कि WebElement इंटरफ़ेस बहुत सुविधाजनक नहीं है:
  1. यह बेमानी कार्यक्षमता प्रदान करता है, उदाहरण के लिए .getCssValue (), जो सेलेनियम परीक्षणों में बिल्कुल अनावश्यक है;
  2. इसका विस्तार नहीं किया जा सकता है, अर्थात् आप हर दिन के लिए अपने बहुत सुविधाजनक तरीकों को नहीं जोड़ सकते हैं, और, तदनुसार, आप इसमें से अनावश्यक तरीकों को नहीं हटा सकते हैं (उदाहरण के लिए, किसी भी लिंक के लिए .isEnabled () विधि अभी कोई मतलब नहीं है);
  3. अधिक जटिल तत्वों के साथ काम करने के लिए (उदाहरण के लिए, ड्रॉप-डाउन सूचियों के साथ) आपको स्पष्ट रूप से सेलेक्ट क्लास के कंस्ट्रक्टर को कॉल करना होगा, जो कुछ प्रकार के हैक की तरह है।

आइए देखें कि आप पेज पर तत्वों के लिए अपने इंटरफेस का उपयोग करके पेज क्लास को कैसे संशोधित कर सकते हैं।
 public class ExtendedSearchPage implements SearchPage { @FindBy(id = "text") private TextField searchField; @FindBy(css = "input[type=\"submit\"]") private Button searchButton; @Override public void search(final String query) { searchField.clearAndType(query); searchButton.click(); } @Override public void init(final WebDriver driver) { PageFactory.initElements(new ExtendedFieldDecorator(driver), this); } } 

इसलिए यहां हम पहले से ही WebElement के बजाय TextField और Button का उपयोग कर रहे हैं। यहां मुख्य बिंदु आइनिट () पद्धति में स्व-लिखित फील्डडेकोरेटर का उपयोग करना है। अब यह वह है जो ExtendedSearchPage वर्ग के क्षेत्रों को आरंभ करता है। इस दृष्टिकोण का उपयोग करने के पेशेवरों:
  1. परीक्षणों की पठनीयता बढ़ जाती है: क्षेत्र के प्रकार को देखते हुए, यह तुरंत स्पष्ट हो जाता है कि यह एक बटन है, और पृष्ठ पर सिर्फ कुछ सार तत्व नहीं है, हालांकि वास्तव में यह एक बटन नहीं हो सकता है, लेकिन यह पहले से ही बटन वर्ग के कार्यान्वयन पर निर्भर करता है;
  2. अपने स्वयं के तरीकों को जोड़ने की क्षमता, उदाहरण के लिए, इनपुट फ़ील्ड के लिए ClearAndType ();
  3. कंटेनर कक्षाएं (तालिकाओं, रूपों, आदि) बनाने के लिए एक और अधिक सुंदर तरीका;

निस्संदेह, एक माइनस: पाया गया प्रत्येक तत्व के लिए, मेमोरी में एक और ऑब्जेक्ट बनाया जाता है, जो बस WebElement ऑब्जेक्ट के लिए सभी कॉल दर्शाता है।

कंटेनर कक्षाएं बनाना


हमेशा की तरह, आपको आरंभ करने के लिए एक छोटा कोड
 public class SearchPageWithSearchForm implements SearchPage { @FindBy(tagName = "form") private SearchForm searchForm; @Override public void search(final String query) { searchForm.search(query); } @Override public void init(final WebDriver driver) { PageFactory.initElements(new ExtendedFieldDecorator(driver), this); } } public class SearchForm extends AbstractContainer { @FindBy(id = "text") private TextField searchField; @FindBy(css = "input[type=\"submit\"]") private Button searchButton; public void search(final String query) { searchField.clearAndType(query); searchButton.click(); } } 

यहां हम पहले से ही खोज फ़ॉर्म के लिए एक पूर्ण-वर्ग को देखते हैं, जिसे आसानी से विभिन्न पृष्ठों पर पुन: उपयोग किया जा सकता है (यदि साइट के सभी पृष्ठों पर खोज फ़ॉर्म को समान रूप से लागू किया गया है)। इसके अतिरिक्त, कंटेनर ऑब्जेक्ट्स को इनिशियलाइज़ करने की प्रक्रिया को इस तरह से लागू करना संभव है कि तत्वों की खोज कंटेनर के अंदर ही होगी, न कि पूरे पेज में, इसलिए यह पता चला है कि कंटेनर को दुनिया के बारे में कुछ भी पता नहीं है, जो अंततः हमें उपयोग करने का अवसर देता है। अन्य पृष्ठों के परीक्षण के लिए इसकी।

स्रोत कोड

नमूना स्रोत यहां से डाउनलोड किए जा सकते हैं


Source: https://habr.com/ru/post/In134462/


All Articles