欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

WEB自动化测试总结篇

时间:2023-06-01
一、初识WEB-selenium自动化测试

针对bing网站的搜索功能进行自动化测试

# 从谷歌公司的一个项目selenium导入webdriver这段代码来驱动浏览器chrome = webdriver.Chrome()# 2、打开bing网站chrome.get('http://cn.bing.com/')# 3、输入关键词chrome.find_element_by_id('sb_form_q').send_keys('51tesing')# 4、点击搜索按钮chrome.find_element_by_id('search_icon').click()

如今,大多数软件应用都是跑在浏览器中网站应用。不同公司和组织之间的测试效率迥异。在这个富交互和响应示处理随处可见的时代,很多组织都使用敏捷的方式来开发,因此测试自动化也称为软件项目的必备部分。测试自动化意味着使用软件工具来反复运行项目中的测试,并为回归测试提供反馈。

测试自动化有很多优点,大多数都与测试的可重复性和高执行率相关。市面上有一些商业或开源的工具来辅助测试自动化开发。Selenium应用是最广泛使用的开源方案。

二、针对海盗商城的登录功能进行自动化测试

import timefrom selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support.select import Select​# 1、登录chrome = webdriver.Chrome()chrome.implicitly_wait(10)  # 由于页面稳定性较差,所以添加了一个隐式等待chrome.maximize_window()  # 窗口最大化chrome.get('http://129.211.129.101:9007/index.php?m=user&c=public&a=login')# chrome.find_element_by_id('username').send_keys('XieChuang') 该命令的输入方式已经过期chrome.find_element(By.ID, 'username').send_keys('XieChuang')chrome.find_element(By.ID, 'password').send_keys('123456')# chrome.find_element_by_class_name('login_btn fl').click() # 登录的类名是复合类名,不能同时使用,fl只是一个左对齐的作用chrome.find_element(By.CLASS_NAME, 'login_btn').click()# 2、点击'进入商城购物'# 登录成功后不是立马进行页面的,所以此处添加一个时间等待time.sleep(3)# 第三种元素定位方式,linktextchrome.find_element(By.link_TEXT, '进入商城购物').click()# 3、搜索'iphone'chrome.find_element(By.NAME, 'keyword').send_keys('小米6')chrome.find_element(By.CLASS_NAME, 'btn1').click()# 4、点击商品图片chrome.find_element(By.XPATH, '/html/body/div[3]/div[2]/div[3]/div[2]/div[1]/a/img').click()# 5、窗口切换# 1、找到新窗口的名字new_window = chrome.window_handles[-1]# 2、切换到新窗口chrome.switch_to.window(new_window)# 6、把选择的商品加入购物车chrome.find_element(By.ID, 'joinCarButton').click()  # 此时由于跳转了新窗口,所以无法进行操作# 7、去购物车结算chrome.find_element(By.CLASS_NAME, 'other_join').click()# 8、点击结算 css selector 定位方式:在两个class之前需要加.chrome.find_element(By.CSS_SELECTOR, '.shopCar_btn_03.fl').click()# 9、添加新地址chrome.find_element(By.CLASS_NAME, 'add-address').click()# 10、填写收货人信息chrome.find_element(By.NAME, 'address[address_name]').send_keys('XC')chrome.find_element(By.NAME, 'address[mobile]').send_keys('15910100202')# 11、选择地区的下拉框sheng=chrome.find_element(By.ID,'add-new-area-select')# 将省这个下拉框进行实例化Select(sheng).select_by_visible_text('北京市')# 将实例化的下拉框进行类型强制转换成Select型,再使用下拉框的属性进行选择# 12、选择收货地区--市 由于下拉框中的ID是动态变化的,且class name又是同名的,所以使用find_elements来找到相同class name,再使用标签名来组合shi=chrome.find_elements(By.CLASS_NAME,'add-new-area-select')[1]Select(shi).select_by_visible_text('北京市')qu=chrome.find_elements(By.TAG_NAME,'select')[2] # 使用标签名来定位Select(qu).select_by_visible_text('海淀区')chrome.find_element(By.NAME, 'address[address]').send_keys('迈行大厦')chrome.find_element(By.NAME, 'address[zipcode]').send_keys('100000')chrome.find_element(By.CLASS_NAME,'aui_state_highlight').click()

1、隐式等待

driver.implicitly_wait(10)

和time.sleep(10)的区别

