java+ Webdriver+TestNG自动化测试实践

2017/09/14 10:39
阅读数 588

有很多团队使用Python + selenium + robotframework做自动化测试,好处是不用造“轮子”,缺点是不利于测试人员的职业发展,人工智能都火爆了,我们测试当然要注重提升自身的能力。当然robotframework给我们提供了一个很好的理念:案例分层测试,使用抽象与封装,把一个实现过程分成不同多层。提高的灵活性,从而达到可扩展性和可维护性。
下面简单介绍环境搭建和着重介绍我们测试过程中遇到的问题,希望能帮到一些测试同学。
一、环境搭建:
1)安装32位的1.8的jdk,并配置环境变量。CLASSPATH=.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar
JAVA_HOME=D:\Program Files\Java\jdk1.8
PATH=%JAVA_HOME%\bin
2)下载testng离线安装testng插件(因为公司网络限制,无法在线安装testng插件),将features文件夹的jar包拷贝到eclipse的features文件夹内,将plugins文件夹的jar包拷贝到plugins文件夹里,然后重启eclipse,验证是否安装成功。








3)网上下载selenium-java-2.53.0,引入到工程里。








4)下载浏览器驱动,注意:必须得是32位的,否则会出现64位系统下执行非常慢的问题。当然得配置环境变量,否则无法启动浏览器。









二、认识常见的定位方式:常见的定位方式有id、name、链接的全部文字定位、链接的部分文字定位、XPath定位、CSS定位、class名称定位、tagName定位、jQuery定位。语法如下:WebDriver driver;
JavascriptExecutor js;
WebElement element = driver.findElement(By.id("ID值"));//ID定位
WebElement element = driver.findElement(By.name("name值"));//name定位WebElement element =driver.findElement(By.linkText("链接的全部文字内容"));
WebElement element =driver.findElement(By.partialLinkText("链接的部分文字内容"));
WebElement element =driver.findElement(By.xpath("//span[contains(text(), '确定')]"));//xpath定位的一个例子
WebElement element =driver.findElement(By.cssSelector("#gfxftd > span > input.combo-text"));//CSS定位的一个例子
WebElement element = driver.findElement(By.className("页面的class属性值"));
WebElement element = driver.findElement(By.tagName("页面中的HTML标签名称"));
js = (JavascriptExecutor )driver;
WebElement element=(WebElement)js.executeScript("jQuery定位表达式");        //调用jQuery库从查找功能

以下是xpath的定位介绍:
第一种方法:通过绝对路径做定位(相信大家不会使用这种方式)
By.xpath("html/body/div/form/input")
第二种方法:通过相对定位
By.xpath("//input")
第三种方法:通过元素索引定位
By.xpath("//input[4]")
第四种方法:使用xpath属性定位(结合第2、第3中方法可以使用)
By.xpath("//input[@id='kw1']")
By.xpath("//input[@type='name' and @name='kw1']")
第五种方法:使用部分属性值匹配(最强大的方法)
By.xpath("//input[start-with(@id,'nice')
By.xpath("//input[ends-with(@id,'很漂亮')
By.xpath("//input[contains(@id,'那么美')]")  //税务组大量使用这种方式
以下是税务组使用部分属性匹配的一个例子
driver.switchTo().frame(driver.findElement(By.xpath("//iframe[contains(@src,'/vatmgr/saleInvoice/invoiceRed/special/create.jsp')]")));

以下是tagName的一个例子 List<WebElement> allInputs = driver.findElements(By.tagName("input"));



三、自动化测试中常见的问题:

1)NoSuchElementException: Unable to find element with xpath 
字面意思很简单,使用xpath找不到元素。原因是定位不正确或是速度太快,元素或页面还没有加载完。
解决办法:
a) 先确定定位是否正确;
b)若定位正确,加一个等待。常用的等待有 显示等待 > 隐式等待 > Thread.sleep()
显示等待使用语法如下:
//设定一个阈值150秒。只有满足显示等待的条件要求,测试代码才会继续向后执行后续的测试逻辑。当显示等待条件未被满足的时候,在设定的最大显示等待时间阈值内,会停留在当前代码位置等待,直到设定的等待条件被满足,才会继续执行后续的测试逻辑。如果超过设定的最大显示等待时间阈值,则测试程序会抛出异常,测试用例被认为执行失败。
WebDriverWait wt = new WebDriverWait(driver,150)//设置显示等待最长等待时间为150秒,用于显示等待
wt.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//div[.='平安健康保险股份有限公司广东分公司']"))).click();//页面元素在页面中存在,我们税务组目前只用到这一种显示等待

