1.11、自动化
自动化
一、java 手机自动化
首先new DesertCapabilities(这是一个类)
setCapability – 设置信息
获取appium的驱动对象 new AppiumDriver – 本机IP地址:端口号/wd/hub,前面的设置值信息
driver.findElementById() – 通过id找位置
click() – 点击 ,clear() – 清空 sendKeys() – 填内容
package com.qf.demo;import java.net.MalformedURLException;
import java.net.URL;import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;import io.appium.java_client.AppiumDriver;public class DemoAppium {public static void main(String[] args) {// TODO Auto-generated method stubDesiredCapabilities desiredCapabilities=new DesiredCapabilities();desiredCapabilities.setCapability("platformName", "Android");desiredCapabilities.setCapability("platformVersion", "21.1.0");desiredCapabilities.setCapability("deviceName", "yeshen");desiredCapabilities.setCapability("appPackage", "com.qf.day63demo2");desiredCapabilities.setCapability("udid", "127.0.0.1:62001");desiredCapabilities.setCapability("noReset", "true");desiredCapabilities.setCapability("appActivity", ".MainActivity");//创建android diver的对象try {AppiumDriver driver = new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"), desiredCapabilities);//找到三国,点击三国WebElement sanguo = driver.findElementById("com.qf.day63demo2:id/sanguo");sanguo.click();Thread.sleep(1000);//睡眠1s//使用dricer找到要操作的元素//根据id找元素 com.qf.day63demo2:id/btn1WebElement ele1 = driver.findElementById("com.qf.day63demo2:id/btn1");ele1.click();//点击这个元素Thread.sleep(1000);WebElement button2 = driver.findElement(By.id("com.qf.day63demo2:id/btn2"));button2.click();Thread.sleep(1000);//找到 输入框 换成太阳WebElement edit1 = driver.findElement(By.id("com.qf.day63demo2:id/edit2"));edit1.clear();edit1.sendKeys("sun");} catch (MalformedURLException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
查找包名和activity
在cmd中输入 adb logcat > 路径 在夜神中打开一个app ,在cmd中关闭logcat ,打开logcat文件 搜索activityManager
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-STFrQWv0-1679826710702)(C:\Users\11700\AppData\Roaming\Typora\typora-user-images\image-20220608153413697.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z1ddEEZx-1679826710704)(C:\Users\11700\AppData\Roaming\Typora\typora-user-images\image-20220608153544520.png)]
第一步:导包将jar包导入到项目的lib文件夹下 --选中然后 add to build path
写配置文件
platformName=Android
platformVersion=21.1.0
deviceName=yeshen
appPackage=com.android.contacts
udid=127.0.0.1:62001
noReset=true
appActivity=.activities.PeopleActivity
将一个配置文件写成一个工具类
package tongxunlu;import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;import io.appium.java_client.AppiumDriver;public class PhoneTools {public static AppiumDriver getDriver(String filename) {AppiumDriver appiumDriver = null;Properties properties = new Properties();try {properties.load(new FileReader(filename));HashMap<String, String> map= new HashMap<>();Set<Entry<Object, Object>> set = properties.entrySet();for (Entry<Object, Object> entry : set) {String key = (String) entry.getKey();String value = (String) entry.getValue();map.put(key, value); }DesiredCapabilities desiredCapabilities = new DesiredCapabilities(map);appiumDriver = new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"), desiredCapabilities);} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return appiumDriver;}public static void clickById(AppiumDriver driver,String id) {driver.findElementById(id).click();}public static void clickByXpath(AppiumDriver driver,String xpath) {driver.findElementByXPath(xpath).click();}public static void inputContentByXpath(AppiumDriver driver,String xpath,String content) {WebElement ele = driver.findElementByXPath(xpath);ele.clear();ele.sendKeys(content);}public static void inputContentById(AppiumDriver driver,String id,String content) {WebElement ele = driver.findElementById(id);ele.clear();ele.sendKeys(content);}public static void inputContentByClass(AppiumDriver driver,String classname,String countent) {WebElement ele = driver.findElementById(classname);ele.clear();ele.sendKeys(countent);}}
封装测试(页面)功能
package tongxunlu;import java.util.List;import org.openqa.selenium.WebElement;import io.appium.java_client.AppiumDriver;public class PhoneActivity {AppiumDriver driver;public PhoneActivity(AppiumDriver driver) {super();this.driver = driver;}//增加联系人 id com.android.contacts:id/floating_action_buttonpublic void addContactor(String uname,String utel) {PhoneTools.clickById(driver, "com.android.contacts:id/floating_action_button"); //classList<WebElement> eles = driver.findElementsByClassName("android.widget.EditText");eles.get(0).sendKeys(uname);eles.get(1).sendKeys(utel);//保存 id com.android.contacts:id/menu_savePhoneTools.clickById(driver, "com.android.contacts:id/menu_save"); }//编辑联系人 public void editContactor(String uname,String utel) {// //android.widget.TextView[@content-desc="uu"]PhoneTools.clickByXpath(driver, "//android.widget.TextView[@content-desc='"+uname+"']");// com.android.contacts:id/menu_editPhoneTools.clickById(driver, "com.android.contacts:id/menu_edit");//List<WebElement> eles = driver.findElementsByClassName("android.widget.EditText");eles.get(1).clear();eles.get(1).sendKeys(utel);// com.android.contacts:id/menu_savePhoneTools.clickById(driver, "com.android.contacts:id/menu_save");}//删除联系人public void delcontactor(String uname) {PhoneTools.clickByXpath(driver, "//android.widget.TextView[@content-desc='"+uname+"']");PhoneTools.clickByXpath(driver, "//android.widget.ImageButton[@content-desc='更多选项']");PhoneTools.clickByXpath(driver, "/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.ListView/android.widget.LinearLayout[1]");PhoneTools.clickById(driver, "android:id/button1");}}
写测试类
package tongxunlu;import static org.junit.Assert.*;import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;import io.appium.java_client.AppiumDriver;public class TestPhone {static AppiumDriver driver=null;static PhoneActivity activity=null;@BeforeClasspublic static void setUpBeforeClass() throws Exception {driver = PhoneTools.getDriver("peizhi.properties");activity=new PhoneActivity(driver);}@AfterClasspublic static void tearDownAfterClass() throws Exception {}/*@Testpublic void testAddContactor() {try {activity.addContactor("ww","112233");} catch (Exception e) {// TODO: handle exceptionfail("失败了"+e.getMessage());}}*/@Testpublic void testEditContactor(){try {activity.editContactor("uu", "112233123");} catch (Exception e) {// TODO: handle exceptionfail("失败了"+e.getMessage());}}/*@Testpublic void testDelContactor(){try {activity.delcontactor("uu");} catch (Exception e) {// TODO: handle exceptionfail("失败了"+e.getMessage());}}*/
}
driver 的方法
driver.fineElementById
driver.fineElementByClassName/driver.fineElementsByClassName – 找到一个或多个
driver.fineElementByXpath
button.getAttribute() –
写配置文件 – 写工具类 – 封装页面功能 – 写测试类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hBVSqXQB-1679826710704)(C:\Users\11700\AppData\Roaming\Typora\typora-user-images\image-20220610091603272.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SNo9tXf9-1679826710705)(C:\Users\11700\AppData\Roaming\Typora\typora-user-images\image-20220610091913199.png)]
二、python 手机自动化
from appium import webdriverclass ContactActivity():def __init__(self,driver):self.driver = driverdef add_contact(self,name,tel):# 添加联系人#self.driver = webdriver.Remote() -- 目的是为了后面写driver的时候会出现函数self.driver.find_element_by_id("com.android.contacts:id/floating_action_button").click()edits = self.driver.find_elements_by_class_name("android.widget.EditText")edits[0].send_keys(name)edits[1].send_keys(tel)self.driver.find_element_by_id("com.android.contacts:id/menu_save").click()
from beice import ContactActivity
from appium import webdriverif __name__ == "__main__":capability = {'platformName': 'Android','platformVersion': '21.1.0','deviceName': 'yeshen','appPackage': 'com.android.contacts','udid': '127.0.0.1:62001','noReset': 'true','appActivity': '.activities.PeopleActivity'}driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub",capability)activity = ContactActivity(driver)activity.add_contact(name="zz",tel="190876")
web自动化
一、python web自动化
什么是自动化?什么时候使用自动化?什么时候使用手动?
下载浏览器 – 配置驱动 –
json 是什么? – 数据交换格式,用字符串表示js对象的一种格式
jison中的{}是什么意思?-- 一个{} 就是一个json 对象 [] 是一个数组
jison 是键值对 – 每个键值对用,号隔开 – 键和值中间用分号隔开
值可以是简单的数据类型,值也可以是一个对象,也可以是一个数组
Selenium IDE是嵌入到Firefox浏览器中的一个插件,实现简单的浏览器操作的录制与回放功能。(首先打开火狐浏览器 – 菜单 – 扩展和主题 --插件 – 搜索selenium – 选择 Selenium IDE – 选择安装)
selenium IDE – 只能录制你的操作
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vhmL8hqW-1679826710706)(C:\Users\11700\AppData\Roaming\Typora\typora-user-images\image-20220613145209211.png)]
1. 8大寻找元素的方式
根据 id 找元素 find_element_by_id()
根据 name 属性值找元素 find_element_by_name()
根据 类名 找元素 find_element_by_class_name()、find_elements_by_class_name()
根据 标签名 找元素 find_element_by_tag_name()、find_elements_by_tag_name()
根据 链接文本 找元素 find_element_by_link_text()、find_elements_by_link_text()
根据 部分连接文本 找元素 find_element_by_partial_link_text()、find_elements_by_partial_link_text()
根据 xpath路径表达式 找元素 find_element_by_xpath()、find_elements_by_xpath
根据 css选择器 找元素 find_elements_by_css_selector()、find_element_by_css_selector()
1.1 根据id找元素
driver.close
#先导包
from selenium import webdriver
import time
#获取火狐driver对象
driver = webdriver.Firefox()
#请求项目地址
driver.get("file:///E:/%E5%86%B3%E6%88%98%E6%B5%8B%E8%AF%95%E5%B7%A5%E7%A8%8B%E5%B8%88/08%20%E5%8E%8B%E7%BC%A9%E6%96%87%E4%BB%B6/day66/testpage/page001.html")
time.sleep(3)
#使用id来寻找
driver.find_element_by_id("btn1").click()
time.sleep(3)
driver.quit()#关闭所有窗口
1.2 根据name(标签属性)找元素
from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("file:///E:/%E5%86%B3%E6%88%98%E6%B5%8B%E8%AF%95%E5%B7%A5%E7%A8%8B%E5%B8%88/08%20%E5%8E%8B%E7%BC%A9%E6%96%87%E4%BB%B6/day66/testpage/page002.html")
driver.find_element_by_name("uname").send_keys("killer")
driver.find_element_by_name("upw").send_keys("999")
time.sleep(5)
driver.quit()
1.3 根据classname类名来找元素
find_element_by_class_name() – 找这个界面第一个符合classname的
find_elements_by_class_name() – 找这个界面中所有符合的
from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("file:///E:/%E5%86%B3%E6%88%98%E6%B5%8B%E8%AF%95%E5%B7%A5%E7%A8%8B%E5%B8%88/08%20%E5%8E%8B%E7%BC%A9%E6%96%87%E4%BB%B6/day66/testpage/page003.html")
ele1 = driver.find_element_by_class_name("wd")
print(ele1.get_attribute("src"))
eles = driver.find_elements_by_class_name("wd")
for ele in eles:print(ele.get_attribute("src"))
time.sleep(5)
driver.quit()
1.4 根据tagname 标签名来找元素 tag – 标签的意思
find_element_by_tag_name(“eg:button”) – 找这个界面第一个标签
find_elements_by_tag_name() – 找这个界面中所有标签
from selenium import webdriver
import timedriver = webdriver.Firefox()
driver.get("file:///E:/%E5%86%B3%E6%88%98%E6%B5%8B%E8%AF%95%E5%B7%A5%E7%A8%8B%E5%B8%88/08%20%E5%8E%8B%E7%BC%A9%E6%96%87%E4%BB%B6/day66/testpage/page004.html")
#driver.find_element_by_tag_name("button").click()
buttons = driver.find_elements_by_tag_name("button")
for button in buttons:button.click()time.sleep(3)driver.switch_to.alert.dismiss()#关闭弹窗
time.sleep(3)
driver.quit()
1.5 根据 linktest 来寻找元素 – 超链接中含有某些字(全包含)
find_element_by_link_text()
find_elements_by_link_text()
from selenium import webdriver
import timedriver = webdriver.Firefox()
driver.get("file:///E:/%E5%86%B3%E6%88%98%E6%B5%8B%E8%AF%95%E5%B7%A5%E7%A8%8B%E5%B8%88/08%20%E5%8E%8B%E7%BC%A9%E6%96%87%E4%BB%B6/day66/testpage/page005.html")
time.sleep(3)
ele = driver.find_element_by_link_text("明朝那些事")
print(ele.get_attribute("herf"))
ele.click()
time.sleep(3)
driver.quit()
1.6 根据 部分链接文本 模糊匹配 含有 来寻找元素
find_element_by_partial_link_text(value)
find_elements_by_partial_link_text()
from selenium import webdriver
import timedriver = webdriver.Firefox()
driver.get("file:///E:/%E5%86%B3%E6%88%98%E6%B5%8B%E8%AF%95%E5%B7%A5%E7%A8%8B%E5%B8%88/08%20%E5%8E%8B%E7%BC%A9%E6%96%87%E4%BB%B6/day66/testpage/page006.html")
time.sleep(3)
eles = driver.find_elements_by_partial_link_text("明朝")
for ele in eles:print(ele.get_attribute("href"))#获取属性值
time.sleep(3)
driver.quit()
1.7 xpath 模糊匹配要找的元素
driver.refresh()#刷新
from selenium import webdriver
import timedriver = webdriver.Firefox()
driver.get("file:///E:/%E5%86%B3%E6%88%98%E6%B5%8B%E8%AF%95%E5%B7%A5%E7%A8%8B%E5%B8%88/08%20%E5%8E%8B%E7%BC%A9%E6%96%87%E4%BB%B6/day66/testpage/page007.html")
time.sleep(5)
driver.find_element_by_xpath("//button[@id='img3']").click()
time.sleep(5)
driver.find_element_by_xpath("//div[@id='div1']/img").click()
time.sleep(5)
driver.refresh()#刷新
time.sleep(5)
imgs = driver.find_elements_by_xpath("//img")
for img in imgs:img.click()time.sleep(5)
driver.quit()
tomcat
D:\apache-tomcat-7.0.40\webapps\ROOT 里面可以放html文件 直接输入网址127.0.0.1:8080/文件名 就可以直接访问文件
1.8 根据css中选择器来选择元素
css 选择器:标签选择器、类选择器、id选择器
from selenium import webdriver
import timedriver = webdriver.Firefox()
driver.get("http://127.0.0.1:8080/page008.html")
time.sleep(3)
driver.find_element_by_css_selector("#img1").click()
time.sleep(3)
driver.refresh()
imgs = driver.find_elements_by_css_selector(".imgxx")
for img in imgs:img.click()time.sleep(3)
driver.refresh()
imgkks = driver.find_elements_by_css_selector("img")
for imgkk in imgkks:imgkk.click()time.sleep(3)
driver.quit()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1jJFOMDi-1679826710707)(C:\Users\11700\AppData\Roaming\Typora\typora-user-images\image-20220614104318392.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vKzaWd8d-1679826710708)(C:\Users\11700\AppData\Roaming\Typora\typora-user-images\image-20220614104545278.png)]
2. 页面相关操作
请求某个url driver.get(url)
刷新页面操作 refresh()
回退到之前的页面 back()
前进到之后的页面 forward()
获取当前访问页面url current_url
获取当前浏览器标题 title
保存图片 get_screenshot_as_png()/get_screenshot_as_file(file)
网页源码 page_source
from selenium import webdriver
import timedriver = webdriver.Firefox()
driver.get("file:///E:/test_html/testpage3/testpage01.html")
time.sleep(5)
driver.find_element_by_id("a1").click()
time.sleep(3)
print(driver.title)
print("+++++++++++++++++++++++")
print(driver.current_url)
print("++++++++++++++++++++++++++")
print(driver.page_source)
print("+++++++++++++++++++++++++")
liu = driver.get_screenshot_as_png()
file = open("E:\\zidonghuaceshi_log\\aa.png","wb")
file.write(liu)
time.sleep(3)
driver.forward()#前进到之后的页面
time.sleep(3)
driver.back()#返回
time.sleep(3)
driver.quit()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OH4yeygm-1679826710708)(C:\Users\11700\AppData\Roaming\Typora\typora-user-images\image-20220614110626696.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-scOZISLj-1679826710709)(C:\Users\11700\AppData\Roaming\Typora\typora-user-images\image-20220614110830752.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vje8x2Im-1679826710709)(C:\Users\11700\AppData\Roaming\Typora\typora-user-images\image-20220614111901151.png)]
3. 出错截图
python 的异常处理
try:
pass()#被检测的代码块
except:
pass()#出了异常后执行的代码
finally:
pass()# 必须执行的代码,一般是扫尾工作
from selenium import webdriver
import timedriver = webdriver.Firefox()
driver.get("file:///E:/%E5%86%B3%E6%88%98%E6%B5%8B%E8%AF%95%E5%B7%A5%E7%A8%8B%E5%B8%88/08%20%E5%8E%8B%E7%BC%A9%E6%96%87%E4%BB%B6/day66/testpage/page001.html")
time.sleep(5)
try:driver.find_element_by_id("a2").click()
except:print("==出现异常了==")driver.get_screenshot_as_file("E:\\zidonghuaceshi_log\\a.png")
finally:driver.quit()
4. 鼠标事件
鼠标操作需要导入类,from selenium.webdriver import ActionChains,然后创建对象ActionChains(driver)
鼠标右击
el = driver.find_element_by_xxx(value)
ActionChains(driver).context_click(el).perform()
鼠标双击
el = driver.find_element_by_xxx(value)
ActionChains(driver).double_click(el).perform()
鼠标悬停
el = driver.find_element_by_xxx(value)
ActionChains(driver).move_to_element(el).perform()
from selenium import webdriver
from selenium.webdriver import ActionChains
import timedriver = webdriver.Firefox()
driver.get("file:///E:/test_html/testpage2/testpage01.html")
time.sleep(5)
# 滑动
js = "window.scrollTo(0,1500)"#准备一句js代码,x为水平拖动距离,y为垂直拖动距离
driver.execute_script(js)#用driver来执行js代码
time.sleep(3)ele = driver.find_element_by_id("btn2")
chains = ActionChains(driver)#创建一个管理鼠标的动作链对象
# 使用动作链来调用鼠标右键
# chains.context_click(ele).perform()
div1 = driver.find_element_by_id("div1")
chains.move_to_element(div1).perform()
time.sleep(3)
driver.quit()
5. 键盘操作
导包 from selenium.webdriver.common.keys import Keys
常用键盘操作
send_keys(Keys.BACK_SPACE) 删除键(BackSpace)
send_keys(Keys.SPACE) 空格键(Space)
send_keys(Keys.TAB) 制表键(Tab)
send_keys(Keys.ESCAPE) 回退键(Esc)
send_keys(Keys.ENTER) 回车键(Enter)
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.keys import Keys
from selenium import webdriver
import timedriver = webdriver.Firefox()
driver.get("file:///E:/test_html/testpage2/testpage01.html")
time.sleep(5)
in1 = driver.find_element_by_id("in1")
in2 = driver.find_element_by_id("in2")
in1.send_keys("hello")
time.sleep(3)
in1.send_keys(Keys.NUMPAD7)#在后面追加一个数字7
time.sleep(3)
in1.send_keys(Keys.NUMPAD1)#在后面追加一个数字1
time.sleep(3)
in1.send_keys(Keys.BACKSPACE)#删除一个字符
time.sleep(3)
in1.send_keys(Keys.CONTROL,'a')# 相当于Ctrl + A 全选
time.sleep(3)
in1.send_keys(Keys.CONTROL,'c')#相当于Ctrl + C 复制
time.sleep(3)
in2.send_keys(Keys.CONTROL,'v')#相当于Ctrl + v 粘贴
time.sleep(3)
driver.quit()
6. 弹出框
进入到弹出框中 driver.switch_to.alert()
接收警告 accept()
关闭警告 dismiss()
发送文本到警告框 send_keys(data)
from selenium import webdriver
import timedriver = webdriver.Firefox()
driver.get("file:///E:/test_html/testpage2/testpage03.html")
time.sleep(3)
driver.find_element_by_id("btn1").click()
time.sleep(3)
#先将driver切换到弹窗里面
driver.switch_to.alert.dismiss()#关闭弹窗
time.sleep(3)
driver.find_element_by_id("btn5").click()
time.sleep(3)
driver.switch_to.alert.accept()#接收弹窗
time.sleep(3)
driver.quit()
7.下拉框
导包–from selenium.webdriver.support.select import Select
将定位到的下拉框元素传入Select类中 selobj = Select(element)
通过索引选择,index 索引从 0 开始 select_by_index()
通过值选择(option标签的一个属性值) select_by_value()
通过文本选择(下拉框的值) select_by_visible_text()
查看所有已选 all_selected_options
查看第一个已选 first_selected_option
查看是否是多选 is_multiple
查看选项元素列表 options
取消选择 deselect_by_index() /deselect_by_value()/ deselect_by_visible_text()
from selenium import webdriver
from selenium.webdriver.support.select import Select
import timedriver = webdriver.Firefox()
driver.get("file:///E:/test_html/testpage2/testpage01.html")
time.sleep(3)
s1 = driver.find_element_by_id("s1")
sObject = Select(s1)
sObject.select_by_index(3)
time.sleep(3)
sObject.select_by_visible_text("上海")
time.sleep(3)
sObject.select_by_value("xian")
time.sleep(3)
driver.quit()
8. 单选复选框
选项.is_selected() – 判断这个选项有没有选中
from selenium import webdriver
from selenium.webdriver.support.select import Select
import timedriver = webdriver.Firefox()
driver.get("file:///E:/test_html/testpage2/testpage01.html")
time.sleep(3)
eles = driver.find_elements_by_name("sex")
for ele in eles:value = ele.get_attribute("value")if value == "woman":ele.click()
time.sleep(3)
duoxuans = driver.find_elements_by_name("vv")
for duoxuan in duoxuans:value = duoxuan.get_attribute("value")xuanze = ["ww","xx","ss"]if value in xuanze:duoxuan.click()time.sleep(3)
driver.quit()
9. cookies (课下了解)
10. 窗体的切换
多标签/多窗口、多表单/多框架切换
多表单/多框架切换
直接使用id值切换进表单(界面中有iframe表单时使用)
- driver.switch_to.frame(value)
定位到表单元素,再切换进入
el = driver.find_element_by_xxx(value)
driver.switch_to.frame(el)
跳回最外层的页面 driver.switch_to.default_content()
跳回上层的页面 driver.switch_to.parent_frame()
多标签/多窗口之间的切换
获取所有窗口的句柄 handles = driver.window_handles
通过窗口的句柄进入的窗口 driver.switch_to.window(handles[n])
10.1 iframe表单切换
from selenium import webdriver
from selenium.webdriver.support.select import Select
import timedriver = webdriver.Firefox()
driver.get("file:///E:/test_html/testpage4/page1.html")
time.sleep(5)
driver.find_element_by_id("btn11").click()
frame1 = driver.find_element_by_id("f1")
driver.switch_to.frame(frame1)#进frame
time.sleep(3)
s1 = driver.find_element_by_id("s1")
sObject = Select(s1)
sObject.select_by_index(3)
time.sleep(5)
driver.switch_to.default_content()#出frame
time.sleep(3)
driver.find_element_by_id("btn22").click()
time.sleep(5)
driver.quit()
10.2 窗口跳转
多标签/多窗口之间的切换
获取所有窗口的句柄 handles = driver.window_handles
通过窗口的句柄进入的窗口 driver.switch_to.window(handles[n])
n = -1 是进入到最后一个窗体
从第一个窗体开始下标为0,1,2,3,4,5,。。。。。
也可以倒序取就是。。。,-3,-2,-1
from selenium import webdriver
import timedriver = webdriver.Firefox()
driver.get("file:///E:/test_html/testpage3/testpage01.html")
time.sleep(3)
driver.find_element_by_id("a1").click()
time.sleep(3)
handles = driver.window_handles#获取窗体历史
driver.switch_to.window(handles[-1])
driver.find_element_by_id("a2").click()
time.sleep(3)
handles = driver.window_handles
driver.switch_to.window(handles[-1])
driver.find_element_by_id("btn5").click()
time.sleep(3)
driver.switch_to.window(handles[0])
time.sleep(3)
driver.quit()
11.js
#使用driver来执行js语句
import timefrom selenium import webdriver
import timedriver = webdriver.Firefox()
driver.get("file:///E:/test_html/testpage2/testpage03.html")
driver.execute_script("window.document.getElementById('btn1').click()")
time.sleep(3)
driver.switch_to.alert.dismiss()
time.sleep(3)
ele1 = driver.find_element_by_id("btn5")
driver.execute_script("arguments[0].click()",ele1)
time.sleep(3)
driver.switch_to.alert.dismiss()
time.sleep(3)
img1 = driver.find_element_by_id("img1")
width_value = "200px"
height_value = "200px"
#参数列表用arguments来表示, arguments是所有参数的元组
driver.execute_script("arguments[0].setAttribute('width',arguments[1])",img1,width_value)
driver.execute_script("arguments[0].setAttribute('height',arguments[1])",img1,height_value)
time.sleep(3)
style_content = "border:2px solid red"
driver.execute_script("arguments[0].setAttribute('style',arguments[1])",img1,style_content)
time.sleep(3)
#img1.style.border = "5px solid blue"
driver.execute_script("arguments[0].style.border = '5px solid blue'",img1)
time.sleep(3)
driver.quit()
12.练习
12.1 豆瓣
# https://www.douban.com/
from selenium import webdriver
import timedriver = webdriver.Firefox()
driver.get("https://www.douban.com/")
time.sleep(3)
driver.find_element_by_link_text("豆瓣电影").click()
time.sleep(3)
handles = driver.window_handles
driver.switch_to.window(handles[-1])
driver.find_element_by_link_text("选电影").click()
time.sleep(3)
handles = driver.window_handles
driver.switch_to.window(handles[-1])
driver.find_element_by_css_selector("label:nth-child(7)").click()
time.sleep(3)
driver.quit()
12.2 豆瓣2
from selenium import webdriver
import timedriver = webdriver.Firefox()
driver.get("https://movie.douban.com/")
time.sleep(3)
driver.find_element_by_link_text("影讯&购票").click()
time.sleep(3)
ele1 = driver.find_element_by_id("inp-query")
ele1.send_keys("侏罗纪世界3")
time.sleep(3)
driver.find_element_by_css_selector(".inp-btn > input").click()
time.sleep(3)
driver.find_element_by_css_selector(".sc-bZQynM:nth-child(2) .cover").click()
time.sleep(3)
driver.find_element_by_link_text("购票").click()
time.sleep(3)
driver.find_element_by_css_selector(".need-promission > .accept").click()
time.sleep(3)
driver.find_element_by_link_text("万达影城").click()
time.sleep(3)
driver.find_element_by_css_selector(".cinema-cell:nth-child(3) .cinema-address").click()
time.sleep(5)
driver.find_element_by_css_selector(".cinema-cell:nth-child(3) > .buy-btn > a").click()
time.sleep(5)
driver.quit()
13.封装(工具类、)
工具类
# 定义一个工具类
from selenium import webdriver
class Tools_Driver():@staticmethod#获取页面的driver的方法def get_driver_by_page(page_url):driver = webdriver.Firefox()driver.get(page_url)return driver#定义一些点击方法@staticmethoddef clickById(driver,id):driver.find_element_by_id(id).click()@staticmethoddef clickByXpath(driver,xpath):driver.find_element_by_xpath(xpath).click()@staticmethoddef clickByCss(driver,css):driver.find_element_by_css_selector(css).click()@staticmethoddef clickByLinkTest(driver,link_test):driver.find_element_by_link_text(link_test).click()@staticmethoddef sendKeysById(driver,id,value):driver.find_element_by_id(id).send_keys(value)@staticmethoddef sendKeysByXpath(driver,xpath,value):driver.find_element_by_xpath(xpath).send_keys(value)@staticmethoddef closeAlert(driver):driver.switch_to.alert.dismiss()
测试功能类
movie
from selenium import webdriver
import time
from Tools.tools_douban import Tools_Driverclass move_douban():def __init__(self,driver):self.driver = driverdef gou_piao(self,move_name):Tools_Driver.clickByLinkTest(self.driver,"影讯&购票")time.sleep(5)Tools_Driver.sendKeysById(self.driver,"inp-query",move_name)time.sleep(5)Tools_Driver.clickByCss(self.driver,".inp-btn > input")time.sleep(5)Tools_Driver.clickByCss(self.driver,".sc-bZQynM:nth-child(2) .cover")time.sleep(5)Tools_Driver.clickByCss(self.driver,".ticket-btn")time.sleep(5)Tools_Driver.clickByCss(self.driver,".need-promission > .accept")time.sleep(5)Tools_Driver.clickByLinkTest(self.driver,"万达影城")time.sleep(5)Tools_Driver.clickByCss(self.driver,".cinema-cell:nth-child(3) .cinema-address")time.sleep(5)Tools_Driver.clickByCss(self.driver,".cinema-cell:nth-child(3) > .buy-btn > a")time.sleep(5)self.driver.quit()
book
from selenium import webdriver
import time
from Tools.tools_douban import Tools_Driverclass book_douban():def __init__(self,driver):self.driver = driverdef sou_zuo_zhe(self,author_name):Tools_Driver.sendKeysByXpath(self.driver,"//input[@id='inp-query']",author_name)time.sleep(5)Tools_Driver.clickByXpath(self.driver,"//input[@value='搜索']")time.sleep(5)Tools_Driver.clickByXpath(self.driver,"//a[contains(text(),'"+author_name+"')]")time.sleep(5)self.driver.quit()
测试 test
from selenium import webdriver
from Tools.tools_douban import Tools_Driver
from doubanmove.movedemo import move_douban
from doubanbook.bookdemo import book_douban
import timeif __name__ == "__main__":driver_move = Tools_Driver.get_driver_by_page("https://movie.douban.com/")movie_page = move_douban(driver_move)movie_page.gou_piao("侏罗纪世界3")driver_book = Tools_Driver.get_driver_by_page("https://book.douban.com/")book_page = book_douban(driver_book)book_page.sou_zuo_zhe("贾平凹")
14.单元测试
TestCase
TestSuit – 测试套件
TestRunner –
import unittest
# 单元测试unittest
# 导包
import unittest
#写一个用例类 继承unittest TestCase
class Page01_TestCase(unittest.TestCase):@classmethoddef setUpClass(cls) -> None:# -> 指明返回值类型print("所有用例执行之前")@classmethoddef tearDownClass(cls) -> None:print("所有用例执行之后")@classmethoddef setUp(self) -> None:print("每个用例执行前")@classmethoddef tearDown(self) -> None:print("每个用例执行之后")#定义用例放法def test_one(self):print("测试用例01")result = Trueself.assertTrue(result,"实际上是假的")def test_two(self):print("测试用例02")expect = 10actual = 10self.assertEqual(expect,actual,"测试失败了")
if __name__ == "__main__":unittest.main()
import unittest
class Page02_TestCase(unittest.TestCase):def test_page2_test001(self):print("page2测试用例01")self.assertTrue(True)def test_page2_test002(self):print("page02测试用例02")self.assertEqual(2,13,"测试失败")def test_page2_test003(self):print("page2测试用例03")self.assertEqual(30,30,"测试03失败")
import unittest
from danyuanceshi.test001 import Page01_TestCase
from danyuanceshi.test002 import Page02_TestCase
if __name__ == "__main__":suit = unittest.TestSuite()suit.addTest(Page01_TestCase("test_one"))suit.addTest(Page01_TestCase("test_two"))suit.addTest(Page02_TestCase("test_page2_test001"))suit.addTest(Page02_TestCase("test_page2_test002"))suit.addTest(Page02_TestCase("test_page2_test003"))runner = unittest.TextTestRunner()runner.run(suit)
可以生成报告
import HTMLTestRunner
import unittest
from danyuanceshi.test001 import Page01_TestCase
from danyuanceshi.test002 import Page02_TestCase
if __name__ == "__main__":suit = unittest.TestSuite()suit.addTest(Page01_TestCase("test_one"))suit.addTest(Page01_TestCase("test_two"))suit.addTest(Page02_TestCase("test_page2_test001"))suit.addTest(Page02_TestCase("test_page2_test002"))suit.addTest(Page02_TestCase("test_page2_test003"))baogao_file = r"E:\\zidonghuaceshi_log\\a1.html"fb = open(baogao_file,"wb")html_runner = HTMLTestRunner.HTMLTestRunner(stream=fb,title="自动化测试报告1",description="这是page01和page02的测试报告")html_runner.run(suit)fb.close()
15.断言 assert
beice
class Page_Gongneng():def first_fun(self):return Falsedef sec_fun(self,a,b):return a+bdef third_fun(self):return "hello"def forth_fun(self):return Nonedef five_fun(self):return "he"def six_fun(self):try:print("==功能代码===")return Trueexcept:return False
测试用例的名字必须以test开头
import unittest
from duanyan.beice import Page_Gongneng
class DanYuan_TestCasre(unittest.TestCase):def test_one(self):result = Page_Gongneng().first_fun()self.assertTrue(result,"测试失败")def test_two(self):result = Page_Gongneng().sec_fun(2,3)self.assertEqual(5,result,"计算错误")def test_third(self):result = Page_Gongneng().third_fun()self.assertIs(result,"hello")def test_forth(self):result = Page_Gongneng().forth_fun()self.assertIsNone(result)def test_five(self):result = Page_Gongneng().five_fun()self.assertIn(result,"hello","不包含")def test_five2(self):self.assertIn(2,[1,2,3],"不包含")def test_da_yu(self):self.assertGreater(10,9,"不大于")def test_lei_xing(self):self.assertIsInstance(3.2,int,"不是int")def test_xiaoyu(self):slf.assertLess(10,9,"不小于")
16.po模型
1.写父类方法
#定义一个所有页面的父类
#在这个父类中提供子类公有的方法
from selenium import webdriver
class BasePage():#构造函数中需要传入driver对象def __init__(self,driver:webdriver):self.driver = driver#根据id点击def clickById(self,id):self.driver.find_element_by_id(id).click()def clickByXpath(self,xpath):self.driver.find_element_by_xpath(xpath).click()def clickByLinkText(self, linktext):self.driver.find_element_by_link_text(linktext).click()def sendkeysById(self, id, value):self.driver.find_element_by_id(id).send_keys(value)def sendkeysByXpath(self, xpath, value):self.driver.find_element_by_xpath(xpath).send_keys(value)# 关闭alertdef close_alert(self):self.driver.switch_to.alert().dismiss()
2.写功能方法(功能类)
#定义一个读书页面的功能 继承BasePage
#在此类中定义读书页面中所有的功能
from page.basepage import BasePage
from selenium import webdriver
import time
class Page_Book(BasePage):def __init__(self,driver):super().__init__(driver)#查询作者信息的功能#定义豆瓣读书的功能def sou_suo_zuozhe(self,author_name):try:self.sendkeysByXpath("//input[@id='inp-query']", author_name)time.sleep(5)self.clickByXpath("//input[@value='搜索']")time.sleep(5)self.clickByXpath("//a[contains(text(),'" + author_name + "')]")time.sleep(5)return Trueexcept:print("+=====测试出现异常了-----")return Falsefinally:self.driver.quit()#查询某本书的价钱def get_book_price(self,book_name):try:print("====查询结果=======")return 10except:print("====查询出异常了===")return 0finally:self.driver.quit()
#定义一个movie page
#继承BasePage
from selenium import webdriver
from page.basepage import BasePage
import time
class Page_Movie(BasePage):def __init__(self,driver:webdriver):super().__init__(driver)#定义页面功能# 电影购票的功能def gou_piao(self, movie_name):try:self.clickByLinkText( "影讯&购票")time.sleep(5)self.sendkeysByXpath("//input[@id='inp-query']", movie_name)self.clickByXpath("//input[@value='搜索']")time.sleep(5)self.clickByXpath("//a[contains(text(),'" + movie_name + "')]")time.sleep(5)self.clickByLinkText("购票")time.sleep(5)return Trueexcept:print("====测试出现异常了====")return Falsefinally:self.driver.quit()def cha_yingYuan(self,yingyuan_name):try:print("====查影院的功能===")return Trueexcept:return Falsefinally:self.driver.quit()
3.写测试方法(测试类)
#这个用例是对页面PageBook的测试用例
import unittest
from page.dushu import Page_Book
from selenium import webdriver
import time
class Book_Page_TestCase(unittest.TestCase):@classmethoddef setUpClass(cls) -> None: # 所有用例执行之前得到页面的对象pass@classmethoddef tearDownClass(cls) -> None:pass # 所有用例执行之后关闭页面对象def setUp(self) -> None:passdef tearDown(self) -> None:pass#测试用例方法def test_sou_author(self):self.driver = webdriver.Firefox()self.page_book = Page_Book(self.driver)self.driver.get("https://book.douban.com/")time.sleep(5)jieguo1 = self.page_book.sou_suo_zuozhe("贾平凹")self.assertTrue(jieguo1,"========读书页面===测试用例1失败======")def test_book_price(self):self.driver = webdriver.Firefox()self.page_book = Page_Book(self.driver)self.driver.get("https://book.douban.com/")time.sleep(5)jieguo2 = self.page_book.get_book_price("狼")self.assertLess(jieguo2,50,"====读书页面===测试用例2失败===")
#这个用例是对页面PageMovie的测试用例
import unittest
from page.movie import Page_Movie
from page.dushu import Page_Book
from selenium import webdriver
import time
class Movie_Page_TestCase(unittest.TestCase):@classmethoddef setUpClass(cls) -> None:#所有用例执行之前得到页面的对象pass@classmethoddef tearDownClass(cls) -> None:pass#所有用例执行之后关闭页面对象def setUp(self) -> None:passdef tearDown(self) -> None:passdef test_goupiao(self):self.driver = webdriver.Firefox()self.page_movie = Page_Movie(self.driver)self.driver.get("https://movie.douban.com/")time.sleep(5)jieguo1 = self.page_movie.gou_piao("侏罗纪世界3")self.assertTrue(jieguo1,"===电影页面===测试用例1失败======")def test_chayingyuan(self):self.driver = webdriver.Firefox()self.page_movie = Page_Movie(self.driver)self.driver.get("https://movie.douban.com/")time.sleep(5)jieguo2 = self.page_movie.cha_yingYuan("万达")self.assertTrue(jieguo2,"===电影页面=测试用例2失败====")
4.测试套件
#使用测试套件来完成对所有页面的测试
import unittest
from testcase.movietest import Movie_Page_TestCase
from testcase.booktest import Book_Page_TestCase
import HTMLTestRunner
if __name__ == "__main__":suit = unittest.TestSuite()suit.addTest(Movie_Page_TestCase("test_goupiao"))suit.addTest(Movie_Page_TestCase("test_chayingyuan"))suit.addTest(Book_Page_TestCase("test_sou_author"))suit.addTest(Book_Page_TestCase("test_book_price"))#定义一个带有报告的runnerbaogao_file = r"D:\\2202\\day69\\baogao2.html"#创建一个报告的文件路径fb = open(baogao_file,"wb")#以二进制方式打开文件流html_runner = HTMLTestRunner.HTMLTestRunner(stream=fb,title="自动化测试的报告2",description="这是豆瓣电影和豆瓣读书的测试报告")html_runner.run(suit)fb.close()
5 异常
"""
打印异常信息
"""
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoSuchWindowExceptiontry:driver = webdriver.Firefox()driver.get("http://www.baidu.com")#driver.find_element_by_id("kkk").click()driver.switch_to.window("windowkkk")
except NoSuchElementException as e:print(e)e.with_traceback()
except NoSuchWindowException as e:print(e)e.with_traceback()
6 参数
关键字传参
#参数 不定长参数 *args 1,2,3
#**xxx,xxx会被当做字典进行处理,传参的时候实参必需以key=value的方式进行传参
#**kwargs a=10 b=3 c=9
def fun1(*args):print(args)print("====参数列表====")for i in range(len(args)):print("第%d个参数是%s" % (i+1,args[i]))
fun1(1,2,3)#(1, 2, 3)
fun1(1,"hello",90)
fun1(1,[1,2,3],90)
print("++++++++++++++++++++++++")
def fun2(**kwargs):print(kwargs)print("====参数列表====")for key,value in kwargs.items():print("%s ----- %s" %(key,value))
fun2(a=10,b=9,c=90)
"""
a,b=1,c=3,d
1,2,3,4
1,b=3,c=9,9
"""
def fun2(a,c=2):pass
def fun1(*args,**kwargs):fun2(*args,**kwargs)
""""""
def fun1(*args,**kwargs):print("====参数列表====")for i in args:print(i)print("+++++++++++++++++++++++")for key,value in kwargs.items():print("%s===%s" %(key,value))
print("++++++++++++++++++++++++++++")
fun1(1,2)
print("+++++++++++++++")
fun1(1,a=10,c=9)
print("+++++++++++++++++++++++++++++++++++")
fun1(9,a=88,c=19)
7 装饰器
1 闭包
#闭包
def outter():def inner():print("====闭包功能===")return inner
in1 = outter()
in1()
print("+++++++++++++++++++++++++++")
def outter(a):def inner():print("====%d===" % a)return a+1return inner
in2 = outter(10)
jieguo1 = in2()
print(jieguo1)
"""
基本的装饰
"""
def fun1():print("====功能fun1===")
def outter(f1):def inner():print("=====fun1前增加功能====")f1()print("=====fun1后增强功能====")return inner
f11 = outter(fun1)
f11()
"""
使用装饰器来完成一个方法的运行时间
"""
import time
#定义一个装饰器
def timmer_fun(f):def inner():start = time.time()print("===装饰器--开始")f()end = time.time()print(end-start)print("===装饰器--结束")return freturn inner@timmer_fun
def fun1():print("====fun1===开始===")time.sleep(5)print("====fun1===end")
fun1()
print("++++++++++++++++++++++++++++")
@timmer_fun
def fun2():print("====fun2===开始===")time.sleep(10)print("====fun2===end")
fun2()
"""
被装饰函数有参数时"""
import time
#定义一个装饰器
def timer_demo(f):def inner(*args,**kwargs):print("====装饰器开始====")start = time.time()f(*args,**kwargs)#可以接收任意参数的方法 也就是说可以装饰所有的方法end = time.time()print(end-start)return f#闭包返回的是被装饰函数的对象return inner#装饰器返回的是闭包对象
@timer_demo
def fun1(a):print("====fun1===begin===")time.sleep(5)print("====fun1==end=====")
fun1(10)
print("++++++++++++++++++++++++++++++++++++++++")
@timer_demo
def fun2(a=2,b=9,c=8):print("====fun2===begin===")time.sleep(5)print("====fun2==end=====")
fun2(10,8,32)
17 参数化
"""
ddt实战首先声明一个@ddt,让程序知道我们要使用ddt了使用@data来设定待测参数使用@unpack来拆分数据,根据“,”来进行拆分导入外部数据:@file_data
"""
import unittest
from ddt import ddt,data
@ddt
class Test_Case1(unittest.TestCase):@data(1,2,3,4,5)def test_one(self,value):print(value)@data((1,2,3),(4,5,6))def test_two(self,value):print(value)
"""
@unpack使用:拆分数据,可以拆分列表,元组,字典
"""
import unittest
from ddt import ddt,data,unpack
@ddt
class Test_case2(unittest.TestCase):@data(("qq","123"),("ww","222"),("ss","999"))#设计的用例数据@unpack#对用例数据进行分解def test_one(self,value1,value2):print("用户名 %s 密码 %s" %(value1,value2))#参数话设计的是字典@data({'name':'qq','pw':'123'},{'name':'ww','pw':'222'},{'name':'ss','pw':'999'})@unpackdef test_two(self,name,pw):#定义的就是字典的键print("====字典的数据===")print(name,pw)
data1.txt
zhangfei,18989899
liubei,128999999
"""
2.读取文件中的内容,填入参数
"""
import unittest
from ddt import ddt,data,unpack,file_data
def read_file():params = []#定义一个列表来接收文件内容file1 = open("data1.txt","r",encoding="utf-8")for line in file1.readlines():params.append(line.strip("\n").split(","))return params
@ddt
class Test_case3(unittest.TestCase):@data(*read_file())@unpackdef test_one(self,name,tel):print("+++++++++++++++++++++++")print(name,tel)
data2.json
{
“case1”: {“name”: “zhangfei”,“tel”: “19090909”},
“case2”: {“name”: “liubei”,“tel”: “189889888”},
“case3”: {“name”: “guanyu”,“tel”: “168888888”}
}
#参数是json文件
import unittest
from ddt import ddt,data,unpack,file_data
@ddt
class Test_Case1(unittest.TestCase):@file_data("data2.json")def test_one(self,name,tel):print(name,tel)
使用@data来设定待测参数
使用@unpack来拆分数据,根据“,”来进行拆分
导入外部数据:@file_data
“”"
import unittest
from ddt import ddt,data
@ddt
class Test_Case1(unittest.TestCase):
@data(1,2,3,4,5)
def test_one(self,value):
print(value)
@data((1,2,3),(4,5,6))
def test_two(self,value):
print(value)
```python
"""
@unpack使用:拆分数据,可以拆分列表,元组,字典
"""
import unittest
from ddt import ddt,data,unpack
@ddt
class Test_case2(unittest.TestCase):@data(("qq","123"),("ww","222"),("ss","999"))#设计的用例数据@unpack#对用例数据进行分解def test_one(self,value1,value2):print("用户名 %s 密码 %s" %(value1,value2))#参数话设计的是字典@data({'name':'qq','pw':'123'},{'name':'ww','pw':'222'},{'name':'ss','pw':'999'})@unpackdef test_two(self,name,pw):#定义的就是字典的键print("====字典的数据===")print(name,pw)
data1.txt
zhangfei,18989899
liubei,128999999
"""
2.读取文件中的内容,填入参数
"""
import unittest
from ddt import ddt,data,unpack,file_data
def read_file():params = []#定义一个列表来接收文件内容file1 = open("data1.txt","r",encoding="utf-8")for line in file1.readlines():params.append(line.strip("\n").split(","))return params
@ddt
class Test_case3(unittest.TestCase):@data(*read_file())@unpackdef test_one(self,name,tel):print("+++++++++++++++++++++++")print(name,tel)
data2.json
{
“case1”: {“name”: “zhangfei”,“tel”: “19090909”},
“case2”: {“name”: “liubei”,“tel”: “189889888”},
“case3”: {“name”: “guanyu”,“tel”: “168888888”}
}
#参数是json文件
import unittest
from ddt import ddt,data,unpack,file_data
@ddt
class Test_Case1(unittest.TestCase):@file_data("data2.json")def test_one(self,name,tel):print(name,tel)
相关文章:
1.11、自动化
自动化 一、java 手机自动化 首先new DesertCapabilities(这是一个类) setCapability – 设置信息 获取appium的驱动对象 new AppiumDriver – 本机IP地址:端口号/wd/hub,前面的设置值信息 driver.findElementById() – 通过id找位置 click() – 点击 &…...

函数的定义与使用及七段数码管绘制
函数的定义 函数是一段代码的表示 函数是一段具有特定功能的、可重用的语句组 函数是一种功能的抽象,一般函数表达特定功能 两个作用:降低编程难度 和 代码复用 求一个阶乘 fact就是 函数名 n就是参数 return就是输出部分即返回值 而函数的调用就是…...

怎么压缩pdf文件大小?pdf文件太大如何压缩?
喜爱看小说的小伙伴们都会在网上下载很多的pdf格式电子书以方便随时阅览,但是pdf的电子书一般都过于的冗长,下载后的储存也是一个问题,怎么pdf压缩大小呢?可以试试今天介绍的这款pdf在线压缩工具来进行pdf压缩(https:/…...

阿里云Linux服务器登录名ecs-user和root选择问题
阿里云服务器Linux系统登录名可以选择root或ecs-user,root具有操作系统的最高权限,但是root会导致的安全风险比较大,ecs-user比较安全,但是如果系统后续依赖root权限就会比较麻烦,从安全的角度,建议选择ecs…...
【云原生】 初体验阿里云Serverless应用引擎SAE(三),挂载配置文件使应用的配置和运行的镜像解耦
目录 一、前言二、SAE配置1、创建配置项2、配置SAE Nginx服务效果1、【云原生】 初体验阿里云Serverless应用引擎SAE(一),部署Nginx服务 2、【云原生】 初体验阿里云Serverless应用引擎SAE(二),前端Nginx静态文件持久化到对象存储OSS 本篇 3、【云原生】 初体验阿里云Se…...

Oracle用户密码过期,修改永不过期
修改密码有效过期时间,可以通过以下四步设置,如果再第一步发现本身的密码过期时间为无限期的,那就请各位小伙伴绕过,如果发现不是无期限的,那么必须设置第四步,才会生效。 目录 第一步:查询密码…...

welearn 视听说1-4
词汇题(55道) 1. You should carefully think over_____ the manager said at the meeting. A. that B. which C. what D. whose 1.选C,考察宾语从句连接词,主句谓语动词think over后面缺宾语,后面的宾语从句谓语动…...

【git】将本地项目同步到远程
前提:git已经安装,并与账号完成密钥绑定 在github上创建一个新仓库 在项目文件夹下,右击选择git bash here ,打开一个终端对话框 git init (在项目目录下出现隐藏的.git文件夹,目的是把该项目文件夹变成git可管理…...

10-链表练习-LeetCode82删除排序链表中的重复元素II
题目 给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回已排序的链表 。 示例 1: 输入:head [1,2,3,3,4,4,5] 输出:[1,2,5] 示例 2: 输入:head …...

贯穿设计模式第五话--接口隔离原则
🥳🥳🥳 茫茫人海千千万万,感谢这一刻你看到了我的文章,感谢观赏,大家好呀,我是最爱吃鱼罐头,大家可以叫鱼罐头呦~🥳🥳🥳 从今天开始,将…...
C语言计算机二级/C语言期末考试 刷题(四)
在空闲时间整理了一些C语言计算机二级和C语言期末考试题库 整理不易,大家点赞收藏支持一下 祝大家计算机二级和期末考试都高分过 系列文章: C语言计算机二级/C语言期末考试 刷题(一) C语言计算机二级/C语言期末考试 刷题&#x…...
JDK8中Stream接口的常用方法
参考答案 Stream 接口中的方法分为中间操作和终端操作,具体如下。 中间操作: filter:过滤元素map:映射,将元素转换成其他形式或提取信息flatMap:扁平化流映射limit:截断流,使其元…...

ThingsBoard源码解析-数据订阅与规则链数据处理
前言 结合本篇对规则链的执行过程进行探讨 根据之前对MQTT源码的学习,我们由消息的处理入手 //org.thingsboard.server.transport.mqtt.MqttTransportHandlervoid processRegularSessionMsg(ChannelHandlerContext ctx, MqttMessage msg) {switch (msg.fixedHeade…...

探究Transformer模型中不同的池化技术
❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博…...
Android 9.0 设置讯飞语音引擎为默认tts语音播报引擎
1.前言 在9.0的系统rom定制化开发中,在产品开发中,一些内置的app需要用到tts语音播报功能,所以需要用到讯飞语音引擎作为默认的系统tts语音引擎功能,所以就需要 了解系统关于tts语音引擎默认的设置方法,然后在设置讯飞语音引擎为默认的tts语音引擎来实现tts语音播报功能的…...
直流无刷电机驱动的PWM频率
以下来源:Understanding the effect of PWM when controlling a brushless dc motorhttps://www.controleng.com/articles/understanding-the-effect-of-pwm-when-controlling-a-brushless-dc-motor/ Brushless dc motors have an electrical time constant τ of a…...

机房动环监控4大价值,轻松解决学校解决问题
不管是政府机构、学校、企业还是医院均有配备机房。机房一般配备服务器、计算机、存储设备、机柜组、UPS、精密空调等关键设备。 传统的机房在事故发生时,无法及时发现并处理,影响范围大,造成严重的损失。因此,一套智慧机房动环监…...

用于平抑可再生能源功率波动的储能电站建模及评价(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
Burpsuite详细教程
Burpsuite是一种功能强大的Web应用程序安全测试工具。它提供了许多有用的功能和工具,可以帮助用户分析和评估Web应用程序的安全性。在本教程中,我们将介绍如何安装、配置和使用Burpsuite,并提供一些常用的命令。 第一步:安装Burp…...

目标检测:FP(误检)和FN(漏检)统计
1. 介绍 目标检测,检测结果分为三类:TP(正确检测),FP(误检),FN(漏检), 尤其是针对复杂场景或者小目标检测场景中,会存在一些FP(误检),FN(漏检)。 如何对检测的效果进行可视化,以帮助我们改进模型,提高模型recall值。 步骤 (1): 数据需要准备为yolo格式(2) 训练数据获得…...

Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
小木的算法日记-多叉树的递归/层序遍历
🌲 从二叉树到森林:一文彻底搞懂多叉树遍历的艺术 🚀 引言 你好,未来的算法大神! 在数据结构的世界里,“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的,它…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...