文主要內容包括以下幾個功能的實現:
·文章發布
·刪除單條文章用例
·刪除所有文章用例
·添加ID標簽實現元素定位
·登錄功能驗證碼識別
添加文章
添加文章頁面:
實現思路:
用例設計:包括添加成功和添加失敗兩條case。
1.元素定位
2.寫標題->內容->點擊發布
3.驗證:toast彈窗文本內容正確
腳本實現:
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from time import sleep
from basic.admin_login import Test_admin_login
class TestArticle(object):
def __init__(self, login):
self.login=login
# 測試添加文章
def test_add_ok(self):
title='我的文章'
content='我的文章內容'
expected='文章保存成功。'
#定位左側文章列表
#文章
self.login.driver.find_element_by_xpath('//*[@id="sidebar-menu"]/li[4]/a/span[1]').click()
sleep(1)
#文章管理
self.login.driver.find_element_by_xpath('//*[@id="sidebar-menu"]/li[4]/ul/li[1]/a').click()
sleep(1)
#新建
self.login.driver.find_element_by_xpath('/html/body/div/div/section[3]/div/div/div/div[1]/div/div/a').click()
sleep(1)
#定位文章區域
#標題
self.login.driver.find_element_by_id('article-title').send_keys(title)
sleep(1)
#進入iframe
frame1=self.login.driver.find_element_by_xpath('//*[@id="cke_1_contents"]/iframe')
self.login.driver.switch_to.frame(frame1)
sleep(1)
#文章內容
self.login.driver.find_element_by_xpath('/html/body').send_keys(content)
#退出frame
self.login.driver.switch_to.default_content()
#發布按鈕
self.login.driver.find_element_by_class_name('btn-primary').click()
#toast定位
loc=(By.CLASS_NAME,"toast-message")
#等待toast出現
WebDriverWait(self.login.driver,5).until(EC.visibility_of_element_located(loc))
#toast文本
message=self.login.driver.find_element(*loc).text
#斷言判斷toast文本和期望值相等
assert message==expected
注意點:
1.frame彈窗的切入切出
2.文章內容定位頁面檢查時到/html,需要自己手動添加到body下'/html/body'
3.發送失敗toast彈窗消失很快,可以多次點擊幾下定位
刪除單條文章用例
刪除文章頁面:
實現思路:
用例設計:刪除成功。
1.鼠標懸停在文章標題
2.點擊垃圾箱
3.驗證:驗證刪除后文章數=刪除前文章數-1
腳本實現:
article.py
# 測試刪除單篇文章
def test_delete_one_article_ok(self):
# 文章管理
self.login.driver.find_element_by_xpath('//*[@id="sidebar-menu"]/li[4]/ul/li[1]/a').click()
sleep(1)
#刪除前文章數
beforenumber=len(self.login.driver.find_elements_by_class_name('jp-actiontr'))
#鼠標懸停文章內容
a=self.login.driver.find_element_by_xpath('/html/body/div/div/section[3]/div/div/div/div[2]/table/tbody/tr[2]/td[2]/strong/a')
ActionChains(self.login.driver).move_to_element(a).perform()
#刪除
self.login.driver.find_element_by_xpath('/html/body/div/div/section[3]/div/div/div/div[2]/table/tbody/tr[2]/td[2]/div/div/a[3]').click()
sleep(1)
#刪除后文章數
afternumber=len(self.login.driver.find_elements_by_class_name('jp-actiontr'))
#驗證刪除后文章數=刪除前文章數-1
assert beforenumber==afternumber+1
技術難點:
1.鼠標懸停操作:
ActionChains(self.login.driver).movetoelement(a).perform()
2.文章數目使用len()函數確認
3.所有文章數目確認通過self.login.driver.findelementsbyclassname定位一組elements確認
刪除所有文章用例
刪除所有文章頁面:
實現思路:
用例設計:刪除成功。
1.點擊全選復選框
2.點擊批量刪除
3.驗證:驗證文章數目=0
實現腳本:
# 測試刪除所有文章
def test_delete_all_article_ok(self):
#文章管理
self.login.driver.find_element_by_xpath('//*[@id="sidebar-menu"]/li[4]/ul/li[1]/a').click()
#點擊全部復選框
self.login.driver.find_element_by_xpath('/html/body/div/div/section[3]/div/div/div/div[2]/table/tbody/tr[1]/th[1]/input').click()
sleep(1)
self.login.driver.find_element_by_id('batchDel').click()
sleep(1)
WebDriverWait(self.login.driver,5).until(EC.alert_is_present())
alert=self.login.driver.switch_to.alert
alert.accept()
sleep(1)
#文章數目=0
afternumber=len(self.login.driver.find_elements_by_class_name('jp-actiontr'))
sleep(1)
assert afternumber==0
if __name__=='__main__':
login=Test_admin_login()
login.login_success()
testArticle=TestArticle(login)
testArticle.test_add_ok()
#testArticle.test_delete_one_article_ok()
testArticle.test_delete_all_article_ok()
總結:
通過上面我們可以發現,自動化用例的實現及用例和功能測試用例基本上是一樣的,相同的操作步驟,相同的驗證方法。只不過是通過腳本的方式展現出來,通過下面的表格再次加深一下印象。
添加ID標簽實現元素定位
問題情境:
在本地環境util工具類里有一個封裝好的圖片驗證碼類,實現識別圖片中的驗證碼,需要傳入參數id。
但前端頁面沒有id屬性,需要添加一個id屬性,如下圖:
那么,怎么樣才能向前端頁面添加屬性值呢?這里我們使用JS語法。
添加id的思路如下:
首先,通過上圖的img標簽找到要處理的HTML元素;
然后,操作這個元素,通過setAttribute添加屬性及屬性值;
注意:js腳本需要放到一個變量中,然后通過self.driver.execute_script(js)執行腳本。
實現腳本:
js="document.getElementsByTagName('img')[0].setAttribute('id','captchaimg')"
self.driver.execute_script(js)
驗證是否添加成功:
1.Chrome瀏覽器F12,找到console,輸入腳本:
document.getElementsByTagName('img')[0].setAttribute('id','captchaimg')
2.返回element tab下,查看存在id屬性如下圖:
上面獲取元素的方法除了標簽名稱還有其他方式如:
·getElementById()
·getElementByName()
·getElementByTagName()
·getElementByClassName()
至于何種方法可以根據源碼查看,源碼有什么用什么方法。
報錯信息
javascript error: Cannot read property 'setAttribute' of undefined
數組越界
源代碼:
js="document.getElementsByTagName('img')[1].setAttribute('id','captchaimg')"
文檔中一共有一個img標簽,下標從0開始,所以將1改為0。
修改后:
js="document.getElementsByTagName('img')[0].setAttribute('id','captchaimg')"
上面提供一種處理問題的思路,當我們需要某種元素標簽時,并且這種標簽不存在的情況下我們可以自己利用js語法添加標簽并實現調用。
同時,在遇到selenium本身語法無法解決的問題,可以借助js腳本完成,比如頁面上下滑動、處理時間空間等等。
登錄功能驗證碼識別
一般web網站登錄頁面都會有驗證碼識別功能 ,如果是公司內部測試,可以讓開發人員通過屏蔽驗證碼或者留后門方式輕松跳過,大可不必把時間浪費在驗證碼識別上。
但是,大部分小伙伴一般剛開始接觸自動化時都是自己找的項目,基本上述兩種方法不適用。
下面推薦兩種常用的驗證碼識別方式:
第一種OCR自動識別方式,缺點較復雜的驗證碼識別不出來。
第二種,第三方API使用,我這里使用的是打碼平臺的,除此之外百度識別或者萬維易源(缺點:調用繁瑣、費用較高)。
場景:識別下圖的驗證碼。
OCR自動識別的原理
在這里我們需要使用pytesseract,它是一款用于光學字符識別(OCR)的python工具,即從圖片中識別出其中嵌入的文字。
整個過程分為截取登錄頁面->獲取驗證碼的位置坐標->打開截圖->從截圖中截取驗證碼的區域->使用pytesseract工具識別驗證碼,這里直接使用pytesseract轉換介紹。
1.安裝Pillow
pip install Pillow
2.安裝pytesseract
pip install pytesseract
3.實現代碼
from PIL import Image 導入Image函數
import pytesseract 導入pytesseract
def get_file_content(filePath):
# 3.驗證碼處理-使用OCR自動識別
qq=Image.open("D://software//project//jpress//testcases//basic//test.png") # 打開jpg驗證碼圖片
text=pytesseract.image_to_string(qq).strip()
運行查看結果返回為空,所以說這種方法對于簡單的驗證碼還可以,復雜一點的可以直接放棄。
第三方API接口
打碼平臺鏈接地址:
http://www.ttshitu.com/docs/index.html?spm=null
首先需要注冊一個賬號,其次充值,1塊錢夠用挺長時間,找到對應的語言(如python),拷貝代碼:
……
※※因原作者要求,文章僅顯示其中一部分,完整文章下載閱讀,可以直接:關注+私信“文章”即可。
最后給軟件測試員的一封信
IT工作是辛苦的,軟件測試當然也不例外。每天執行用例、跟蹤Bug,還要與開發、產品同學爭吵PK,與人斗其樂無窮~
但正是因為這些默默的付出,你讓一場本該在用戶面前發生的災難,提前在自己面前發生了,你是否有一種救世主的感覺?
你拯救了用戶,也拯救了這一軟件,避免了她被撇棄、卸載的命運。既然選擇了測試這一行,何不一站到底~~
現在我邀請你進入我們的軟件測試學習交流群,關注+私信我“測試”,即可拉你入群喲~~
大家可以一起探討交流軟件測試,共同學習軟件測試技術、面試等軟件測試方方面面,還會有免費直播課,收獲更多測試技巧,我們一起進階Python自動化測試/測試開發,走向高薪之路。
那我邀你進群吧!記得:關注+私信我“測試”,即可拉你入群喲~~
何在郵件里顯示購買的商品信息
系統本身的郵件發送很是強大,你可以設置郵件服務器、設置購物流程中何時發送郵件、郵件的內容格式。但是有個功能沒提供,那就是在郵件里顯示購買商品信息。
很多客戶都要求在給客戶發送的郵件里顯示購買商品信息,這樣可以更好的給客戶提醒。今天就講下這個功能的實現。
在flow.php里找到相應的操作步驟代碼,比如我想在客戶下完訂單后發送郵件,就要找到這樣的步驟代碼
elseif ($_REQUEST['step']=='done')
然后找到這個步驟里發送郵件的代碼
send_mail($_CFG['shop_name'], $_CFG['service_email'], $tpl['template_subject'], $content, $tpl['is_html']);
發送郵件的內容是從后臺模板設置那里讀取出來的,所以我們只需要增加模板變量,然后修改模板。
在這行代碼前,增加如下代碼
//發送多個郵件 顯示購物詳細 王文松修改
$wwssql="select g.goods_id,go.* from ".$ecs->table('order_goods')."as g left join".$ecs->table('order_info')."as o on g.order_id=o.order_id left join " .$ecs->table('goods'). " as go on g.goods_id=go.goods_id where o.order_sn="."'$order[order_sn]'";
$wwsrow=$GLOBALS['db']->getAll($wwssql);
//如果需要調用商品屬性,在這里寫代碼
/*for($i=0;$i<count($wwsrow);$i++){
$wwsrow[$i]["##"]=$GLOBALS['db']->GetOne("select attr_value from ".$ecs->table("goods_attr")." where goods_id=".$wwsrow[$i]["goods_id"]." and attr_id=##");
}*/
$smarty->assign('goodslist', $wwsrow);
然后在后臺模板管理-郵件模板里,找到你要修改的模板,輸入如下代碼
您購買的商品如下:
{foreach from=$goodslist item=goods}
{$goods.goods_sn}:{$goods.goods_name}<br/>
{/foreach}
當然您也可以調整的非常好看,這里就不寫了。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。