隐式等待是一种智能等待,可以自动判断需要等待时间。括号中的时间代表最大等待时间

隐式等待只需要在声明driver之后,书写一次即可影响后面的所有代码

time.sleep()则需要在每次等待之前进行书写

2、窗口最大化

chrome.maximize_window()

3、窗口切换

找出新窗口的名字

new_window = driver.window_handles[-1]

切换到新窗口

driver.switch_to.window(new_window)

4、下拉框选择

定位下拉框

element=driver.find_element(By....)

把找到的页面元素,转换为下拉框的类型Select

select = Select(element)

调用Select类中的select_by_*方法

.select_by_value(选项的value属性的值)

.select_by_index(第几个选项)

.select_by_visible_text(选项的文本值)

5、find_element_by_*的形式提示代码已过期

现对原有的定位方式进行修改为find_element(By.*)

注意:使用By之前需要导包from selenium.webdriver.common.by import By

6、find_elements和find_element的区别

find_elements可以找到相同标签名的全部信息,再通过序号的形式找到对应的值

find_element只能默认找到第一个标签名的信息

driver.find_elements(...)[0]==diver.find_element(...)

三、针对海盗商城的修改个人信息功能进行自动化测试

# 1、登录import timefrom selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support import expected_conditionsfrom selenium.webdriver.support.wait import WebDriverWait​chrome = webdriver.Chrome()chrome.implicitly_wait(5)chrome.maximize_window()chrome.get("http://129.211.129.101:9007/index.php?m=user&c=public&a=login")chrome.find_element(By.ID, 'username').send_keys('XieChuang')chrome.find_element(By.ID, 'password').send_keys('123456')# submit方法:类似于click(),只能用于form表单中# 当无法定位到按钮时,可以使用同一表单中的任意元素进行submit提交chrome.find_element(By.ID, 'password').submit()# 使用submit代替了定位登录按钮进行提交# 2、修改个人信息# 2.1 点击"账户设置"chrome.find_element(By.link_TEXT, '账号设置').click()# 2.2 点击"个人资料" 当link_text中的文字信息被其他数据阻挡时,可以使用partial_link_text使用部分的文字信息进行定位chrome.find_element(By.PARTIAL_link_TEXT, '人资').click()# 2.3 修改"真实姓名"chrome.find_element(By.ID, 'true_name').clear()chrome.find_element(By.ID, 'true_name').send_keys('小谢')# 2.4 选择"性别"# 通过CSS_SELECtOR的方式,可以采用任意的属性来定位元素。只需要在属性的两边加一对中括号即可chrome.find_element(By.CSS_SELECTOR, '[value="1"]').click()# 2.5 输入"出生年月"# 日历控件# 传统的方法是一次一次的点击,选择年月日# 新方法:1、删除readonly属性 2、直接向日历控件中输入日期# 问题:selenium无法实现删除一个元素的属性,但是JavaScrip可以实现# 2.5.1编写Javascript命令脚本script = 'document.getElementById("date").removeAttribute("readonly")'# 2.5.2浏览器执行这段Javascript命令,进行属性的删除chrome.execute_script(script)# 2.5.3 清除默认值——由于日历控件中有默认值,直接输入日期无法完成覆盖,所以进行删除操作chrome.find_element(By.ID, 'date').clear()# 2.5.4 直接在输入框中输入生日chrome.find_element(By.ID, 'date').send_keys('1980-02-02')# 2.6 输入"QQ"chrome.find_element(By.ID, 'qq').clear()chrome.find_element(By.ID, 'qq').send_keys('123456789')# 2.7 点击"确定"chrome.find_element(By.CSS_SELECTOR, '[value="确认"]').click()​# 3、弹出框的处理# 弹出框alert,不是HTML的页面元素,而是Javascript的控件# 由于不能右键检查,所以不能用传统的方法操作# selenium提供了三个常用处理alert的方法#     chrome.switch_to.alert.accept()   ——点击确定按钮#     chrome.switch_to.alert.dismiss()   ——点击取消按钮#     chrome.switch_to.alert.text       ——获取弹出框提示的文本信息# time.sleep(3) # 处理弹出框时,隐式等待不起作用# 隐式等待判断的是页面的加载,而弹出框出来后,页面没有刷新过,所以隐式等待在这里不起作用# 由于time.sleep()的等待时间过长,这里引用第三种等待方式WebDriverWait(chrome, 30, 0.5).until(expected_conditions.alert_is_present())# WebDriverWait需要传入三个属性,diver ,timeout(最大等待时间),poll_frequency(多少时间检查一次)# expected_conditions 条件检查,需要导包# alert_is_present 有alert弹出update_status = chrome.switch_to.alert.textprint(update_status)chrome.switch_to.alert.accept()

