今天跟你們聊一聊自動化測試中的驗證碼處理方法一些小總結,但願對大家有幫助,有說的很差的地方,還請多多指教!java
目前,很多網站在用戶登陸、用戶提交信息登登陸和輸入的頁面上使用了驗證碼技術。驗證碼技術能夠有效防止惡意用戶對網站的濫用,使得網站能夠有效避免用戶信息失竊、廣告SPAM等問題。但與此同時,驗證碼技術的使用卻使得WEB自動化測試面臨了較大的困難。面試
驗證碼通常應用在WEB系統涉及登陸和輸入的頁面上,其實現的通常方法是在頁面上顯示一幅圖片,要求用戶肉眼識別圖片中的信息並將該信息做爲輸入的一部分進行提交。頁面上顯示的這幅圖片通常是一串隨機產生的數字或符號,而且被添加了用於防止識別的背景。驗證碼的主要目的是爲了防止惡意用戶利用自動工具(機器人)對用戶口令進行暴力破解、惡意註冊用戶,或是向網站發佈使人厭煩的廣告信息等。算法
驗證碼具備隨機性和不易被自動工具識別的特色,當用戶訪問某個使用驗證碼的頁面時,每次對該相同頁面的訪問都會獲得一個隨機產生的不一樣的驗證碼,而且,這些驗證碼具備可以被人工識別,但很難被自動工具識別的特色,這樣,自動工具就很難適應使用驗證碼的頁面,從而達到保護網站不被惡意使用的目的。編程
(一)、驗證碼的主要實現方法安全
要解決驗證碼,須要知道驗證碼是如何產生的,驗證碼的生成方式有兩種「讀取方式」和「生成方式」兩種。服務器
讀取方式,就是在服務器目錄下保存製做好的圖片文件,而後顯示在Web頁面上讓用戶識別。這種方式徹底能夠經過url的來破解圖片的地址,經過圖片地址能夠間接的知道圖片表示的驗證碼是什麼。因此如今這種方式不多出現了。session
生成方式,是經過隨機生成字符串,而後利用編程語言的圖形庫生成驗證碼圖片顯示在頁面上讓用戶識別。在生成的時候還能夠增長背景的一些噪音,改變字符和背景的顏色,甚至變形字符。這種方式自己若是不是用對字符的變形和在背景增長噪音的狀況下,能夠經過OCR的技術來識別,可是通過這兩種處理後,使得識別變得很是困難。框架
(二)、驗證碼的大體實現原理dom
使用生成式的驗證碼實現原理:首先服務器端生成隨機數,並把它保存在session中,而後利用圖形庫生成驗證圖片展示給客戶端的用戶辨認;用戶根據驗證碼圖片輸入本身識別的驗證碼發送給服務器端;服務器端根據session保存的隨機數和用戶輸入的驗證碼進行對比,若是匹配驗證經過,若是不匹配驗證失敗。jsp
(三)、自動化測試解決驗證碼的方式
自動化測試解決驗證碼的問題,最主要的有兩種方式,經過識別方法和服務端插入法。這兩種方式實現方法上側重點不一樣,適用的場合也不一樣。
3.1 識別的方法
識別的方法,徹底不用考慮服務端,直接經過圖像識別的技術(如OCR技術),經過識別圖片來破解驗證碼。這種方法優勢就在於不須要服務器端作任何修改,不用提供任何接口,自動化測試即可以完成本身的驗證碼識別。可是這種方法也有致命的缺點,就是它的識別成功率的問題,在存在變形和背景加入噪音的驗證碼中,這種識別率至關的低。若是驗證碼還存在中文的話,那識別成功率就幾乎難以忍受了。這種方法咱們在以往的實踐經驗中,曾經使用OCR技術處理過驗證碼。可是最近遇到一些驗證碼,使用OCR的識別率都很低。
簡單說明一下爲何OCR的識別率比較低,OCR是光學字符識別的簡稱,他通常用來識別等大規則字體的圖像,比方說他能夠掃描印刷的圖書,將紙質的書掃描到計算機中造成文本;也能夠用來識別證件號碼,加快機讀證件速度。因此若是在驗證不規整或者存在噪點,那麼識別率會直線降低。可是市面上有些人作的驗證碼識別程序爲何識別率那麼高而通用的OCR識別程序識別率低呢?因爲驗證碼的生成時的變形和加入噪點是存在規律的,開發者能夠經過這些規律,爲特定的驗證碼生成程序編寫特定的識別代碼,這種狀況下的識別率是很是高的。還有爲何中文識別率低?這個就比較好理解了,想一想英文只有26個字母,26種形態,咱們中文一個字一個形態。還有在OCR識別的時候,他的算法可能會經過識別部分來確認所有,有點盲人摸象的感受(具體的算法能夠參照OCR具體的實現算法),在這種狀況下,若是中文有稍微的變形就很難識別的了。若是不能理解這點,想一想咱們小學學習那些形近字的痛苦,也就知道對於計算機是多難了。
這裏補充一下QTP9.5之後加入了ABBYY公司的OCR解決方案,他對驗證碼的識別率是比較高的。固然silktest2009也加入了OCR識別庫,不過我以爲識別率比較低。具體這兩個工具OCR的部分,能夠參照相關手冊。固然開源中也有OCR的項目,目前比較好的叫tesseract-ocr。能夠將開源的OCR庫加入到自動化測試工程中使用。若是對軟件測試、接口測試、自動化測試、面試經驗交流。感興趣能夠加軟件測試交流:1085991341,還會有同行一塊兒技術交流。
3.2 服務器插入方法
服務器插入方法,方法在服務端提供一個可被客戶端使用的接口,只要客戶端傳遞過來本身的SessionID,該接口就返回此時正確的Session,這種方法就能夠很容易地讓自動測試工具直接獲取到正確的應該提交的驗證碼內容。從測試的角度來講,這種方法就等因而在系統上增長了一個測試接口,從而提升了系統的可測試性。這種方法的缺點也很明顯,上線的程序通常不會保留這樣的缺口,而且若是是作性能測試,經過接口獲取驗證碼,會多一次交互操做,這樣測試結果可能會有差別。
session的獲取的實現方法,根據使用的語言不一樣框架不一樣,可能獲取session中驗證碼的方法有所不同,可是總的思路是一致的。
這裏提供一個java用jsp寫的demo,主要是爲了說明從session中獲取驗證碼的方法思路是什麼樣子的:
首先,先來看一下jsp中通常驗證碼是如何實現的:
CheckCode.jsp文件代碼以下
String sRand="";
for (int i=0;i<4;i++){
String rand=String.valueOf(random.nextInt(10)); //生成隨機數
sRand+=rand;
}
session.setAttribute("rand",sRand); 將隨機數據存入session中
String sRand="";
for (int i=0;i<4;i++){
String rand=String.valueOf(random.nextInt(10)); //生成隨機數
sRand+=rand;
}
session.setAttribute("rand",sRand); 將隨機數據存入session中
簡單分析一下,在頁面中有一個圖片,該圖片是經過驗證碼生成程序來生成的,生成程序首先生成隨機數或者隨機的字母。而後將隨機生成好的代碼存入到session中去。
而後,能夠經過使用jsp的頁面來把session中的驗證碼傳出來,具體代碼以下:
getCheckCode.jsp代碼以下
<%
out.print(session.getAttribute("rand"));
%>
最後,在自動化測試腳本中首先CheckCode.jsp來生成圖片的驗證碼,而後打開getCheckCode.jsp來得到驗證碼,而後將得到的驗證碼填入提交的表單中提交。
總結該方法,適合在測試環境中,加入一個獲取驗證碼的頁面(或者其餘接口),自動化測試經過該頁面來得到相應的驗證碼;當產品上線後,刪除得到驗證碼的頁面便可。該方法不適合生產環境,他實際上是作了一個後門,從安全角度上講,是比較危險的。該方法也不適合對驗證碼加密存儲的狀況:在實際應用中,能夠將隨機生成的驗證碼進行MD5加密存儲到session中,用戶輸入的驗證碼也須要使用MD5加密後,和session中存在的密文進行對比。你們知道破解md5是很是困難的,若是使用這種方法的話,從session中得到驗證碼也是不可取的
3.3 其餘一些方法來解決驗證碼
在實際使用中也能夠經過一些小技巧來解決驗證碼,這些方法就是經過各類手段來逃避或者得到驗證,而這些手段主要是要求開發者在開發的時候留有必定的後門。下面簡述幾種:
一、使用萬能驗證碼,這種方法就是在判斷驗證的時候,若是遇到前臺輸入的是萬能驗證碼,那就不要作驗證碼校驗直接經過。
二、特定用戶跳過驗證碼,這種方法就是若是遇到指定用戶登陸,那麼無論輸入什麼驗證碼,驗證碼校驗都經過。
三、使用hidden 控件在頁面上顯示驗證碼,就是在使用驗證碼的頁面上,加入一個隱藏的控件,該控件的內容就是驗證碼。雖然用戶看不到可是自動化測試工具能夠找到該控件,並得到驗證碼。固然隱藏控件中的驗證碼也可使用加密的方法,自動化測試腳本獲得加密的驗證後,能夠經過解密操做解密驗證碼。
上述的方法都須要開發對代碼進行必定的修改,最好不要在生產環境上作,否則會形成安全漏洞。
(四)、小結
做爲自動化測試工程師遇到驗證碼的問題,無疑是很是頭疼的。若是在測試環境中,最好能經過接口方法,或者開發後門的方法獲取驗證碼,這樣可能更有效。若是上線程序,安全性要求比較高的狀況下,只能使用識別的方法。識別的方法能夠多嘗試幾種OCR程序,因爲OCR程序的算法不一樣,可能對於特定的驗證碼識別的成功率也不一樣。若是遇到中文的驗證碼,且那個中文字還變形了,最好的方法就是告訴開發換成英文的,中文的識別率,那真的很低。
以上內容但願對你有幫助,有被幫助到的朋友歡迎點贊,評論。