自动化测试selenium

目录

定义

分类

原理

webdriver API

元素的定位(以定义百度输入框,并且向输入框输入“selenium”文本内容为例)

 id定位

name 定位

tag name (标签名)定位和class name 定位

CSS 定位

XPath 定位

link text定位

Partial link text 定位

操作测试对象

鼠标点击与键盘输入

submit 提交表单:

text 用于获取元素的文本信息

添加等待

sleep休眠(指固定休眠)

隐式等待

浏览器的操作

浏览器最大化

设置浏览器宽、高

操作浏览器的前进、后退

控制浏览器滚动条

键盘事件

键盘按键用法

键盘组合键用法

鼠标事件

定位一组元素

框架/窗口定位

下拉框处理

alert、confirm、prompt 的处理

DIV对话框的处理

上传文件操作

单元测试工具Junit

通过 order 注解来排序 

 参数化

单参数

多参数

动态参数方法

断言 Assertions


定义:

自动化测试指软件测试的自动化,在预设状态下运行应用程序或者系统,预设条件包括正常和异常,最 后评估运行结果。将人为驱动的测试行为转化为机器执行的过程

  • 为什么选择selenium作为web自动化工具
    selenium是开源的
    selenium支持多种语言
    selenium支持各种浏览器
    selenium有丰富的API
  • 什么是自动化以及为什么要做自动化
    自动化是测试人员为了提高测试效率或者保证测试质量,让代码辅助测试人员执行测试的这个过程

分类:

单元测试,接口自动化,UI自动化

selenium:

Selenium是web应用中基于UI的自动化测试框架,支持多平台、多浏览器、多语言。 

原理:

webdriver API:

元素的定位(以定义百度输入框,并且向输入框输入“selenium”文本内容为例)

 id定位:

browser.find_element_by_id("kw").send_keys("selenium")

name 定位:

如果这个元素有name,并且元素的name命名在整个页面是唯一的,那么我们可以用name来定位这个 元素。

browser.find_element_by_name("wd").send_keys("selenium")

tag name (标签名)定位和class name 定位:

input 就是一个标签的名字,可以通过find_element_by_tag_name("input") 函数来定位。 class="s_ipt",通过find_element_by_class_name("s_ipt")函数定位百度输入框。

browser.find_element_by_tag_name("input").send_keys("selenium") 
//不能成功,因为input太多了不唯一。

CSS 定位:

CSS 使用选择器来为页面元素绑定属性。这些选择器可以被selenium 用作另外的定位策略。

CSS 的比较灵活可以选择控件的任意属性,上面的例子中: find_element_by_css_selector("#kw") 通过find_element_by_css_selector( )函数,选择取百度输入框的id 属性来定义

browser.find_element_by_css_selector("#kw").send_keys("selenium")

XPath 定位:

XPath 扩展了上面id 和name 定位方式,提供了很多种可能性。

browser.find_element_by_xpath("//*[@id='kw']").send_keys("selenium")

link text定位:

有时候不是一个输入框也不是一个按钮,而是一个文字链接,我们可以通过链接内容,也就是 link text 来定位。

#coding=utf-8
//防止乱码,在编辑器里面可以不用加,因为编辑器默认的就是UTF-8模式。
from selenium import webdriver
//导入webdriver工具包,这样就可以使用里面的API
browser = webdriver.Chrome()
browser.get("http://www.baidu.com")
browser.find_element_by_link_text("hao123").click()
browser.quit()
//quit方法不仅关闭窗口,还会彻底的退出webdriver,释放与driver
server之间的连接,与close()不同

Partial link text 定位:

通过部分链接定位

#coding=utf-8
//防止乱码,在编辑器里面可以不用加,因为编辑器默认的就是UTF-8模式。
from selenium import webdriver
//导入webdriver工具包,这样就可以使用里面的API
browser = webdriver.Chrome()
browser.get("http://www.baidu.com")
browser.find_element_by_link_text("hao").click()
browser.quit()
//quit方法不仅关闭窗口,还会彻底的退出webdriver,释放与driver
server之间的连接,与close()不同

操作测试对象

鼠标点击与键盘输入:

send_keys("xx") 用于在一个输入框里输入xx 内容。

click() 用于点击一个按钮。

clear() 用于清除输入框的内容,比如百度输入框里默认有个“请输入关键字”的信息,再比如我们的登陆 框一般默认会有“账号”“密码”这样的默认信息。clear 可以帮助我们清除这些信息。

