Selenium Java版(笔记)

介绍

Selenium是最广泛的web端UI自动化框架,支持java、python、ruby等编辑语言。 官网地址:https://selenium.dev/
Selenium家族

  • Selenium IDE: 是浏览器的扩展插件,通过Selenium IDE我们可以录制和回放浏览器操作。
  • Selenium WebDriver: Selenium的核心,提供了各种语言环境的API来支持更多控制权和编写符合标准软件开发实践的应用程序。
  • Selenium Grid: 分布式测试,通过Selenium Grid可以将自动化测试脚本分发到不同的测试机器中执行。

Selenium WebDriver

一、引入Maven依赖

<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.141.59</version>
</dependency>

****仓库地址:****https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java
下载浏览器驱动(版本须于浏览器一致)

  • 在chrome浏览器的地址栏上面输入chrome://version获取chrome版本/在chrome设置中查看对应版本在这里插入图片描述

二、下载对应的chromedriver驱动:

  • 谷歌版本122驱动百度云盘获取 链接:https://pan.baidu.com/s/1VfCzRFFcJh4sGQhVUOWZEg
    提取码:1234

  • 其他版本驱动:https://chromedriver.storage.googleapis.com/index.html
    将驱动解压至项目目录下
    在这里插入图片描述

		//引用driver路径(路径为相对路径)
        System.setProperty("webdriver.chrome.driver", "src/test/resources/chromedriver-win32/chromedriver.exe");
		//引用浏览器driver
        ChromeDriver chromeDriver = new ChromeDriver();
       	//访问URL
        chromeDriver.get("https://www.qimao.com/");

基础元素定位

id定位:

By.id("id");

name定位

By.name("名称");

标签名定位

By.tagName("标签名");

样式名定位

By.className("样式名");

超链接完整文本定位

By.linkText("超链接完整文本地址");

超链接部分文本定位

By.partialLinkText("超链接部分文本地址");

css选择器定位

By.cssSelector("标签名") //实现方式可百度

xpath定位

  • xpath其实就是一个path(路径),一个描述页面元素位置信息的路径,相当于元素的坐标

绝对定位(禁止使用,后期维护成本极差)
在这里插入图片描述