1、当对submit按钮无法定位时

可以通过submit方法提交表单中的任何一个元素。在form表单中,所有数据都是存在一个表单中的,对其中的一个元素进行提交都可造成所有数据一起提交的效果。

chrome.find_element(By.ID, 'password').submit()

2、css_selector定位方式

浏览器中copy。在元素上鼠标右键检查元素,选择copy再选择copy selector

手工书写selector

标签名可以直接写在css selector中使用

使用任意元素的属性来进行定位,只需要在属性的两边加一对中括号

class属性前面加一个小数点.

ID属性前面加一个井号#

[]用来表示所有属性

属性间>(大于号),表示大于号前面的元素是后面元素的父元素

属性间 (空格),表示前面的元素是后面元素的祖先元素

例如:

chrome.find_element(By.CSS_SELECTOR, '[value="确认"]').click()

chrome.find_element(By.CSS_SELECTOR,'.uploadBtn.state-finish.state-ready').click()

chrome.find_element(By.CSS_SELECTOR,'#filePicker label').click()

3、如何操作日历控件

传统的方法就是一次一次的点击,选择年月日。但是很容易出现错误

 

在这个日历控件中可以看到,在其属性中有一个readonly属性,这就造成了这个日历控件输入框具有只读的特性。

我们可以通过删除readonly属性,再直接输入日期的方式完成日期输入的操作

问题:

Selenium不具有删除一个元素属性的功能

Javascript具有这个功能

# 编写一段Javascript命令,并实例化script = 'document.getElementById("date").removeAttribute("readonly")'# 通过浏览器执行这段Javascript命令,完成删除readonly属性的操作chrome.execute_script(script)

问题:

日历控件中的readonly属性删除了,日期也输入了,但是日历控件存在默认值怎么办呢?

借助Selenium的clear动作来删除默认值

chrome.find_element(By.ID, 'date').clear()

4、弹出框的处理

页面的弹出框alert,是Javascript的控件,而非是HTML的页面元素。

Selenium提供了三种常用处理alert的方法:

driver.switch_to.alert.accept()——点击确定

driver.switch_to.alert.dismiss()——点击取消

driver.switch_to.alert.text——获取弹出框提示的文本信息

注意:

在处理弹出框时,隐式等待时不起作用的

隐式等待判断的是页面加载,当alert弹出框出现后,页面是没有刷新的,所以隐式等待无效

5、显示等待

WebDriverWait(driver,timeout=程序需要等待的最长时间,poll_frequency=每隔几秒执行until中的方法).until(method='执行什么方法,具体来做什么事情')

例如:

WebDriverWait(chrome, 30, 0.5).until(expected_conditions.alert_is_present())

其中expected_conditions表示条件检查

alert_is_present()表示有alert弹框出现

四、针对海盗商城的后台管理系统

