美文网首页
Selenuim Testing - Framworks

Selenuim Testing - Framworks

作者: 小眼睛的露鹿酱 | 来源:发表于2019-04-22 19:12 被阅读0次

    POM(Page object Model) & Page Factory: WebDriver
    POM是一种设计模式,用于创建web ui元素的对象存储库。在这种模式下,每一个WEB应用下的页面都应该具有一个相关的page的class; 这个class能够寻找到所有页面的webElement, 还包含各种能够实现操作的methods;
    这些methods的名字应该作为每一个操作的目标。例如, 一个加载器正在等待要显示的支付网关;那就可以将这个POM中cloass的methods写成 waitForPaymentScreenDisplay()

    开始一个UI的自动化测试, 并不是一个很艰难的工作。 我们只需要找到相关的Element, 来完成对应的功能。
    考虑下面的一个简单的脚本去登陆一个网站



    正如你所见, 无非就是去找到元素, 然后输入对应的值。这是一个简单的脚本,脚本看上去很容易, 但是随着时间的增长,你需要增减越来越多的代码, 事情就变得很复杂。
    最主要的问题就是 假如10个不同的而脚本正在使用相同的元素,一旦有任何的改变, 我们就需要改变所有的代码。这即费时还费力。
    一个更好的维护脚本的方法就是去创建单独的class , 能够找到对应得元素或者就是去输入值, 或者去验证。这个class能够被重复利用,而且能够容易维护。
    这种方法被称为 POM;


    优势

    1. 代码简单而且容易理解
    2. 重复利用, 还能集成到TestNG和Junit来做单元测试
      代码会简洁而且被优化
    3. methods包含更加容易理解得名称

    如何实现POM

    简单得POM
    POM模式得基本结构就是所有得页面得元素和操作都保存在一个class中;操作都保存在methods中



    TestCase:


    testcase
    这个流程涉及到两个界面
    1. 登陆界面
    2. homepage界面
      分别对应以下两个class
    package POMdemo;
    
    import org.openqa.selenium.By;
    import org.openqa.selenium.WebDriver;
    
    public class LoginPage4Baidu {
          WebDriver driver;
          By user = By.name("uid");
          By pwd = By.name("password");
          By login = By.name("btnLogin");
          By resetBy = By.name("btnReset");
          By titletext = By.className("barone");  //如果click正确后,用于验证(Guru99 Bank)是否登陆成功;
          
          //构造函数
          public LoginPage4Baidu(WebDriver driver) {
              this.driver = driver;
          }
    
        public void setUser(String username) {
            driver.findElement(user).sendKeys(username);
        }
        
        public void setPwd(String pwdString) {
            driver.findElement(pwd).sendKeys(pwdString);
        }
    
        public void clickLogin() {
            driver.findElement(login).click();
        }
    
        public void clickResetBy() {
            driver.findElement(resetBy).click();
        }
            
        public String getLoginTitle() {
          String titleString = driver.findElement(titletext).getText();
            return titleString;
        }
        
        public boolean loginPass() {
            return "Guru99 Bank".equals(getLoginTitle());
        }
        
        
    }
    
    
    package POMdemo;
    
    
    import java.io.ObjectInputStream.GetField;
    
    import org.openqa.selenium.By;
    import org.openqa.selenium.WebDriver;
    
    public class Homepagedemo {
        WebDriver driver;
        By content = By.xpath("/html/body/table/tbody/tr/td/table/tbody/tr[3]/td");
        
        public Homepagedemo(WebDriver driver) {
            this.driver = driver;
        }
        
        public String GetTitle() {
            return driver.findElement(content).getText();
        }
    }
    
    

    调用以上的class,完成测试

    package POMdemo;
    
    import java.sql.Driver;
    
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.chrome.ChromeDriver;
    
    public class pomDemo1 {
    
          WebDriver driver;
          LoginPage4Baidu loginObj;
          Homepagedemo homepageObj;
          
          //setup before test
          public void setup() {
              String driverLocationString = "D:\\codding\\seleniumTest\\seleniumDemo1\\DriverFolder\\chromedriver.exe";
              System.setProperty("webdriver.chrome.driver", driverLocationString);
              this.driver = new ChromeDriver(); 
              driver.get("http://demo.guru99.com/V4");
          }
          
          // test
          public void Login2checkName() {
              loginObj = new LoginPage4Baidu(this.driver);
              loginObj.setUser("mgr123");
              loginObj.setPwd("mgr!23");
              loginObj.clickLogin();
              System.out.println(loginObj.loginPass());
              
              homepageObj = new Homepagedemo(driver);
              String title = homepageObj.GetTitle();
              System.out.println("login passed and title is"+title);
          }
          
          public static void main(String[] args) {
            pomDemo1 demo1 = new pomDemo1();
            demo1.setup();
            demo1.Login2checkName();
            demo1.driver.quit();
        }
    }
    
    

    page Factory

    Page Factory 是一种内建的Page Object 模型概念, 用于Selenuim WebDriver, 但是它是优化的。
    在这里,我们遵循页面对象存储和methods的分离概念。另外在PageFatory class的帮助下,我们使用注释 @FindBy 来寻找 WebElement。 我们使用initElements来初始化web元素。



    @FindBy 能使用 tagName partialLinkTest,name, linkTest,id,css,className, xpath作为属性。
    以下就是一个例子

    1. login Class
    package POMDEMO1;
    
    import java.security.PublicKey;
    
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.support.FindBy;
    import org.openqa.selenium.support.PageFactory;
    
    public class loginPage {
       WebDriver driver;
       @FindBy(name="uid") WebElement username;      //类似于driver.findElement(By....)
       @FindBy(name="password") WebElement password;
       @FindBy(name="btnLogin") WebElement loginIcon;
       @FindBy(name="btnReset") WebElement resetIcon;
       
       public loginPage(WebDriver driver) {
           this.driver = driver;
           
           //下面的methods会创建所有的webElemets
           PageFactory.initElements(driver, this);
       }
       
       
       public void setUsername(String usernamestring) {
           username.sendKeys(usernamestring);
       }
       
       public void setPWD(String pwdString) {
           password.sendKeys(pwdString);
       }
       
       public void clickLogin() {
           loginIcon.click();
       }
       
       public void clickReset() {
           resetIcon.click();
       }
       
       public void user2login(String user,String pwd) {
           this.setUsername(user);
           this.setPWD(pwd);
           this.clickLogin();
       }
    }
    
    1. homepage class
    package POMDEMO1;
    
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.support.FindBy;
    import org.openqa.selenium.support.PageFactory;
    
    public class homepage {
        WebDriver driver;
        @FindBy(xpath="/html/body/table/tbody/tr/td/table/tbody/tr[3]/td") WebElement context;
        
        public homepage(WebDriver driver) {
            this.driver = driver;
            PageFactory.initElements(driver, this);
        }
        
        public String getContext() {
            return context.getText();
        }
    }
    
    
    1. TestNG test
    package POMDEMO1;
    
    import java.util.concurrent.TimeUnit;
    
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.chrome.ChromeDriver;
    import org.testng.Assert;
    import org.testng.annotations.AfterTest;
    import org.testng.annotations.BeforeTest;
    import org.testng.annotations.Test;
    
    public class POMdemo1 {
       WebDriver driver;
       loginPage loginObj;
       homepage homepageObj;
       
       @BeforeTest
       public void setup() {
           String driverLocationString = "D:\\codding\\seleniumTest\\seleniumDemo1\\DriverFolder\\chromedriver.exe";
           System.setProperty("webdriver.chrome.driver", driverLocationString);
           driver = new ChromeDriver();
           driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
           driver.get("http://demo.guru99.com/V4");
       }
       
       @Test(priority=0)
       public void test() {
           loginObj = new loginPage(driver);
           loginObj.user2login("mgr123", "mgr!23");
           homepageObj = new homepage(driver);
           Assert.assertTrue(homepageObj.getContext().toLowerCase().contains("manger id : mgr123"));
       }
       @AfterTest
       public void quit() {
           driver.quit();
       }
    }
    
    

    推荐使用:
    AjaxElementLocatorFactory 包含wait时间


    waits

    在Selenuim中, Waits扮演了一个重要的角色。在这个教程中,你将学习到“implicit”和“Explicit”两种wait

    为什么我们需要Waits

    其实大部分得页面都是使用Ajax和JavaScript两种。当一个页面在浏览器中被加载得时候,页面中的元素会在不同的时间间隔中被加载。
    如果页面没有加载完整, 这不仅会让识别元素变得困难, 而且会报出“ElementNotVisibleException”, 当使用Waits,我们就能有效地避免这个问题。
    让我们来模拟一种情景, 我们需要在我们的脚本中使用implicit和explicit两种waits;假定 implicit设置的是20s, 而explicit设置的是10s。
    假设我们正在寻找一个元素, 这个元素包含“ExpectedConditions”(外部Wait), 如果这个元素没有在规定的10s内加载好, 那他就会执行implicit Wait(20s); 要是还没有加载好, 就会抛异常。

    Implicit Wait

    Selenuim WebDriver 参考了Watir的隐式wait的观点。
    这种wait会告诉WebDriver去等待确定的时间, 然后再抛出异常:"No Such Element Exception". 默认的时间是0.一旦我们设置了时间, WebDriver会等待。
    下面的例子中, 声明了一个隐式的wait, 具体的时间是10s。

    driver.manage().timeouts().implicitlyWait(TimeOut, TimeUnit.SECONDS);   
    
    driver = new ChromeDriver(); 
    driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS) ;
        String eTitle = "Demo Guru99 Page";
    

    Explicit Wait

    显示的wait就是去告诉WebDriver去等待确定的条件或者是最大的时间, 然后再抛出异常“ElementNotVisibleExpection”
    显式的wait是一个很智能的等待, 但是他被应用与特定的element;显式的等待比较好的一个原因是 动态的等待Ajax元素的加载
    一旦我们声明一个explicit wait, 我们需要使用“ExpectedConditions”或者我们能配置查看条件(使用 Fluent Wait)满足的频率。
    These days while implementing we are using Thread.Sleep() generally it is not recommended to use

    WebDriverWait wait = new WebDriverWait(WebDriverRefrence,TimeOut);
    
    driver = new ChromeDriver(); 
    WebDriverWait wait=new WebDriverWait(driver, 20);
    String eTitle = "Demo Guru99 Page";
        String aTitle = "" ;
        // launch Chrome and redirect it to the Base URL
        driver.get("http://demo.guru99.com/test/guru99home/" );
        //Maximizes the browser window
        driver.manage().window().maximize() ;
        //get the actual value of the title
        aTitle = driver.getTitle();
        //compare the actual title with the expected title
        if (aTitle.contentEquals(eTitle))
        {
        System.out.println( "Test Passed") ;
        }
        else {
        System.out.println( "Test Failed" );
        }
        WebElement guru99seleniumlink;
        guru99seleniumlink= wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath( "/html/body/div[1]/section/div[2]/div/div[1]/div/div[1]/div/div/div/div[2]/div[2]/div/div/div/div/div[1]/div/div/a/i")));
        guru99seleniumlink.click();
        }
    

    注意: 以上的例子中我们会等待20秒直到后面的条件满足, 然后我们点击click
    下面举例一些条件语句:
    1. alertIsPresent()
    2. elementSelectionStateToBe()
    3. elementToBeClickable()
    4. elementToBeSelected()
    5. frameToBeAvaliableAndSwitchToIt()
    6. invisibilityOfTheElementLocated()
    7. invisibilityOfElementWithText()

    1. presenceOfAllElementsLocatedBy()
    2. presenceOfElementLocated()
    3. textToBePresentInElement()
    4. textToBePresentInElementLocated()
    5. textToBePresentInElementValue()
    6. titleIs()
    7. titleContains()
    8. visibilityOf()
    9. visibilityOfAllElements()
    10. visibilityOfAllElementsLocatedBy()
    11. visibilityOfElementLocated()

    Fluent Wait

    流利的等待就是为了告诉webDriver, 抛出异常之前的等待条件, 以及检查条件满足的频率。
    频率:以一个固定的交互时间来检测是否条件满足。
    让我们考虑一个以不同的时间间隔加载元素的场景。如果我们声明显式等待20秒,该元素可能会在10秒,20秒甚至更长时间内加载。在抛出异常之前它会等到指定的时间。在这种情况下,流畅的等待是理想的等待使用,因为这将尝试以不同的频率找到元素,直到它找到它或最终的计时器用完为止。

    Wait wait = new FluentWait(WebDriver reference)
    .withTimeout(timeout, SECONDS)
    .pollingEvery(timeout, SECONDS)
    .ignoring(Exception.class);
    
    package guru.test99;
    
    import org.testng.annotations.Test;
    import java.util.NoSuchElementException;
    import java.util.concurrent.TimeUnit;
    import java.util.function.Function;
    
    import org.openqa.selenium.By;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.chrome.ChromeDriver;
    import org.openqa.selenium.support.ui.ExpectedConditions;
    import org.openqa.selenium.support.ui.FluentWait;
    import org.openqa.selenium.support.ui.Wait;
    import org.openqa.selenium.support.ui.WebDriverWait;
    import org.testng.annotations.Test;
    
    public class AppTest3 {
        protected WebDriver driver;
        @Test
        public void guru99tutorials() throws InterruptedException 
        {
        System.setProperty ("webdriver.chrome.driver",".\\chromedriver.exe" );
        String eTitle = "Demo Guru99 Page";
        String aTitle = "" ;
        driver = new ChromeDriver();
        // launch Chrome and redirect it to the Base URL
        driver.get("http://demo.guru99.com/test/guru99home/" );
        //Maximizes the browser window
        driver.manage().window().maximize() ;
        //get the actual value of the title
        aTitle = driver.getTitle();
        //compare the actual title with the expected title
        if (aTitle.contentEquals(eTitle))
        {
        System.out.println( "Test Passed") ;
        }
        else {
        System.out.println( "Test Failed" );
            }
        
        Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)                            
                .withTimeout(30, TimeUnit.SECONDS)          
                .pollingEvery(5, TimeUnit.SECONDS)          
                .ignoring(NoSuchElementException.class);
        WebElement clickseleniumlink = wait.until(new Function<WebDriver, WebElement>(){
        
            public WebElement apply(WebDriver driver ) {
                return driver.findElement(By.xpath("/html/body/div[1]/section/div[2]/div/div[1]/div/div[1]/div/div/div/div[2]/div[2]/div/div/div/div/div[1]/div/div/a/i"));
            }
        });
        //click on the selenium link
        clickseleniumlink.click();
        //close~ browser
        driver.close() ;
        }
    }
    

    频率设置的是5s, 最大的时间是30s,每五秒检查一次元素,不超过30s 要是还是没有就会去报" ElementNotVisibleException"


    image.png

    不推荐使用Thread.Sleep()

    相关文章

      网友评论

          本文标题:Selenuim Testing - Framworks

          本文链接:https://www.haomeiwen.com/subject/smkugqtx.html