Selenium的java实践

我们为什么需要Selenium?

回想一下,我们每次打开测试环境网页的原因是什么?是为了出单造数据、以及验证老旧的菜单及按钮,还是为了验证新菜单及按钮的场景更多?我想大多数都是为了操作已有的功能吧。就我个人而言,经常是打开系统操作固定的功能:打开浏览器->输入测试的网址->输入用户名密码->切换角色-> loop 找到对应菜单->录入类似的模板数据->点击确定 end loop;

如果是为了造数据,我们还可以通过整理sql脚本等方式,来代替繁琐的页面操作。但如果是为了回归测试呢,为了验证新代码上线后,旧的已有功能是否受到了影响呢?无论单元测试、接口测试等做的多好,但用户并操作的毕竟是页面,而不是代码,所以作为测试人员,总是需要亲自在系统操作一遍,才能放心的。

既然对已有菜单及按钮的操作,每次都如此类似,那么我们是不是可以利用一些脚本、录屏等,让计算机按既定逻辑自动去点击操作呢?事实上市面上已有挺多这类技术实现手段的,有操作windows系统、操作移动端Andorid/IOS的,还有这篇博客要介绍的,操作Web浏览器的工具 - Selenium。借助这些工具,我们可以在各个平台上,实现操作的自动化,从而释放人力。

Selenium简介

Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7,8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera,Edge等。这个工具的主要功能包括:测试与浏览器的兼容性——测试应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成.Net、Java、Perl等不同语言的测试脚本。

Selenium是一个工具包,并不是一个框架,所以它依赖其他语言去调用它,主流为使用Python或Java语言。在使用特定语言调用的同时,往往还会配合一个该语言的测试框架,如Java的TestNG框架,用于更好地管理测试数据、管理测试案例、产出测试报告、并行执行提升效率等等。

Selenium+Java+Chrome环境搭建

Selenium的jar包只有一个,非常方便,在pom文件里增加如下依赖即可:

		<dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>4.0.0</version>
        </dependency>

如果是非maven工程,那只能自行前往Selenium官网,下载对应jar包并导入工程。

除了Selenium的依赖包外,想要操作浏览器,还需要准备浏览器的驱动包,每个浏览器、不同版本间的包均不相同。以Chrome为例,我本地目前的浏览器版本是98.0.4758.102,则需要下载对应的驱动包,否则可能导致无法正常驱动。

Chrome驱动包下载地址:http://chromedriver.storage.googleapis.com/index.html

准备完毕后,工程结构如下:
在这里插入图片描述

Chrome启动的测试代码为:

public class ChromeTest {

    @Test
    public void testChromeStartAndVisitBaidu(){

        System.setProperty("webdriver.chrome.driver", "./src/test/resources/chromedriver.exe");

        //初始化一个chrome浏览器实例,实例名称叫driver
        WebDriver driver = new ChromeDriver();
        //最大化窗口
        driver.manage().window().maximize();
        //设置隐性等待时间
        driver.manage().timeouts().implicitlyWait(8, TimeUnit.SECONDS);

        // get()打开一个站点
        driver.get("https://www.baidu.com");

        //关闭并退出浏览器
        driver.quit();
    }
}

元素定位

个人认为,使用Selenium编写脚本过程中,最重要也是最困难的点,在于定位元素。

Selenium中常用的定位页面元素方法如下显示,并且最优先使用的定位方法显示在前面:
在这里插入图片描述

元素定位方式很多,特别是XPath定位方法,十分灵活,我使用经验不对,暂不做归纳分享,待后续补充。这里提供一个通过百度,找到我CSDN博客的自动化操作示例:

public class ChromeTest {

    @Test
    public void testChromeStartAndVisitBaidu(){

        System.setProperty("webdriver.chrome.driver", "./src/test/resources/chromedriver.exe");

        //初始化一个chrome浏览器实例,实例名称叫driver
        WebDriver driver = new ChromeDriver();
        //最大化窗口
        driver.manage().window().maximize();
        //设置隐性等待时间
        driver.manage().timeouts().implicitlyWait(8, TimeUnit.SECONDS);

        // get()打开一个站点
        driver.get("https://baidu.com");
        String firstHandle = driver.getWindowHandle();
        driver.findElement(By.id("kw")).sendKeys("再来一块红烧肉CSDN");
        driver.findElement(By.id("su")).click();
        driver.findElement(By.partialLinkText("再来一块红烧肉_CSDN")).click();

        Set<String> allHandles = driver.getWindowHandles();
        for (String handle:allHandles) {
            if(!handle.equals(firstHandle)){
                driver.switchTo().window(handle);
            }
        }
        driver.findElement(By.xpath("//a[text()='关注']")).click();
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //关闭并退出浏览器
        driver.quit();
    }
}

POM页面对象模型

Selenium使用时,大多都是以面向过程的形式编写的代码。而一个站点包含那么多页面,而每个页面又有那么多的元素,如果全部以面向过程的形式编写,则每次都需要重新定位,代码复用率特别低。

Page Object Model(POM) 是selenium代码的一种设计思想,其核心就是将每个页面看作一个类,则页面中的元素则为类的成员变量;页面提供的功能/动作,则作为类的方法。以这样的方式建模封装,则在使用时直接调用方法,复用已有的元素定位等代码,省去不少工作量。

以一个登录页面为例子,一共三个元素,均以成员变量形式定义,登录动作则以方法形式提供。这样,调用页面的登录方法时,只需要传入用户名和密码即可,登录成功还会返回主页的对象,继续在主页对象想调用后续操作即可,以此类推。

public class LoginPage extends BasePage{
    private By username = By.id("username");
    private By password = By.id("password");
    private By signIn = By.xpath("//input[@value='登录']");


    public HomePage login(String userName,String password){
        findElementAndSendKey(username,userName);
        findElementAndSendKey(password,password);
        findElementAndClick(signIn);
        return new HomePage();
    }
}

版权声明:本文为HhmFighting原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。