# 1、登录海盗商城的后台管理系统import timefrom selenium import webdriverfrom selenium.webdriver import ActionChainsfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support import expected_conditionsfrom selenium.webdriver.support.select import Selectfrom selenium.webdriver.support.wait import WebDriverWait# 1.1 打开后台登录界面chrome = webdriver.Chrome()chrome.implicitly_wait(5)chrome.maximize_window()chrome.get('http://localhost/pirate/admin.php')# 1.2 输入用户名、密码、验证码chrome.find_element(By.NAME, 'username').send_keys('admin')chrome.find_element(By.NAME, 'userpass').send_keys('password')chrome.find_element(By.NAME,'userverify').send_keys('1234')# 1.3 点击登录按钮chrome.find_element(By.CLASS_NAME,'Btn').click()# 2、添加商品# 2.1 在后台管理中心,点击商品管理chrome.find_element(By.link_TEXT,'商品管理').click()# 2.2 点击添加商品chrome.find_element(By.link_TEXT,'添加商品').click()# 2.3 输入商品名称# 此处存在HTML嵌套,需要进行子页面切换chrome.switch_to.frame('mainframe')chrome.find_element(By.NAME,'name').send_keys('iPone xs max')# 2.4 选择商品分类chrome.find_element(By.ID,'1').click()chrome.find_element(By.ID,'2').click()chrome.find_element(By.ID,'3').click()# chrome.find_element(By.ID,'4')# 元素的高级操作 ActionChains中封装了所有可以对页面元素进行的高级操作# Action——动作# Chains——链表# chrome——当前浏览器# 合起来就是,把当前浏览器转换为一个可以执行各种操作的行为链# perform()作为结束标志ActionChains(chrome).double_click(chrome.find_element(By.ID,'4')).perform()# 2.5 选择商品品牌brand = chrome.find_element(By.NAME,'brand_id')Select(brand).select_by_value('1')# 2.6 添加商品图片chrome.find_element(By.link_TEXT,'商品图册').click()'''在前端点击的按钮不是真正复制上传文件的控件,真正负责上传文件的控件是我们要做的是,找到这个控件。然后直接对这个控件进行send_keys,发送图片或文件的路径即可'''chrome.find_element(By.NAME,'file').send_keys('//Mac/Home/Desktop/1643087781227.jpg')# 注意:图片路径处的''要进行转义,也就是写为'/'chrome.find_element(By.CSS_SELECTOR,'.uploadBtn.state-finish.state-ready').click()# 处理“上传成功”弹出框WebDriverWait(chrome, 30 ,0.5).until(expected_conditions.alert_is_present())chrome.switch_to.alert.accept()# 2.6 点击提交按钮chrome.find_element(By.CLASS_NAME,'button_search').click()

1、验证码的处理

常见的验证码处理方式:

借助第三方图片识别文字的工具

缺点:准确率较低

借助第三方网站识别验证码

优点:准确率很高,几乎可以达到100%

缺点:收费

设置万能验证码

当我们在测试环境中时,求助开发人员帮忙设置一个万能验证码,以便使用

问题:如何查看系统是否存在万能验证码呢?以海盗商城为例

1、明确开发人员为海盗商城写的源代码位置

2、为了看懂开发人员的代码,必须了解MVC设计模型

M——模型层,主要用于和数据库打交道

V——视图层,主要和前端打交道,用于收集和显示用户数据

C——控制器,主要用于处理业务逻辑

判断验证码是否正确就属于业务逻辑层

3、也可以通过网址来分析功能的源代码位置

http://172.31.14.251/pirate/index.php?m=admin&c=public&a=login

网址中主要分为5个部分:

http:协议

172.31.14.251:域名或者IP地址

/index.php:路径

m=admin&c=public&a=login:参数

m=admin——m代表模块,一个模块就是一个文件夹

c=public——c代表控制器(controller),一个控制器就是一个类,一个文件

a=login——a代表动作(action),一个action就是代码中的一个方法

4、在测试环境中屏蔽掉验证码

5、绑定IP地址

有些公司,在测试环境中,如果绑定IP地址是可以不显示验证码的

6、读取cookie和缓存

7、在输入验证码前,添加一个固定的时间等待,手动输入验证码

2、frame标签的处理

在输入商品名称时,明明元素属性存在,但是定位失败,这是为什么呢?

chrome.find_element(By.XPATH,'/html/body/div[2]/div[2]/dl/form/dd[1]/ul/li[1]/input').send_keys('ipone xs max')

把鼠标放在根节点标签上,检查页面高亮部分是否覆盖全屏

如果覆盖全屏,说明页面中不存在frame标签

如果不能覆盖全屏,说明页面中存在frame标签

检查后发现,页面中存在一个frame标签,且商品名称等信息都在该标签中

使用driver.switch_to.frame('frame的name属性名')来切换到frame标签中,再进行定位

3、元素的高级操作

如何实现鼠标左键的双击呢?

Selenium中提供了一个ActionChains的方法,可以对页面元素进行高级操作

context_click():鼠标右击

double_click():鼠标左键双击

drag_and_drop:拖动

move_to_element:鼠标悬停在一个元素上

click_and_hold():按下鼠标左键在一个元素上,一般配合release()释放使用

key_down():在一个元素上按住一个键不松,只能与修改键(控制,Ctrl、Alt和Shift)一起使用

key_up():松开按键,释放修改键

move_by_offset():鼠标移动

perform():执行所有ActionChains中存储的行为,在命令最后添加

4、如何上传图片

一般在前端点击的按钮都不是真正的上传文件控件,而是为了符合整体页面布局的

在这个

chrome.find_element(By.NAME,'file').send_keys('//Mac/Home/Desktop/1643087781227.jpg')