页面元素是否被选中,例如单选复选框,可以使用 elementToBeSelected(By locator)
页面元素是否包含特定的文本,可以使用 textToBePresentInElement(By locator)

隐式等待语法如下:
//不推荐使用,缺点是设定了等待时长,则在页面元素没有被立即找到的情况下,测试程序也必须等待设定的时长。例如,设定了隐式等待时间为10秒,即使页面元素在过了5秒后显示了,测试程序也会等待10秒后再进行页面元素的查找工作
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);


c)实际应用可能使用显示等待也无法找到元素,这时就要靠自己写代码来处理,我们税务组是这样处理的:
WebElement sr = null;
while(null == sr) {
        try {
                sr = driver.findElement(By.cssSelector("#gfxftd > span > input.combo-text"));
        } catch (Exception e) {
        // TODO: handle exception
                continue;
        }
}


sr.sendKeys("平安健康保险股份有限公司广东分公司");
这里使用while循环来代替等待,因为系统不稳定,也是不得已而为之,出现异常了,依然让它循环,直到找到为止。



2)NullPointerException:空指针异常
出现空指针异常的原因必定是出现了null,出现null的情况多为:类没有初始化就直接使用;参数在传递过程中,没有正确传递过来导致后续被调用方法中接受到的参数实际为null;
出现这种异常,就检查类有没初始化,若初始化了还报空指针,就一定是元素没找着,解决方法:还是使用上面写的while循环。

3)iframe的处理:
iframe是嵌套的页面,必须使用driver.switchTo().frame处理,以下是一段代码
driver.switchTo().defaultContent();//由上个iframe切出
driver.switchTo().frame(driver.findElement(By.xpath("//iframe[contains(@src,'/vatmgr/saleInvoice/invoiceRed/special/create.jsp')]")));
遇到多个iframe就需要确定iframe的位置,若是嵌套就需要多次使用driver.switchTo().frame,注意iframe里的操作完成后,需要切回原页面,就需要使用driver.switchTo().defaultContent(),可能需要多次使用,这取决于iframe嵌套了几层,若是两层,就需要使用两次。

4)找到元素,但是无法点击,这种情况比较普遍:我们使用JS来点击元素
//这里有时找不到,我使用下面的JS来代替一般元素定位按钮点击新增按钮
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].click();",
driver.findElement(By.id("matterAdd")));




5)表格的处理:将页面所有的input框找到放到一个list里,然后遍历判断。
//得到第一条单选框,定位标签,然后判断,找到第2个checkbox
                        List<WebElement> allInputs = driver.findElements(By.tagName("input"));
                        
                        WebElement wb=null;
                        int i=0;
                        for(WebElement e: allInputs){
                                
                                System.out.println(e.getAttribute("type"));
                                if (e.getAttribute("type").equals("checkbox")){
                                        
                                        if(i==1){
                                                System.out.println(e.getText().toString());
                                                wb=e;
                                                break;
                                        }
                                        i++;
                                }
                        }
                        if(wb!=null){
                                wb.click();                
                        }


6)封装逻辑:有的时候webdriver的API无法满足我们的需求,这个时候就需要自己封装实现。webdriver中有个WebDriverWait对象,以下是封装的显示等待的一个例子
//封装显示等待
public static WebElement webelementExplicitWait(WebDriver driver,By by){
    return (new WebDriverWait(driver, 10)) .until(
                new ExpectedCondition< WebElement>(){
                    @Override
                    public WebElement apply(WebDriver d) {
                        return d.findElement(by);
                        }
                    }
                )
}

以上代码是时间写死了,可重写以上方法,多传一个时间参数

public static WebElement webelementExplicitWait(WebDriver driver, By by, int second ){
    return (new WebDriverWait(driver, 
second)) .until(
                new ExpectedCondition< WebElement>(){
                    @Override
                    public WebElement apply(WebDriver d) {
                        return d.findElement(by);
                        }
                    }
                )
}

这种写法好像测试工程师看起来费劲,而且没有捕获异常,修改成以下代码:
public static WebElement webelementExplicitWait(WebDriver driver, By by, int second ){
       
WebElement waitElement = null;
       WebDriverWait wait = new WebDriverWait(driver, second);
       //以下用于捕获异常
       try{
              waitElement = wait.until(new ExpectedCondition<WebElement>(){
                     public WebElement apply(WebDriver d) {
                        return d.findElement(by);
                     }
              })
       }catch(Exception e){
             System.out.println(by.toString() + " is not exist until " + second);    
       }
       return  waitElement;  //返回waitElement对象
}
 

展开阅读全文
打赏
1
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
1
分享
返回顶部
顶部