chromeDriver.findElement(By.xpath("/html/body/div[1]/div/div/header/div[2]/div/div/div[2]/div[2]/div/a/span");

相对定位 相对路径以//表示

在这里插入图片描述

//通过文本定位
chromeDriver.findElement(By.xpath("//span[text()=\"立即登录\"]"));
//xxx为属性名, yyy为对应的值
chromeDriver.findElement(By.xpath("//span[@xxx=\"yyy\"]"));
//模糊匹配
chromeDriver.findElement(By.xpath("//span[contains(text(),\"立即\")]"));

xpath轴定位

ancestor选取当前结点的所有先辈(父、祖父等)
ancestor-or-self选取当前节点的所有先辈(父、祖父等)以及当前节点本身
attribute选取当前节点的所有属性。@id等价于attribute::id
child选取当前节点的所有子元素,title等价于child:title
descendant选取当前节点的所有后代元素(子、孙等)
descendant-or-self选取当前节点的所有后代运算(子、孙等)以及当前节点本身
following选取文档中当前节点的结束标签之后的所有结点
namespace选取当前节点的所有命名空间节点
parent选取当前节点的父节点
preceding选取当前节点的父节点
preceding-sibling选取当前节点之前的所有同级节点
self选取当前节点。等驾驭self::node()
以上方式都无法定位到元素的情况下,可以考虑轴定位
在这里插入图片描述
By.ByXPath("//div[@class=\"qm-header-con\"]//following-sibling::span");

其他方法参考: https://blog.csdn.net/yiqiushi4748/article/details/104037528

三大等待

**- 硬性等待:**强制等待x秒

//缺点:有点浪费时间
Thread.sleep(8);

**- 隐式等待:**在一定时间内只要找到元素就会结束等待,若没找到则会一直等待

//使用场景比较局限(不能判断元素是否可以点击/可见)
chromeDriver.manage().timeouts().implicitlyWait(8000, TimeUnit.MINUTES);

**- 显示等待:**在一定时间内只要找到元素就会结束等待,若未找到元素则会抛出超时等待异常

//实用场景很多如(可见、存在、可点击等),比较推荐
WebDriverWait webDriverWait = new WebDriverWait(chromeDriver,2);
webDriverWait.until(ExpectedConditions.elementToBeClickable(By.xpath("//span[contains(text(),\"立即\")]"))).click();

其他方法参考:https://blog.csdn.net/qq_39704682/article/details/85596644

三大切换

- 切换Iframe

//xxx为frame中的name/id属性
chromeDriver.switchTo().frame("xxx");
//通过xpath进行定位
chromeDriver.switchTo().frame(chromeDriver.findElement(By.xpath("xxx")))
//返回父级Iframe
driver.switchTo().parentFrame();
//返回默认Iframe
driver.switchTo().defaultContent();

- 切换Alert

//获取文本
chromeDriver.switchTo().alert().getText();
 //点击确认按钮
……alert.accept();
//取消
……alert.dismiss();

- 切换Window

new WebDriverWait(driver, 8).until(ExpectedConditions.elementToBeClickable(driver.findElement(By.xpath("//a[@aria-label=\"秒杀\"]")))).click();
//遍历所有窗口
 for (String i : driver.getWindowHandles()) {
     driver.switchTo().window(i);//切换窗口
     System.out.println("--------------" + driver.getTitle());
            //获取title文本
     if ("京东秒杀-正品保证、天天低价、限时限量".equals(driver.getTitle())){System.out.println("进来了:" + driver.getTitle());}

鼠标操作

clickAndHold在特定元素上单击鼠标左键(不释放)
release在特定元素上释放鼠标左键
doubleClick在特定元素上双击鼠标左键
moveToElement移动鼠标指针到特定元素
contextClick在特定元素上右键单击
dragAndDrop拖拽元素
perform调用perform后才会真正执行操作
Actions actions=  new Actions(driver);
WebElement webElement = driver.findElement(By.xpath("//a[text()=\"我的京东\"]"));
//移动到指定位置
actions.moveToElement(webElement).build().perform();
}

其他操作:https://zhuanlan.zhihu.com/p/396773865

文件上传

  • 标签中带有input标签,可以通过senkeys进行上传文件
  • 上传文件标签中没有input标签,则需要借助第三方工具如(autoit)官方地址:https://www.autoitscript.com/site/autoit/downloads/
    参考:https://www.cnblogs.com/yunman/p/7112882.html#:~:text=selenium%2Bjava%E5%88%A9%E7%94%A8AutoIT%E5%AE%9E%E7%8E%B0%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0%201%20AutoIT%E8%84%9A%E6%9C%AC%E7%BC%96%E8%AF%91%E6%88%90%E5%8F%AF%E6%89%A7%E8%A1%8C%E6%96%87%E4%BB%B6%E5%90%8E%EF%BC%8C%E6%94%BE%E5%88%B0%E6%9C%AC%E5%9C%B0%E7%9A%84%E6%9F%90%E4%B8%80%E4%B8%AA%E7%9B%AE%E5%BD%95%E4%B8%8B,2%20%E8%87%AA%E5%8A%A8%E5%8C%96%E5%AE%9E%E7%8E%B0%E8%BF%87%E7%A8%8B%E4%B8%AD%EF%BC%8C%E9%9C%80%E8%A6%81%E4%B8%8A%E4%BC%A0%E5%9B%BE%E7%89%87%E6%97%B6%EF%BC%8C%E9%A6%96%E5%85%88%E5%AE%9A%E4%BD%8D%E5%88%B0%E3%80%90%E4%B8%8A%E4%BC%A0%E3%80%91%E5%AD%97%E6%A0%B7%E6%96%87%E6%9C%AC%EF%BC%8C%E7%82%B9%E5%87%BB%E6%AD%A4%E6%8C%89%E9%92%AE%203%20%E6%89%A7%E8%A1%8C%E7%BC%96%E8%BE%91%E5%90%8E%E7%9A%84%E5%8F%AF%E6%89%A7%E8%A1%8C%E6%96%87%E4%BB%B6%EF%BC%8C%E5%AE%9E%E7%8E%B0%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0

验证码处理

  • 测试环境去除验证码
  • 找开发添加一个万能验证码绕过校验
  • 添加cookie绕过:
//1.代码中添加cookie
Cookie cookie = new Cookie("cookie名称","cookie值");
driver.manage().addCookie(cookie);
//2.手动添加,在浏览器中登录账号,勾选自动登录,下次再次登录就可以不需要验证码
  • 图像识别
  • 参考:https://zhuanlan.zhihu.com/p/358553292

- JavaScript操作网页元素

document.getElementById(id);
document.getElementsByClassName(className);
//点击
document.getElementById(XX).click();
//修改属性
document.getElementById(XX).setAttribute('属性名','属性值');
//滚动到页面最底部(通用的)
window.scrollTo(0, document.body.scrollHeight);
//滚动到指定元素上去
XXX.scrollIntoViewIfNeeded(true);  //XXX为定位到的元素

selenium操作javascript

WebElement kw = chromeDriver.findElement(By.id("kw"));
JavascriptExecutor chromeDriver1 = chromeDriver;
//arguments[0]… + selenium元素定位实现输入值
chromeDriver1.executeScript("arguments[0].value=\"111441\"\n",kw);
//js中实现输入值
chromeDriver1.executeScript("document.getElementById(\"kw\").value=\"111441\"\n");
//

其他方法:https://zhuanlan.zhihu.com/p/403194552

数据驱动

测试中经常会使用相同的测试脚本使用不同的测试数据来执行,测试数据和测试行为完全分离, 这样的测试脚本设计模式称为数据驱动

    @Test(dataProvider="userPra")
    public void userLogin(String userName, String password, String msg) throws InterruptedException {
        System.setProperty("webdriver.chrome.driver", "src/test/resources/chromedriver-win32/chromedriver.exe");
        ChromeDriver chromeDriver = new ChromeDriver();
        chromeDriver.get("https://www.baidu.com/");
        chromeDriver.findElement(By.id("s-top-loginbtn")).click();
        WebDriverWait webDriverWait = new WebDriverWait(chromeDriver,8);
        webDriverWait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//input[@placeholder=\"手机号/用户名/邮箱\"]"))).sendKeys(userName);
        webDriverWait.until(ExpectedConditions.presenceOfElementLocated(By.id("TANGRAM__PSP_11__password"))).sendKeys(password);
        webDriverWait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//p[@id=\"TANGRAM__PSP_11__submitWrapper\"]//label"))).click();
        webDriverWait.until(ExpectedConditions.presenceOfElementLocated(By.id("TANGRAM__PSP_11__submit"))).click();
        String text = chromeDriver.findElement(By.id("TANGRAM__PSP_11__error")).getText();
        Assert.assertEquals(msg, text);
    }

    @DataProvider
    public Object[][] userPra() {
        Object[][] datas = {
                {" ","dededw","请您输入手机号/用户名/邮箱"},
                {"rferfer"," ", "请您输入密码"},
                {" ","","请您输入手机号/用户名/邮箱"},
                {"feewf","fewfewgt","账号或密码错误,请重新输入或者"},
        };
        return datas;
    }

测试日志

//引入log4j依赖
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
//配置文件
#根logger主要定义log4j支持的日志级别及输出目的地
log4j.rootLogger = INFO,console,file
​
###输出信息到控制台配置###
#表示输出到控制台
log4j.appender.console = org.apache.log4j.ConsoleAppender
#将System.out作为输出
log4j.appender.console.Target = System.out
#使用灵活的布局展示日志信息
log4j.appender.console.layout = org.apache.log4j.PatternLayout
#日志详细输出信息样式
log4j.appender.console.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
​
###输出信息到文件中配置###
#每天产生一个日志文件
log4j.appender.file = org.apache.log4j.DailyRollingFileAppender
#输出文件目的地
log4j.appender.file.File = log/test.log
#新的日志信息是否追加到旧的日志文件末尾
log4j.appender.file.Append = false
#使用灵活的布局展示日志信息
log4j.appender.file.layout = org.apache.log4j.PatternLayout
#日志详细输出信息样式
log4j.appender.file.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
//需要日志的类下加
private static Logger logger = Logger.getLogger(LogTest.class);
public static void main(String[] args) {
    logger.debug("debug级别的日志");
    logger.info("info级别的日志");
    logger.warn("warn级别的日志");
    logger.error("error级别的日志");
}

allure

官方地址:https://allurereport.org/docs/

//引入依赖
<dependency>
    <groupId>io.qameta.allure</groupId>
    <artifactId>allure-testng</artifactId>
    <version>2.12.1</version>
    <scope>test</scope>
</dependency>

//设置编码格式
<properties>
    <aspectj.version>1.8.10</aspectj.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>  

//引入插件
<build>
    <plugins>
        <plugin>
            <!-- maven-surefire-plugin 配合testng执行测试用例的maven插件 -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.22.1</version>
            <configuration>
                <!-- 测试失败后,是否忽略并继续测试 -->
                <testFailureIgnore>true</testFailureIgnore>
                <suiteXmlFiles>
                    <!-- testng配置文件名称 -->
                    <suiteXmlFile>testng.xml</suiteXmlFile>
                </suiteXmlFiles>
                <!--设置参数命令行 -->
                <argLine>
                    <!-- UTF-8编码 -->
                    -Dfile.encoding=UTF-8
                    <!-- 配置拦截器 -->
                    -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
                </argLine>
                <systemProperties>
                    <property>
                        <!-- 配置 allure 结果存储路径 -->
                        <name>allure.results.directory</name>
                        <value>${project.build.directory}/allure-results</value>
                    </property>
                </systemProperties>
            </configuration>
            <dependencies>
                <!-- aspectjweaver maven坐标 -->
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjweaver</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
            </dependencies>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>8</source>
                <target>8</target>
            </configuration>
        </plugin>
    </plugins>
</build>

将项目打包在这里插入图片描述
下载allure包并配置环境遍历,然后执行 allure serve 就进入到了allure报告界面
在这里插入图片描述
参考:https://blog.csdn.net/qq_36396763/article/details/128816918?ops_request_misc=&request_id=&biz_id=102&utm_term=maven%E5%A6%82%E4%BD%95%E8%BF%9B%E5%85%A5allureweb%E7%95%8C%E9%9D%A2&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-3-128816918.nonecase&spm=1018.2226.3001.4187

失败用例截图截图

//将截图保存到本地
public void screenshot(RemoteWebDriver chromeDriver) {
        Date data = new Date();
        String format = new SimpleDateFormat("YYYY-MM-dd-HH-mm-ss").format(data);
        System.out.println("format:---"+format);
        File screenshotAs = ((TakesScreenshot) chromeDriver).getScreenshotAs(OutputType.FILE);
        File file = null;
        try {
            file = new File( new File("").getCanonicalPath()+"\\picture\\"+ format +".png");
            System.out.println(file);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        try {
            System.out.println("file:-----"+file);
            FileUtils.copyFile(screenshotAs,file);
        } catch (Exception e) {
            e.printStackTrace();}}

//使用监听器进行截图
public class IHookableDemo implements IHookable {
    @Override
    public void run(IHookCallBack iHookCallBack, ITestResult iTestResult) {
        iHookCallBack.runTestMethod(iTestResult);
        if (iTestResult.getThrowable() != null){
            System.out.println("222222");
            allureText instance = (allureText) iTestResult.getInstance();
            new allureText().screenshot(instance.chromeDriver);
        }
    }
}
//将截图上传至allure
@Attachment(value="screenshot:",type="image/jpg")
public byte[] screen(RemoteWebDriver chromeDriver){
   return ((TakesScreenshot)chromeDriver).getScreenshotAs(OutputType.BYTES);
  • 30
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值