5、元素定位的8种方式

ID :使用ID进行定位

NAME:使用name进行定位

使用id和name定位的优缺点:

优点:易于定位元素,大多数时其属性值时唯一的

缺点:很多元素不具备id和name属性

CLASS_NAME :使用classname进行定位

TAG_NAME :使用tagname(标签名)进行定位

使用class_name和tag_name定位的优缺点:

优点:几乎所有的元素都具备class_name和tag_name的属性

缺点:class和tag的值往往不是唯一的,很难精准找到一个元素

link_TEXT :使用超链接文本定位

PARTIAL_link_TEXT :使用部分超链接文本定位

使用link_text和partial_link_text特点:只能用于标签

XPATH :使用xpath定位

CSS_SELECTOR :使用css_selector定位

使用xpath和css_selector几乎可以用于定位所有页面元素

都有工具可以直接生成,但是工具生成的不一定100%管用,有些情况仍然需要手工书写

6、几种常用定位元素后的操作方式

click() :鼠标左键单击

send_keys:模拟键盘输入

submi():提交表单

clear():清除

五、自动化测试框架unittest2 1、unittest2介绍

unittest2是unittest的升级版,都是Python自带测试库,是单元测试框架,提供了丰富的断言方法

unittest2的四大特点:

TestCase:测试案例,所有的用例都是直接继承于Unittest2.TestCase类

TestFixture:SetUp和TearDown,作为前置条件和后置条件

TestSuite:测试套件,一组测试案例,运行套件,则运行套件中所有的测试案例

TestRunner:测试运行器,与TestSuite结合一起使用

断言:在Unittest2中封装了很多成熟断言,可以直接被调用

2、unittest2的使用

Unittest2环境搭建

import unittest2

Unittest2语法规则

Unittest2中测试用例定义都是以test_开头

注意:用例排序与写的顺序无关,排序遵循A-Z,a-z,0-9

class前置条件

在类中所有方法前,需要进行的前置条件@classmethoddef setUpClass(cls):

class后置条件

在类中所有方法后,需要进行的后置条件@classmethoddef tearDown(cls):

前置条件

在每条测试用例方法开始前,需要进行的前置条件def setUp(self):

后置条件

在每条测试用例方法结束后,需要进行的后置条件def tearDown(self):

3、baseTestCase的封装

因为所有的测试用例都需要进行浏览器的相关操作

import timeimport unittest2from selenium import webdriver​​class baseTestCase(unittest2.TestCase):   @classmethod   def setUpClass(cls):       cls.driver = webdriver.Chrome()       cls.driver.maximize_window()       cls.driver.implicitly_wait(5)​   @classmethod   def tearDownClass(cls):       # time.sleep(10)       cls.driver.quit()

4、数据驱动测试

基础步骤:

创建一个Excel表格进行测试数据准备

usernamepassword/confirm/i_passwordmobile_numemailchangcheng212112345612345613456788765changcheng2121@163.comchangcheng212212345612345613456788766changcheng2121@164.comchangcheng212312345612345613456788767changcheng2121@165.comchangcheng212412345612345613456788768changcheng2121@166.com

编写代码读取csv表中的内容

csvFileManager.py# 进行csv文件的读取,以进行数据驱动# 1、导入代码库import csv​# 2、指定csv文件所在的路径path = r'/Users/chuangxie/Desktop/学习课件/SeleniumTest/test_data/login_test_cases.csv''''当路径中存在反斜线时,需要在字符串前面加一个字母r这时系统会将反斜线默认为字符串的一部分'''# 3、打开csv文件file = open(path)# 4、进行csv中数据读取table = csv.reader(file)# 5、打印csv文件中的内容for i in table:   print(i)

上方代码中的弊端:

文件始终处于打开状态,会验证影响运行效率

csvFileManager2.pyimport csvimport os.path​​def reader(filename):   list = []   # path = '../test_data/' + filename   由于文件路径可能会变化,故舍弃   base_path = os.path.dirname(__file__) # 表示当前文件所在路径   path = base_path.replace('func','test_data/'+filename) # 将func路径替换成test_data文件夹   # file = open(path)   with open(path) as file:       table = csv.reader(file)       i = 0   # 用于剔除首行标题       for row in table:           if i == 0:               pass           else:               list.append(row)           i = i + 1   return list

把读取到的内容分别传入测试用例中,循环执行