submit 提交表单: 

driver.find_element_by_id("su").submit()

如果元素在form标签中,按钮“百度一下”元素的类型type=“submit”,所以把“百度一下”的操作从click 换成submit 可以达到相同的效果;如果不在form标签中,则用submit会报错

text 用于获取元素的文本信息

添加等待

sleep休眠(指固定休眠)

time.sleep(3)

隐式等待

隐式地等待并非一个固定的等待时间,当脚本执行到某个元素定位时,如果元素可以定位,则继续执 行;如果元素定位不到,则它以轮询的方式不断的判断元素是否被定位到。直到超出设置的时长

browser.implicitly_wait(30)

浏览器的操作

浏览器最大化

browser.maximize_window()

设置浏览器宽、高

browser.set_window_size(width, high)

操作浏览器的前进、后退

#浏览器的前进
browser.forward()
#浏览器的后退
browser.back()

控制浏览器滚动条

#将浏览器滚动条滑到最顶端
document.documentElement.scrollTop=0
#将浏览器滚动条滑到最底端
document.documentElement.scrollTop=10000

键盘事件

键盘按键用法

send_keys(Keys.TAB) # TAB
send_keys(Keys.ENTER) # 回车
send_keys(Keys.SPACE) #空格键
send_keys(Keys.ESCAPE) #回退键(Esc)

键盘组合键用法

send_keys(Keys.CONTROL,'a') #全选(Ctrl+A)
send_keys(Keys.CONTROL,'c') #复制(Ctrl+C)
send_keys(Keys.CONTROL,'x') #剪贴(Ctrl+X)
send_keys(Keys.CONTROL,'v') #粘贴(Ctrl+V)

鼠标事件

要使用鼠标事件需要导入工具包:

from selenium.webdriver.common.action_chains import ActionChains

ActionChains 类:

  • context_click() 右击
  • double_click() 双击
  • drag_and_drop() 拖动
  • move_to_element() 移动
ActionChains(driver).move_to_element(element).perform()
//ActionChains(driver)
//生成用户的行为。所有的行动都存储在actionchains 对象。通过perform()存储的行为。
//move_to_element(element)
//移动鼠标到一个元素中,menu 上面已经定义了他所指向的哪一个元素
//perform()
//执行所有存储的行为

定位一组元素

应用场景:

  • 批量操作对象,比如将页面上所有的checkbox 都勾上
  • 先获取一组对象,再在这组对象中过滤出需要具体定位的一些对象。比如定位出页面上所有的 checkbox,然后选择最后一个

框架/窗口定位

  •  定位一个框架frame :switch_to.frame(name_or_id_or_frame_element)
  • 定位一个窗口window:switch_to.window(name_or_id_or_frame_element)

下拉框处理

下拉框是我们最常见的一种页面元素,对于一般的元素,我们只需要一次就定位,但下拉框里的内容需 要进行两次定位,先定位到下拉框对下拉框进行操作后,再定位到下拉框内里的选项。

以下为一个下拉框的HTML:

<html>
<body>
<select id="ShippingMethod"
onchange="updateShipping(options[selectedIndex]);" name="ShippingMethod">
<option value="12.51">UPS Next Day Air ==> $12.51</option>
<option value="11.61">UPS Next Day Air Saver ==> $11.61</option>
<option value="10.69">UPS 3 Day Select ==> $10.69</option>
<option value="9.03">UPS 2nd Day Air ==> $9.03</option>
<option value="8.34">UPS Ground ==> $8.34</option>
<option value="9.25">USPS Priority Mail Insured ==> $9.25</option>
<option value="7.45">USPS Priority Mail ==> $7.45</option>
<option value="3.20" selected="">USPS First Class ==> $3.20</option>
</select>
</body>
</html>

先定位到下拉框对下拉框进行操作后,再定位到下拉框内里的选项:

#coding=utf-8
from selenium import webdriver
import os,time
driver= webdriver.Chrome()
file_path = 'file:///' + os.path.abspath('drop_down.html')
driver.get(file_path)
time.sleep(2)
#先定位到下拉框
m=driver.find_element_by_id("ShippingMethod")
#再点击下拉框下的选项
m.find_element_by_xpath("//option[@value='10.69']").click()
time.sleep(3)
driver.quit()

