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) 训练数据获得…...
【MySQL专题】04、性能优化之读写分离(MyCat)
1、MyCat概述 从定义和分类来看,它是一个开源的分布式数据库系统,是一个实现了MySQL协议的Server,前端用户可以把它看做是一个数据库代理,用MySQL客户端工具和命令行访问,而其后端可以用MySQL原生(Native&…...

信息系统项目管理师第四版知识摘编:第5章 信息系统工程
第5章 信息系统工程信息系统工程是用系统工程的原理、方法来指导信息系统建设与管理的一门工程技术学科,它是信息科学、管理科学、系统科学、计算机科学与通信技术相结合的综合性、交叉性、具有独特风格的应用学科。5.1软件工程软件工程是指应用计算机科学、数学及管…...

【2023春招】西山居游戏研发岗笔试AK
120min,一共三道算法、两道填空、10道不定项选择 算法题部分 T1-二叉树后序遍历 题面 一个节点数据为整数的二叉搜索树,它的遍历结果可以在内存中用一个整数数组来表示。比如,以下二叉树,它每个节点的左子节点都比自己小,右子节点都比自己大,对它进行后序遍历,结果可以…...

什么是分布式,分布式和集群的区别又是什么?
1. 什么是分布式 ? 分布式系统一定是由多个节点组成的系统。 其中,节点指的是计算机服务器,而且这些节点一般不是孤立的,而是互通的。 这些连通的节点上部署了我们的节点,并且相互的操作会有协同。 分布式系统对于用户而言&a…...

Cellchat和Cellphonedb细胞互作一些问题的解决(error和可视化)
今日的内容主要解决两个问题,一个是cellchat的代码报错问题,因为已经有很多人提出这个问题了。第二个是Cellphonedb结果的可视化,这里提供一种免费的很实用的快捷可视化方法。其实这些问题只要自己思考都是能明白的。 Cellchat和cellphonedb细…...

大文件分片上传的实现【前后台完整版】
在一般的产品开发过程中,大家多少会遇到上传视频功能的需求,往往我们采用的都是对视频大小进行限制等方法,来防止上传请求超时,导致上传失败。这时候可能将视频分片上传可以对你的项目有一个小小的体验优化。 本片文章前端是vue&…...

Java序列化面试总结
Java序列化与反序列化是什么? Java序列化是指把Java对象转换为字节流的过程,而Java反序列化是指把字节流恢复为Java对象的过程。 序列化: 序列化是把对象转换成有序字节流,以便在网络上传输或者保存在本地文件中。核心作用是对象…...

fs的常用方法
以下是fs模块的一些常用方法: 1. 读取文件内容 使用fs.readFile()方法读取文件内容。该方法接收两个参数:文件路径和回调函数。回调函数的参数包括错误信息和文件内容。 javascript const fs require(fs); fs.readFile(/path/to/file, (err, data)…...

【华为OD机试 2023最新 】字符串重新排列、字符串重新排序(C++ 100%)
文章目录 题目描述输入描述输出描述用例题目解析C++题目描述 给定一个字符串s,s包括以空格分隔的若干个单词,请对s进行如下处理后输出: 1、单词内部调整:对每个单词字母重新按字典序排序 2、单词间顺序调整: 1)统计每个单词出现的次数,并按次数降序排列 2)次数相同,按…...

Matlab自动消除论文插图白边的7种方法
通过Matlab所绘制的插图,如不进行一定的调整,其四周往往存在一定范围的白边。 白边的存在会影响数据展示效果,有时也会给论文的排版造成一定麻烦。 要想消除白边,一种简单的方法是,在导出插图后,用其它软…...