register2Test.pyfrom selenium.webdriver.common.by import Byfrom func.csvFilemanager2 import readerfrom test_case.baseTestCase import baseTestCase​​class register2Test(baseTestCase):   def test_register(self):       table = reader('register_test_cases.csv')       for row in table:           self.driver.get('http://129.211.129.101:9007/index.php?m=user&c=public&a=reg')           self.driver.find_element(By.NAME, 'username').send_keys(row[0])           self.driver.find_element(By.NAME, 'password').send_keys(row[1])           self.driver.find_element(By.NAME, 'userpassword2').send_keys(row[2])           self.driver.find_element(By.NAME, "mobile_phone").send_keys(row[3])           self.driver.find_element(By.NAME, 'email').send_keys(row[4])

上方代码中的弊端:

当使用for循环时,如果有一组数据运行失败了,后面的代码都不会被执行

改进方法:使用ddt代码库

csvFileManager3.pyimport ddtfrom selenium.webdriver.common.by import Byfrom func.csvFilemanager2 import readerfrom test_case.baseTestCase import baseTestCase​​@ddt.ddtclass register3Test(baseTestCase):​   table = reader('register_test_cases.csv')​   @ddt.data(*table)   def test_register(self, row):      self.driver.get('http://129.211.129.101:9007/index.php?m=user&c=public&a=reg')      self.driver.find_element(By.NAME,'username').send_keys(row[0])      self.driver.find_element(By.NAME, 'password').send_keys(row[1])      self.driver.find_element(By.NAME, 'userpassword2').send_keys(row[2])      self.driver.find_element(By.NAME, "mobile_phone").send_keys(row[3])      self.driver.find_element(By.NAME, 'email').send_keys(row[4])

问题:类上面的修饰器的作用是什么?

@ddt.ddt class register3Test(baseTestCase):

用来表示该类是一个数据驱动测试类

问题:方法上面的修饰器的作用是什么?

@ddt.data(*table) def test_register(self, row):

用来指定测试数据源,要求数据源格式为多个参数

*table 是将table 列表中的数据进行了拆分,每一行即为一个参数

5、生成测试报告(HTMLTestRunner)

HTMLTestRunner提供了一个可以生成美观的测试报告的模板

使用方法:

下载并复制HTMLTestRunner.py文件到我们的项目中

使用HTMLTestRunner这个类来执行测试用例

run_all_cases.pyimport unittest2from lib.HTMLTestRunner import HTMLTestRunner​if __name__ == '__main__':   # 1、找到所有需要执行的测试用例   suite = unittest2.defaultTestLoader.discover('./test_case', '*Test.py')   # 2、执行找到的测试用例集   # unittest2.TextTestRunner().run(suite)​   # 3、生成测试报告   # 指定测试报告生成位置   path = 'report/TestReport.html'   file = open(path, 'wb')  # w表示写,b表示二进制,   HTMLTestRunner(stream=file, verbosity=1, title='自动化测试报告', description='测试环境:Chrome', tester='谢闯').run(suite)  # 实例化HTMLTestRunner

在实例化HTMLTestRunner时需要传入五个参数

HTMLTestRunner(stream=二进制文件, verbosity=1(日志的详细程度,默认即可),title=报告的标题,description=报告的正文, tester = 测试人员的名字)

文件file = open(path, 'wb')的保存:

默认是以只读的方式打开文件

w表示以写的方式打开文件

b表示以二进制的方式进行写入

6、断言

作用:自动判断测试用例执行的结果是否成功

一般情况使用的检查点包括:

页面级别的检查

网页的标题

网址的变化

页面元素级别的检查

元素的文本

元素的某个属性

以海盗商城的登录为例# 对比网页的titleself.assertEqual('我的会员中心 - 道e坊商城 - Powered by Haidao', self.driver.title)# 对比网址的变化self.assertEqual('http://129.211.129.101:9007/index.php?m=user&c=index&a=index', self.driver.current_url)# 对比登录成功后,是否有登录用户名显示# a:nth-child(1)——表示为第一个子标签,n=1welcome = self.driver.find_element(By.CSS_SELECtOR, '.site-nav-right.fr > a:nth-child(1)').textself.assertEqual('您好 XieChuang', welcome)# 对比页面跳转后的搜索value属性是否相同search = self.driver.find_element(By.CSS_SELECTOR, '.btn1').get_attribute('value')self.assertEqual('搜索', search)