alert、confirm、prompt 的处理

  • text 返回alert/confirm/prompt 中的文字信息
  • accept 点击确认按钮
  • dismiss 点击取消按钮,如果有的话
  • send_keys 输入值,如果alert 没有对话框就不能用了,不然会报错 
//当alert中有对话框,在alert的对话框中输入信息
#点击“请点击”
driver.find_element_by_xpath("html/body/input").click()
#输入内容
driver.switch_to.alert().send_keys('webdriver')
driver.switch_to.alert().accept()
sleep(5)
driver.quit()

DIV对话框的处理

如果页面元素比较多,利用元素的属性无法准确的定位这个元素的时候,我们可以先定位元素所在的 div块,再去定位这个元素。

上传文件操作

#定位上传按钮,添加本地文件
driver.find_element_by_name("file").send_keys('D:\\PycharmProjects\\test\\upload
.txt')

单元测试工具Junit

自动化就是 selenium 脚本来实现的,junit 是 java 的单元测试工具,只不过在实现自动化的时候需要借用一下 junit 库里面提供的一些注解(junit5)

  <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.9.1</version>
            <scope>test</scope>
        </dependency>

@Test(测试方法)、

@BeforeEach(每个测试用例前执行一次)、

@BeforeAll(所有测试用例前执行一次)、( 注解的方法必须为静态方法

@AfterEach(每个测试用例之后执行一次)、

@AfterAll(所有测试用例之后执行一次)( 注解的方法必须为静态方法

通过 order 注解来排序 

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
//按随机运行
//@TestMethodOrder(MethodOrderer.Random.class)(则不用order)
public class JunitTest3 {
    @Order(2)
    @Test
    void test01(){
        System.out.println("tset01");
    }
    @Order(1)
    @Test
    void test02(){
        System.out.println("tset02");
    }
    @Order(3)
    @Test
    void test03(){
        System.out.println("tset03");
    }
}

执行结果:

 参数化

单参数:

@ParameterzedTest + @ValueSource(数据类型方法/加s = {参数1,参数2,参数3,…})

 @ParameterizedTest
    @ValueSource(ints={1,2,3})
    void Test01(int num){
        System.out.println(num);
    }

 执行结果:

多参数:

@parameterizedTest + @CsvSource({“”, “”, '", …}) 每个双引号就是一组测试用例

@ParameterizedTest
    @CsvSource({"张三,22","李四,25","王五,35"})
    void muchParamsTest(String name,int age) {
        System.out.println("name: " + name + ",age: " + age);
    }

执行结果:

 @parameterizedTest + @CsvFileSource({“”, “”, '", …}) 每个双引号就是一组测试用例

  @ParameterizedTest
    @CsvFileSource(resources = "test02.csv")
    void test03(int num,String name){
        System.out.println("学号:"+num+"姓名:"+name);
    }

 

 执行结果:

动态参数方法:

// 通过动态方法来提供数据源
@ParameterizedTest
@MethodSource("methodParams")
void dynamicMethodParamsTest(String name,int age) {
    System.out.println("name: " + name + ",age: " + age);
}
static Stream<Arguments> methodParams() throws InterruptedException {
    // 构造动态参数
    String[] arr = new String[5];
    for (int i = 0; i < arr.length; i++) {
        Thread.sleep(500);
        arr[i] = System.currentTimeMillis() + "";
    }
    return Stream.of(
            Arguments.arguments(arr[0],20),
            Arguments.arguments(arr[1],20),
            Arguments.arguments(arr[2],20),
            Arguments.arguments(arr[3],20),
            Arguments.arguments(arr[4],20)
    );
}

 执行结果:

static Stream<Arguments> methodParams() throws InterruptedException {此处返回的数据类型如果是统一的,就写具体的数据类型;如果不统一,就返回Arguments的流

@MethodSource("methodParams")当不指定数据源方法名时,会自动找和用例方法名(dynamicMethodParamsTest())相同的静态方法

断言 Assertions

断言匹配 assertEquals,断言不匹配 assertNotEquals 

 @ParameterizedTest
    @ValueSource(ints = {1})
    void test01(int num){
        //判断是否为1,不是会报错
        Assertions.assertEquals(1,num);
        //判断是否不为1,是1会报错
        //Assertions.assertNotEquals(1,num);
        //判断字符串是否为空
        //Assertions.assertNull();
    }

 执行结果:

断言结果为真 assertTrue,断言结果为假 assertFalse

断言结构为空 assertNull,断言结果不为空 assertNotNull

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

发呆的百香果子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值