一、Selenium中如何判断元素是否存在?

selenium中没有提供原生的方法判断元素是否存在,一般我们可以通过定位元素+异常捕获的方式判断。

# 判断元素是否存在
try:
    dr.find_element_by_id('none')
except NoSuchElementException:
    print 'element does not exist'

二、selenium中hidden或者是display = none的元素是否可以定位到?

不可以,selenium不能定位不可见的元素。display=none的元素实际上是不可见元素。

三、selenium中如何保证操作元素的成功率?也就是说如何保证我点击的元素一定是可以点击的?

1.被点击的元素一定要占一定的空间,因为selenium默认会去点这个元素的中心点,不占空间的元素算不出来中心点;
2.被点击的元素不能被其他元素遮挡;
3.被点击的元素不能在viewport之外,也就是说如果元素必须是可见的或者通过滚动条操作使得元素可见;
4.判断元素是否是可以被点击的

四、如何提高selenium脚本的执行速度?

1.使用更高配置的电脑和选择更快的网络环境
2.使用效率更高的语言,比如java执行速度就快过python
3.优化代码
4.不要盲目的加sleep,尽量使用显式等待
5.对于firefox,考虑使用测试专用的profile,因为每次启动浏览器的时候firefox会创建1个新的profile,对于这个新的profile,所有的静态资源都是从服务器直接下载,而不是从缓存里加载,这就导致网络不好的时候用例运行速度特别慢的问题
6.chrome浏览器和safari浏览器的执行速度看上去是最快的
7.可以考虑分布式执行或者使用selenium grid

五、用例在运行过程中经常会出现不稳定的情况,也就是说这次可以通过,下次就没办法通过了,如何去提升用例的稳定性?

1.测试专属profile,尽量让静态资源缓存
2.尽量使用显式等待
3.尽量使用测试专用环境,避免其他类型的测试同时进行,对数据造成干扰

六、你的自动化用例的执行策略是什么?

1.每日执行:比如每天晚上在主干执行一次
2.周期执行:每隔2小时在开发分之执行一次
3.动态执行:每次代码有提交就执行

七、自动化测试的时候是不是需要连接数据库做数据校验?

一般不需要,因为这是单元测试层做的事情,在自动化测试层尽量不要为单元测试层没做的工作还债。

八、id,name,clas,xpath, css selector这些属性,你最偏爱哪一种,为什么?

xpath和css最为灵活,所以其他的答案都不够完美。

九、如何去定位页面上动态加载的元素?

显示等待

十、如何去定位属性动态变化的元素?

找出属性动态变化的规律,然后根据上下文生成动态属性

十一、selenium的原理是什么?

selenium的原理涉及到3个部分,分别是

  1. 浏览器
  2. driver: 一般我们都会下载driver
  3. client: 也就是我们写的代码

client其实并不知道浏览器是怎么工作的,但是driver知道,在selenium启动以后,driver其实充当了服务器的角色,跟client和浏览器通信,client根据webdriver协议发送请求给driver,driver解析请求,并在浏览器上执行相应的操作,并把执行结果返回给client。这就是selenium工作的大致原理。

十二、webdriver的协议是什么?

webdriver协议本身是http协议,数据传输使用json。

十三、什么是page object设计模式?

官方介绍,简单来说就是用class去表示被测页面。在class中定义页面上的元素和一些该页面上专属的方法。
例子

public class LoginPage {
    private final WebDriver driver;
 
    public LoginPage(WebDriver driver) {
        this.driver = driver;
 
        // Check that we're on the right page.
        if (!"Login".equals(driver.getTitle())) {
            // Alternatively, we could navigate to the login page, perhaps logging out first
            throw new IllegalStateException("This is not the login page");
        }
    }
 
    // The login page contains several HTML elements that will be represented as WebElements.
    // The locators for these elements should only be defined once.
        By usernameLocator = By.id("username");
        By passwordLocator = By.id("passwd");
        By loginButtonLocator = By.id("login");
 
    // The login page allows the user to type their username into the username field
    public LoginPage typeUsername(String username) {
        // This is the only place that "knows" how to enter a username
        driver.findElement(usernameLocator).sendKeys(username);
 
        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;
    }
 
    // The login page allows the user to type their password into the password field
    public LoginPage typePassword(String password) {
        // This is the only place that "knows" how to enter a password
        driver.findElement(passwordLocator).sendKeys(password);
 
        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;
    }
 
    // The login page allows the user to submit the login form
    public HomePage submitLogin() {
        // This is the only place that submits the login form and expects the destination to be the home page.
        // A seperate method should be created for the instance of clicking login whilst expecting a login failure.
        driver.findElement(loginButtonLocator).submit();
 
        // Return a new page object representing the destination. Should the login page ever
        // go somewhere else (for example, a legal disclaimer) then changing the method signature
        // for this method will mean that all tests that rely on this behaviour won't compile.
        return new HomePage(driver);
    }
 
    // The login page allows the user to submit the login form knowing that an invalid username and / or password were entered
    public LoginPage submitLoginExpectingFailure() {
        // This is the only place that submits the login form and expects the destination to be the login page due to login failure.
        driver.findElement(loginButtonLocator).submit();
 
        // Return a new page object representing the destination. Should the user ever be navigated to the home page after submiting a login with credentials
        // expected to fail login, the script will fail when it attempts to instantiate the LoginPage PageObject.
        return new LoginPage(driver);
    }
 
    // Conceptually, the login page offers the user the service of being able to "log into"
    // the application using a user name and password.
    public HomePage loginAs(String username, String password) {
        // The PageObject methods that enter username, password & submit login have already defined and should not be repeated here.
        typeUsername(username);
        typePassword(password);
        return submitLogin();
    }
}

十四、page object设计模式中,如何实现页面的跳转?
返回另一个页面的实例可以代表页面跳转。

// The login page allows the user to submit the login form
public HomePage submitLogin() {
    // This is the only place that submits the login form and expects the destination to be the home page.
    // A seperate method should be created for the instance of clicking login whilst expecting a login failure.
    driver.findElement(loginButtonLocator).submit();
 
    // Return a new page object representing the destination. Should the login page ever
    // go somewhere else (for example, a legal disclaimer) then changing the method signature
    // for this method will mean that all tests that rely on this behaviour won't compile.
    return new HomePage(driver);
}

十五、你觉得自动化测试最大的缺陷是什么?

  1. 实现成本高
  2. 运行速度较慢
  3. 需要一定的代码能力才能及时维护

十六、什么是分层测试
分层测试

Q.E.D.


Nothing really matters to me!