实际运行代码如下:import timeimport ddtfrom selenium.webdriver.common.by import Byfrom TestCases.baseTestCases import baseTestCasesfrom TestCases.csvFileManager2 import reader​​@ddt.ddtclass loginTest(baseTestCases):   table = reader('login_test_cases.csv')​   @ddt.data(*table)   def test_login(self, row):       self.chrome.get('http://129.211.129.101:9007/index.php?m=user&c=public&a=login')       self.chrome.find_element(By.NAME, 'username').send_keys(row[0])       self.chrome.find_element(By.NAME, 'password').send_keys(row[1])       self.chrome.find_element(By.NAME, 'password').submit()       time.sleep(3)       welcome = self.chrome.find_element(By.CSS_SELECtOR, '.site-nav-right.fr>a:nth-child(1)').text       self.assertEqual('您好 '+row[0]+'', welcome)

六、持续集成

目标:

实现定时执行测试用例

测试报告邮件提醒

1、安装环境

安装jdk

配置环境变量JAVA_HOME:安装路径

解压tamcat文件

解压tomacat文件夹,一般存放在D盘根目录中

Jenkins文件处理

将Jenkins.war文件复制到到tomacatwebapps文件夹中

2、启动Jenkins

运行tomacatbin下面的startup.bat文件

当出现jenkins is fully up and running后

在浏览器上输入网址

或者在webapps目录下使用dos命令:java -jar jenkins.war

3、定时执行测试任务

在构建中选择window批处理命令

cd 项目路径

Python 测试用例执行脚本.py

编辑日程表

5个时间单位

分钟

小时

日期

月份

星期

6个符号

空格 :时间单位的间隔,有且只能有4个

*星号:表示有可能的取值

例:0 21 * * * 每天21点分别执行一次

-横线:表示区间

例:0 21 * * 1-5 每周一到周五的21点自动执行一次

,逗号:表示枚举

例: 0 8,12,20 * * * 每天的8点、12点、20点自动执行一次

/斜线:表示间隔

例:*/30 * * * * 每隔30分钟执行一次

H:用于分散负载

例:H/30 * * * * 同样是每隔30分钟执行一次,但不一定是整点和半点执行,可能在任何一个时间点。会自动找服务器的空闲时间执行,更推荐使用

4、设置邮件提醒

安装插件

HTML Publisher

Email Extension Plugin

Email Extension Template Plugin

修改配置信息

系统管理员邮件地址

改成发邮件的邮箱

注意:要求是一个设置过客户端授权码的邮箱(我的授权码TALEENGMSITQLWAQ)

Extended E-mail Notification

SMTP server:smtp.163.com

SMTP Port:465

点击高级:添加jenkins

用户名:邮箱账号

密码:授权码,不能使用邮箱密码

ID:空

描述:空

勾选USE SSL

Default user e-mail suffix(默认邮箱后缀):@163.com

点击高级:

Admin Account Address:填写发件箱

SMTP server:smtp.163.com

SMTP Port:25

Default Content Type:HTML(text/html)

Default Recipients:默认的收件人地址

Default Content:默认的邮件正文

                ${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次构建日志                                           本邮件由系统自动发出,无需回复!
                      各位同事,大家好,以下为${PROJECT_NAME }项目构建信息
            构建结果 - ${BUILD_STATUS}                                                   构建信息                                                                       

                       项目名称 : ${PROJECT_NAME}                       测试报告: 测试报告                       构建编号 : 第${BUILD_NUMBER}次构建                       触发原因: ${CAUSE}                       构建状态: ${BUILD_STATUS}                       构建日志: ${BUILD_URL}console                       构建 Url : ${BUILD_URL}                       工作目录 : ${PROJECT_URL}ws                       项目 Url : ${PROJECT_URL}                       ​失败用例$FAILED_TESTS
​最近提交(#$SVN_REVISION)

${CHANGES_SINCE_LAST_SUCCESS, reverse=true, format="%c", changesFormat="%d [%a] %m"}详细提交: ${PROJECT_URL}changes
​                                     

勾选Enable Debug Mode:如果邮件发送失败,日志中会包含详细的错误信息

点击Default Triggers

勾选Always:不论测试执行是否失败,总是发送邮件

保存,设置完成

项目设置

打开之前创建的任务,进入配置

构建后操作

选择Editable Email Notification

Project From:必须为空,否则邮件发送失败

5、版本控制

SVN版本控制和GIT版本控制

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。