• 通过Selenium Page Factory谈程序员三境界


    需求例子

    比如我们使用java+Selenium编写页面自动化测试的功能。
    现在有个登录页面。

    1. It works

    public class Login {
      public void testLogin() {
        // fill login data on sign-in page
        driver.findElement(By.name("user_name")).sendKeys("testUser");
        driver.findElement(By.name("password")).sendKeys("my supersecret password");
        driver.findElement(By.name("sign-in")).click();
    
        // verify h1 tag is "Hello userName" after login
        driver.findElement(By.tagName("h1")).isDisplayed();
        assertThat(driver.findElement(By.tagName("h1")).getText(), is("Hello userName"));
      }
    }
    

    面向过程就是命令式的编程,就是意识流,把脑子里的想法转换成指令,让计算机去执行。
    这样的模式是跳过“抽象”这一步骤,而计算机领域,“抽象”“建模”是非常重要的方法,甚至超过编码本身的重要性。
    初级程序员这么写能完成任务也算达成目标了,但我们绝不能止步于此,我们要设想我们的代码要能应对更大的“变化”。

    2. OOP

    import org.openqa.selenium.By;
    import org.openqa.selenium.WebDriver;
    
    /**
     * Page Object encapsulates the Sign-in page.
     */
    public class SignInPage {
      protected static WebDriver driver;
    
      // <input name="user_name" type="text" value="">
      private By usernameBy = By.name("user_name");
      // <input name="password" type="password" value="">
      private By passwordBy = By.name("password");
      // <input name="sign_in" type="submit" value="SignIn">
      private By signinBy = By.name("sign_in");
    
      public SignInPage(WebDriver driver){
        this.driver = driver;
      }
    
      /**
        * Login as valid user
        *
        * @param userName
        * @param password
        * @return HomePage object
        */
      public HomePage loginValidUser(String userName, String password) {
        driver.findElement(usernameBy).sendKeys(userName);
        driver.findElement(passwordBy).sendKeys(password);
        driver.findElement(signinBy).click();
        return new HomePage(driver);
      }
    }
    

    这样就好了一点,利用OOP编程语言提供的OO特性(字段,属性,方法,继承,实现等),进行OOP开发。

    中高级程序员如果能合理的划分项目的文件结构和业务对象,构建不同的抽象角色,承担不同的职责,然后在某处组装调用,那么这个项目至少不会被后来的维护者骂脏话了,也能承受相当长一段时间的业务变化,项目也能服役相当一段时间了。

    然而毫不夸张的说,面试的时候夸夸其谈的所谓的大佬,也未必能很务实的去面向对象开发,尽管他们知道这些理论。他们会选择第一种方式,“又不是不能用”。要么就是眼高手低,要么就是没有热情和追求。

    所以我劝大家务实一点,三思而码。梳理清楚业务需求,先抽象再建模,让代码“活”起来,你在创建一个世界,这个世界里有好多超能力的角色,它们都有自己的职责,而且尽可能地应付变化的袭击。

    3. Best Practice

    package pages;
    
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.support.FindAll;
    import org.openqa.selenium.support.FindBy;
    
    public class Login {
    	
    	final WebDriver driver;
    	
    	//Constructor, as every page needs a Webdriver to find elements
    	public Login(WebDriver driver){
    			this.driver=driver;
    		}
    		
    	//Locating the username text box
    	@FindAll({
    		@FindBy(id="wrapper"),
    		@FindBy(id="userName")
    	})
    	WebElement username;
    	
    	//Locating the password text box
    	@FindBy(id="password")
    	WebElement pswd;
    	
    	//Locating Login Button
    	@FindBy(id="login")
    	WebElement loginBtn;
    	
    	
    	//Method that performs login action using the web elements
    	public void LogIn_Action(String uName, String pwd){
    		username.sendKeys(uName);
    		pswd.sendKeys(pwd);
    		loginBtn.click();
    	}
    }
    
    public static void main(String[] args) {
    	driver = new ChromeDriver();
    	Login loginPg = PageFactory.initElements(driver, Login.class);
    	loginPg.LogIn_Action("---your username---", "---your password---");
    	driver.quit();		
    }
    

    简单看好像与第二种方式没啥区别。事实上,纯熟OOP已经很棒了。如果在此基础上,还能站的更高,甚至站在上帝视角进行看待问题和抽象设计,那么无疑是最佳实践了。
    这种方式使用Page Object Model,将页面视为对象,抽象Factory,结合编程语言的高级特性(诸如反射、注解等),创造出使调用者使用起来会更加友好和简洁的对象模型。

  • 相关阅读:
    psy & vr
    psy 2
    psy
    linux c中select使用技巧
    hostent h_addr_list
    gethostbyname() -- 用域名或主机名获取IP地址
    c_select 调用参数说明
    [NYOJ 737] 石子合并(一)
    [HDU 1059] Dividing
    [HDU 1789] Doing Homework again
  • 原文地址:https://www.cnblogs.com/talentzemin/p/15319410.html
Copyright © 2020-2023  润新知