<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    qileilove

    blog已經轉移至github,大家請訪問 http://qaseven.github.io/

    Web安全測試-WebScarab工具介紹

     1.1 Webscarab
      【功能】
      WebScarab是一個用來分析使用HTTP和HTTPS協議的應用程序框架。其原理很簡單,WebScarab可以記錄它檢測到的會話內容(請求和應答),并允許使用者可以通過多種形式來查看記錄。WebScarab的設計目的是讓使用者可以掌握某種基于HTTP(S)程序的運作過程;可以用它來調試程序中較難處理的bug,也可以幫助安全專家發現潛在的程序漏洞。
      【適用對象】
      分析使用HTTP和HTTPS協議的應用程序框架
      1.1.1 工具安裝
      WebScarab需要在java環境下運行,因此在安裝WebScarab前應先安裝好java環境(JRE或JDK均可)。
      安裝好jdk后,右擊安裝文件:webscarab-installer-20070504-1631.jar 選擇“打開方式”如下圖:
      然后進入安裝界面,下一步下一步安裝即可。
      1.1.2 功能原理
      webscarab工具的主要功能:它可以獲取客戶端提交至服務器的http請求消息,并以圖形化界面顯示,支持對http請求信息進行編輯修改。
      原理:webscarab工具采用web代理原理,客戶端與web服務器之間的http請求與響應都需要經過webscarab進行中轉,webscarab將收到的http請求消息進行分析,并將分析結果圖形化顯示,如下圖:
      可以用于驗證當客戶端對輸入有限制時(如長度限制、輸入字符集的限制等),可以使用此種方法繞過客戶端驗證服務端是否對輸入有限制。
      1.1.3 工具使用
      下面將主要介紹如何使用webscarab工具對post請求進行參數篡改
      1、  運行WebScarab
      WebScarab有兩種顯示模式:Lite interface和full-featured interface,可在Tools菜單下進行模式切換,需要重啟軟件生效,修改http請求信息需要在full-featured interface下進行。
      2、  點擊Proxy標簽頁->Manual Edit標簽頁
      3、  選中Intercept requests
      在Methods中列舉了http1.1協議所有的請求方法,用來選擇過濾,如我們選擇了post,那WebScarab只能對post請求的http消息進行篡改。
      4、  打開IE瀏覽器的屬性,進入連接》局域網設置,在代理地址中配置host為127.0.0.1或localhost,port為8008
    5、  以上配置便完成了,下面選擇一個功能測試一下,以登錄為例,打開webScarab工具后,在瀏覽器中輸入需訪問的url地址,此時WebSarab會獲取到頁面的所有請求消息并彈出需要修改的會話框,
      輸入正確信息,點擊修改,此時WebScarab會彈出提示框,顯示http傳遞參數信息,可以http請求進行新增、刪除和修改參數操作,修改后點擊“Accept changes”按鈕。
      1.1.34  使用心得
      WebScarab是一款很強大的http消息分析工具,它可以讓我們清楚地觀察到客戶端的http請求消息,同時支持對http消息的修改編輯,很適合web安全性篡改表單數據測試。

    posted @ 2014-11-06 10:32 順其自然EVO 閱讀(5348) | 評論 (0)編輯 收藏

    Selenium并行啟動多個瀏覽器

     快速上手
      如果你對 Selenium 自動化測試已經非常熟悉,你僅僅需要一個快速上手來使程序運行起來。本章節的內容能滿足不同的技術層次,但是如果你僅僅需要一個可以快速上手的指引,那么就顯得有點多。如果是這樣,你可以參考 Selenium Wiki 的相關文章
      什么是 Selenium-Grid ?
      Selenium-Grid 允許你在多臺機器的多個瀏覽器上并行的進行測試,也就是說,你可以同時運行多個測試。本質上來說就是,Selenium-Grid 支持分布式的測試執行。它可以讓你的測試在一個分布式的執行環境中運行。
      何時需要使用
      通常,以下兩種情況你都會需要使用 Selenium-Grid。
      在多個瀏覽器中運行測試,在多個版本的瀏覽器中進行測試,或在不同操作系統的瀏覽器中進行測試。
      減少測試運行時間。
      Selenium-Grid 通過使用多臺機器并行地運行測試來加速測試的執行過程。例如,如果你有一個包含100個測試用例的測試套件,你使用 Selenium-Grid 支持4臺不同的機器(虛擬機或實體機均可)來運行那些測試,同僅使用一臺機器相比,你的測試所需要的運行時間大致為其 1/4。對于大型的測試套件和那些會進行大量數據校驗的需要長時間運行的測試套件來說,這將節約很多時間。有些測試套件可能要運行好幾小時。另一個需要縮短套件運行時間的原因是開發者檢入(check-in)AUT 代碼后,需要縮短測試的運行周期。越來越多的團隊使用敏捷開發,相比整夜整夜的等待測試通過,他們希望盡快地看到測試反饋。
      Selenium-Grid 也可以用于支持多執行環境的測試運行,典型的,同時在多個不同的瀏覽器中運行。例如,Grid 的虛擬機可以安裝測試必須的各種瀏覽器。于是,機器 1 上有 ie8,機器 2 上有 ie9,機器 3 上有最新版的 chrome,而機器 4 上有最新版的 firefox。當測試套件運行時,Selenium-Grid 可以使測試在指定的瀏覽器中運行,并且接收每個瀏覽器的運行結果。
      另外,我們可以擁有一個裝有多個類型和版本都一樣的瀏覽器 Grid。例如,一個 Grid 擁有 4 臺機器,每臺機器可以運行 3 個 firefox 12 實例,形成一個 firefox 的服務農場。當測試套件運行時,每個傳遞給 Selenium-Grid 的測試都被指派給下一個可用的 firefox 實例。通過這種方式,我們可以使得同時有 12 個測試在并行的運行以完成測試,顯著地縮短了測試完成需要的時間。
      Selenium-Grid 非常靈活。以上兩個例子可以聯合起來使用,這樣可以就可以使得不同類型和版本的瀏覽器有多個可運行實例。使用這樣的配置,既并行地執行測試,同時又可以測試多個瀏覽器類型和版本。
      Selenium-Grid 2.0
      Selenium-Grid 2.0 是在編寫本文時(5/26/2012)已發布的最新版本。它同版本 1 有很多不同之處。在 2.0 中,Selenium-Grid 和 Selenium-RC 服務端進行了合并。現在,你僅需要下載一個 jar 包就可以獲得它們。
      Selenium-Grid 1.0
      版本 1 是 Selenium-Grid 的第一個發布版本。如果你是一個 Selenium-Grid 新手,你應該選擇版本 2 。新版本已經在原有基礎上進行了更新,頁增加了一些新特性,并且支持 Selenium-WebDriver。一些老的系統可能仍然在使用版本 1.關于 Selenium-Grid 版本 1 的信息可以參考 Selenium-Grid website
      Selenium-Grid 的 Hub 和 Nodes 是如何工作的?
      Grid 由一個中心和一到多個節點組成。兩者都是通過 selenium-server.jar 啟動。在接下來的章節中,我們列出了一些例子。
      中心接收要執行的測試信息,包括在哪些平臺和瀏覽器執行等。它知道每個注冊了的節點的配置。根據測試信息,它會選擇符合需求的節點進行測試。一旦選定了一個節點,測試腳本就會初始化 Selenium 命令,并且由重心發送給選定的要運行測試的節點。這個節點會啟動瀏覽器,然后在瀏覽器中執行這個 AUT 的 Selenium 命令。
      我們提供了一些圖標來演示其原理。第二張圖標是用以說明 Selenium-Grid 1 的,版本 2 也適用并且對于我們的描述是一個很好的說明。唯一的區別在于相關術語。使用“Selenium-Grid 節點”替換“Selenium Remote Control”即符合我們對 Selenium-Grid 2 的描述。
      下載
      下載過程很簡單。從 SeleniumHq 站點的下載頁面下載 Selenium-Server jar 包。你需要的鏈接在“Selenium-Server (以前是 Selenium-RC)”章節中。
      將它存放到任意文件夾中。你需要確保機器上正確的安裝了 java。如果 java 沒有正常運行,檢查你系統的 path 變量是否包含了 java.exe 的路徑。
      啟動 Selenium-Grid
      由于節點對中心有依賴,所以你通常需要先啟動一個中心。這也不是必須的,因為節點可以識別其中心是否已經啟動,反之亦然。作為教程,我們建議你先啟動中心,否則會顯示一些錯誤信息,你應該不會想在第一次使用 Selenium-Grid 的時候就看到它們。
    啟動中心
      通過在命令行執行以下命令,可以啟動一個使用默認設置的中心。所有平臺可用,包括 Windows Linux, 或 MacOs 。
      java -jar selenium-server-standalone-2.21.0.jar -role hub
      我們將在接下來的章節中解釋各個參數。注意,你可能需要修改上述命令中 jar 包的版本號,這取決于你使用的 selenium-server 的版本。
      啟動節點
      通過在命令行執行以下命令,可以你懂一個使用默認設置的節點。
      java -jar selenium-server-standalone-2.21.0.jar -role node  -hub http://localhost:4444/grid/register
      該操作假設中心是使用默認設置啟動的。中心用于監聽請求使用的默認端口號為 4444,這就是為什么端口 4444 被用于中心 url 中。同時“localhost”假定你的節點和中心運行在同一臺機器上。對于新手來說,這是最簡單的方式。如果要在兩臺不同的機器上運行中心和節點,只需要將“localhost”替換成中心所在機器的 hostname 即可。
      警告: 確保運行中心和節點的機器均已關閉防火墻,否則你將看到一個連接錯誤。
      配置 Selenium-Grid
      默認配置
      JSON 配置文件
      通過命令行選項配置
      中心配置
      通過指定 -role hub 即以默認設置啟動中心:
      java -jar selenium-server-standalone-2.21.0.jar -role hub
      你將看到以下日志輸出:
      Jul 19, 2012 10:46:21 AM org.openqa.grid.selenium.GridLauncher main
      INFO: Launching a selenium grid server
      2012-07-19 10:46:25.082:INFO:osjs.Server:jetty-7.x.y-SNAPSHOT
      2012-07-19 10:46:25.151:INFO:osjsh.ContextHandler:started o.s.j.s.ServletContextHandler{/,null}
      2012-07-19 10:46:25.185:INFO:osjs.AbstractConnector:Started SocketConnector@0.0.0.0:4444
      指定端口
      中心默認使用的端口是 4444 。這是一個 TCP/IP 端口,被用于監聽客戶端,即自動化測試腳本到 Selenium-Grid 中心的連接。如果你電腦上的另一個應用已經占用這個接口,或者你已經啟動了一個 Selenium-Server,你將看到以下輸出:
      10:56:35.490 WARN - Failed to start: SocketListener0@0.0.0.0:4444
      Exception in thread "main" java.net.BindException: Selenium is already running on port 4444. Or some other service is.
      如果看到這個信息,你可以關掉在使用端口 4444 的進程,或者告訴 Selenium-Grid 使用一個別的端口來啟動中心。-port 選項用于修改中心的端口:
      java -jar selenium-server-standalone-2.21.0.jar -role hub -port 4441
      即使已經有一個中心運行在這臺機器上,只要它們不使用同一個端口,就能正常工作。
      你可能想知道哪個進程使用了 4444 端口,這樣你就可以讓中心使用這個默認端口。使用以下命令可以查看你機器上所有運行程序使用的端口:
      netstat -a
      Unix/Linux, MacOs 和 Windows 均支持此命令,只是在 Windows 中 -a 參數為必須的。基本上,你需要顯示進程 id 和端口。在 Unix 中,你可以通過管道 “grep” 輸出那些你關心的端口相關的條目。
      節點配置
      時間參數
      獲取命令行幫助
      Selenium-Server 提供了一個可選項列表,每個選項都有一個簡短的描述。目前(2012夏),命令行幫助還有一些奇怪,但是如果你知道如何去找、如何解讀信息會對你很有幫助。
      Selenium-Server 提供了兩種不同的功能,Selenium-RC server 和 Selenium-Grid。它們是兩個不同的團隊編寫的,所以每個功能的命令行幫助被放置在不同的地方。因此,對于新手來說,在初次使用任意一個功能時,幫助都不是那么顯而易見。
      如果你僅傳遞一個 -h 選項,你將看到 Selenium-RC Server 的可選項而不是 Selenium-Grid 的。
      java -jar selenium-server-standalone-2.21.0.jar -h
      上述代碼將顯示 Selenium-RC server 選項。如果你想看到 Selenium-Grid 的命令行幫助,你需要先使用 -hub 或 -node 選項告訴 Selenium-Server 你想看的是關于 Selenium-Grid 的,然后再追加 -h 選項。
      java -jar selenium-server-standalone-2.21.0.jar -role node -h
      對于這個問題,你還可以給 -role node 傳遞一個垃圾參數:
      java -jar selenium-server-standalone-2.21.0.jar -role node xx
      你將先看到 “INFO...” 和一個 “ERROR”,在其后你將看到 Selenium-Grid 的命令行選項。我們沒有列出這個命令的所有輸出,因為它實在太長了,這個輸出的最初幾行看起來如下:
    Jul 19, 2012 10:10:39 AM org.openqa.grid.selenium.GridLauncher main
    INFO: Launching a selenium grid node
    org.openqa.grid.common.exception.GridConfigurationException: You need to specify a hub to register to using -hubHost X -hubPort 5555. The specified config was -hubHost null -hubPort 4444
    at org.openqa.grid.common.RegistrationRequest.validate(RegistrationRequest.java:610)
    at org.openqa.grid.internal.utils.SelfRegisteringRemote.startRemoteServer(SelfRegisteringRemote.java:88)
    at org.openqa.grid.selenium.GridLauncher.main(GridLauncher.java:72)
    Error building the config :You need to specify a hub to register to using -hubHost X -hubPort 5555. The specified config was -hubHost null -hubPort 4444
    Usage :
    -hubConfig:
    (hub) a JSON file following grid2 format.
    -nodeTimeout:
    (node) <XXXX>  the timeout in seconds before the hub
    automatically ends a test that hasn't had aby activity than XX
    sec.The browser will be released for another test to use.This
    typically takes care of the client crashes.
      常見錯誤
      Unable to acess the jarfile
      Unable to access jarfile selenium-server-standalone-2.21.0.jar
      無論是啟動中心還是節點都有可能產生這個錯誤。這意味著 java 無法找到 selenium-server jar 包。你需要從 selenium-server-XXXX.jar 文件存放在目錄運行命令或者指定 jar 包的完整路徑。

    posted @ 2014-11-06 10:03 順其自然EVO 閱讀(4555) | 評論 (0)編輯 收藏

    Web測試方面的知識點整理

    軟件測試體系架構設計
      一、體系架構
      1.C/S:客戶端+服務器端,如QQ、單機版記事本、office等,所用語言:VB、C++、C、C#、JAVA、PB、D…等數組語言,C和S都是自己測,且復雜度較高。擴展性差。
      補:軟件質量包括五種質量:內部質量、外部質量、過程質量、使用質量、情感質量(從使用質量提取出來的,易用性的、用戶體驗的老師稱為情感質量)。
      B/S:瀏覽器+服務器,S如tomcat、IIS,所用語言:HTML、ASP、PHP、JSP等腳本語言,B和S都是成熟的產品,不需測。范圍廣。擴展性好,便于用戶訪問,但是安全性較差。可看到后綴,根據后綴知道其架構,即知道什么語言開發,可能使用的服務器是什么,可能使用的數據庫是什么,可能使用的服務器的操作系統是什么。便于測試。
      機房包括:HTTP(只做請求的轉發,不做請求的具體處理,做負載均衡的)、Web Server(網絡服務)、APP Server(應用服務)、DB Server(數據庫服務器)。
      嵌入式應用系統:如投影儀,里面裝有數控類的代碼,也是程序,對其需用模擬器來進行測試,稱為嵌入式系統。
      如今很多企業都是C/S和B/S合并起來做,核心關鍵的用B/S做,對外公布的用C/S做,兩者之間留接口即可。涉及軍工類的都是C/S架構。
      2.web服務器:在B/S架構開發平臺:J2EE(Java開發,包括:J2EE企業級,是C/S系統;J2ME微型平臺,是嵌入式系統;J2SE標準平臺,是桌面型系統、.net(C#,微軟開發,是站點開發,應用于電子商務)、LAMP(php開發,Linux+Apache+MySQL+php)
      Windows:后臺C#,  前臺ASP/ASP.NET
      SUN:    后臺Java,前臺jsp
      常用的web服務器:Apache、Tomcat、IIS、jboss、Resin、weblogic、WebSphere
      3.DB Server數據庫服務器:全部基于SQL語言(結構化查詢語言),包括:MySQL、SQLServer、Oracle、Sybase、DB2(后三者過了安全認證即五星認證,較厲害)
      只能在windows上運行,沒有絲毫的開放性,操作系統的穩定對數據庫是十分重要的。Windows9X系列產品是偏重于桌面應用,NT server只適合中小型企業。而且windows平臺的可靠性,安全性和伸縮性是非常有限的。它不象unix那樣久經考驗,尤其是在處理大數據庫。
      并行實施和共存模型并不成熟,很難處理日益增多的用戶數和數據卷,伸縮性有限。
      沒有獲得任何安全證書。
    多用戶時性能不佳
      C/S結構,只支持windows客戶,可以用ADO、DAO、OLEDB、ODBC連接。
      操作簡單,但只有圖形界面。
      完全重寫的代碼,經歷了長期的測試,不斷延遲,許多功能需要時間來證明。并不十分兼容。
      Oracle
      能在所有主流平臺上運行(包括 windows)。完全支持所有的工業標準。采用完全開放策略。可以使客戶選擇最適合的解決方案。對開發商全力支持。
      并行服務器通過使一組結點共享同一簇中的工作來擴展windownt的能力,提供高可用性和高伸縮性的簇的解決方案。如果windowsNT不能滿足需要,用戶可以把數據庫移到UNIX中。Oracle的并行服務器對各種UNIX平臺的集群機制都有著相當高的集成度。
      獲得最高認證級別的ISO標準認證。
      性能最高, 保持開放平臺下的TPC-D和TPC-C的世界記錄。
      多層次網絡計算,支持多種工業標準,可以用ODBC、JDBC、OCI等網絡客戶連接。
      較復雜,同時提供GUI和命令行,在windowsNT和unix下操作相同。
      長時間的開發經驗,完全向下兼容。得到廣泛的應用。完全沒有風險。
      Sybase
      能在所有主流平臺上運行(包括 windows)。 但由于早期Sybase與OS集成度不高,因此VERSION11.9.2以下版本需要較多OS和DB級補丁。在多平臺的混合環境中,會有一定問題。
      雖然有DB SWITCH來支持其并行服務器,但DB SWITCH在技術層面還未成熟,且只支持版本12.5以上的ASE SERVER。DB SWITCH技術需要一臺服務器充當SWITCH,從而在硬件上帶來一些麻煩。
      獲得最高認證級別的ISO標準認證。
      性能接近于SQL Server,但在UNIX平臺下的并發性要優與 SQL Server。
      C/S結構,可以用ODBC、Jconnect、Ct-library等網絡客戶連接。
      較復雜,同時提供GUI和命令行。但GUI較差,常常無法及時狀態,建議使用命令行。
      向下兼容, 但是ct-library 程序不益移植。
      DB2
      能在所有主流平臺上運行(包括windows)。最適于海量數據。DB2在企業級的應用最為廣泛,在全球的500家最大的企業中,幾乎85%以上用DB2數據庫服務器,而國內到97年約占5%。
      具有很好的并行性。DB2把數據庫管理擴充到了并行的、多節點的環境。數據庫分區是數據庫的一部分,包含自己的數據、索引、配置文件、和事務日志。數據庫分區有時被稱為節點安全性。
      獲得最高認證級別的ISO標準認證。
      性能較高適用于數據倉庫和在線事物處理。
      跨平臺,多層結構,支持ODBC、JDBC等客戶。
      操作簡單,同時提供GUI和命令行,在windowsNT和unix下操作相同。
      在巨型企業得到廣泛的應用,向下兼容性好。風險小
      4.OS操作系統:Windows Server、Linux(起源于網絡,起源于Unix,開源的免費的,靠賣服務收費,如Ubuntu、Red Hat等)、Unix(一種是IBM的AIX,如中國移動;另一種是HP的HP-Unix,如中國電力。很厲害,功能很強大)。
      5.編程語言:基于B/S架構,
      .html、.htm、.dhtml、.shtml:超文本標記語言HTML,靜態頁面設計,web服務器所有都行,Apache、Tomcat、IIS、JBoss、Resin、WebLogic、WebSphere
      .jsp、.do、.js、.css:J2EE、Java、Jsp,動態頁面設計,Web服務器包括Tomato、JBoss、WebLogic、Resin、WebSphere,所有數據庫都行,不區分系統平臺
      .asp、.aspx:.net、C#、.asp,動態頁面設計,WEB服務器包括IIS或IIS+Apache,Apache跟什么服務器都可以配,是解析靜態的,數據庫是SQLServer,應用于Windows server平臺
      .php:LAMP/WAMP,動態頁面設計,Linux+Apache+MySQL+PHP解析器/Windows server+Apache+MySQL+PHP解析器
      二、為什么Java語言一次編譯到處運行?
      .java經過JRE編譯(Javac)運行,放到JVM跑,生成.class字節碼文件
      以下三者統一稱JDK:
      JDK(Java develop kit)Java開發平臺,庫函數、類文件
      JRE(Java Run Environment)Java運行環境
      JVM(Java Virtual Machine)Java虛擬機
      將.java編譯成.class文件,運行.class文件,跟平臺無關。
      三、HTTP狀態碼:(性能測試)
      200:服務器響應正確
      403:連接被限制
      404:不存在
      500:服務器處理錯誤
      四、搭建JDK+Tomcat,參見“Windows測試環境搭建手冊.doc”
      五、HTML語言:參見“HTML開發基礎.pptx”
      HTML表單的兩種提交方式(method):
      get:小數據,不加密
      post:大數據,加密

    posted @ 2014-11-06 10:01 順其自然EVO 閱讀(217) | 評論 (0)編輯 收藏

    karma作為jQuery單元測試Runner

    karma作為angular測試runner出現,如果你使用過karma一定感受到這很不錯的javascript測試runner。簡單干凈的配置文件karma.config.js,以及karma init一些快捷的配置command。以及整套測試套件,如html2js,coverage。對于angular單元測試karma就是一個全生態的測試套件,能夠簡潔快速的搭建整個測試流程。
      本文將嘗試運用karma作為jQuery單元測試runner。對于jQuery這種DOM操作的框架,有時難于分離view邏輯,以及ajax這種外部資源的mock,所以比較難于實施對jQuery程序的TDD開發。
      jasmime測試套件
      對于jasmine測試框架為了解決這些問題有兩個插件jasmine-jquery和jasmine-ajax。
      jasmine-jquery
      jasmine-jQuery主要解決加載測試所需的DOM元素,為單元測試構建前置環境。jasmine-jQuery加載DOM方法:
      jasmine.getFixtures().fixturesPath = 'base path';
      loadFixtures('myfixture.html');
      jasmine.getFixtures().load(...);
      這里的loadFixtures需要真實ajax獲取html fixtures所以我們需要提前host html fixtures。jasmine-jQuery還框架了一些有用的matchers,如toBeChecked, toBeDisabled, toBeFocused,toBeInDOM……
      jasmine-ajax
      jasmine-ajax則是對于一般ajax測試的mock框架,其從底層xmlhttprequest實施mock。所以讓我們能很容易實施對于jQuery的$.ajax,$.get…mock。如
    beforeEach(function() {
    jasmine.Ajax.requests.when = function (url) {
    return this.filter("/jquery/ajax")[0];
    };
    jasmine.Ajax.install();
    });
    it("jquery ajax success with getResponse", function() {
    var result;
    $.get("/jquery/ajax").success(function(data) {
    result = data;
    });
    jasmine.Ajax.requests.when("/jquery/ajax").response({
    "status": 200,
    "contentType": 'text/plain',
    "responseText": 'data from mock ajax'
    });
    expect(result).toEqual('data from mock ajax');
    });
    afterEach(function() {
    jasmine.Ajax.uninstall();
    });
      對于jasmine-ajax是實施mock之前一定需要jasmine.Ajax.install(),以及測試完成后需要jasmine.Ajax.uninstall();jasmine-ajax在install后會把所有的ajax mock掉,所以如果有需要真實ajax的需要在install之前完成,如jasmine-jQuery加載view loadFixtures。
     運用karma runner
      我們已經了解了jasmine測試的兩個框架jasmine-jQuery和jasmine-ajax,所以運用karma作為runner,我們需要解決的問題就是把他們和karma集成在一起。
      所以分為以下幾步: 1:karma中引入jasmine-jQuery和jasmine-ajax(可以利用bowerinstall) 2:host 測試的html fixtures。 3:加載html fixtures 與install ajax之前。
      對于host 文件karma提供了pattern模式,所以karma配置為:
    files: [
    {
    pattern: 'view/**/*.html',
    watched: true,
    included: false,
    served: true
    },
    'bower_components/jquery/dist/jquery.js',
    'bower_components/jasmine-jquery/lib/jasmine-jquery.js',
    'bower_components/jasmine-ajax/lib/mock-ajax.js',
    'src/*.js',
    'test/*.js'
    ],
      這里需要注意karma自帶的jasmine是低版本的,所以我們需要npm install karma-jasmine@2.0獲取最新的karma-jasmine插件。
      我們就可以完成了karma的配置,我們可以簡單測試我們的配置:demo on github.
      測試html fixtures加載:
    describe('console html content', function() {
    beforeEach(function() {
    jasmine.getFixtures().fixturesPath = 'base/view/';
    loadFixtures("index.html");
    });
    it('index html', function() {
    expect($("h2")).toBeInDOM();
    expect($("h2")).toContainText("this is index page");
    });
    })
        測試mock ajax:
    describe('console html content', function() {
    beforeEach(function() {
    jasmine.Ajax.requests.when = function(url) {
    return this.filter("/jquery/ajax")[0];
    };
    jasmine.Ajax.install();
    });
    it('index html', function() {
    expect($("h2")).toBeInDOM();
    expect($("h2")).toContainText("this is index page");
    });
    it("ajax mock", function() {
    var doneFn = jasmine.createSpy("success");
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function(args) {
    if (this.readyState == this.DONE) {
    doneFn(this.responseText);
    }
    };
    xhr.open("GET", "/some/cool/url");
    xhr.send();
    expect(jasmine.Ajax.requests.mostRecent().url).toBe('/some/cool/url');
    expect(doneFn).not.toHaveBeenCalled();
    jasmine.Ajax.requests.mostRecent().response({
    "status": 200,
    "contentType": 'text/plain',
    "responseText": 'awesome response'
    });
    expect(doneFn).toHaveBeenCalledWith('awesome response');
    });
    it("jquery ajax success with getResponse", function() {
    var result;
    getResponse().then(function(data){
    result = data;
    });
    jasmine.Ajax.requests.when("/jquery/ajax").response({
    "status": 200,
    "contentType": 'text/plain',
    "responseText": 'data from mock ajax'
    });
    expect(result).toEqual('data from mock ajax');
    });
    it("jquery ajax error", function() {
    var status;
    $.get("/jquery/ajax").error(function(response) {
    status = response.status;
    });
    jasmine.Ajax.requests.when("/jquery/ajax").response({
    "status": 400
    });
    expect(status).toEqual(400);
    });
    afterEach(function() {
    jasmine.Ajax.uninstall();
    });
    })

    posted @ 2014-11-06 09:58 順其自然EVO 閱讀(324) | 評論 (0)編輯 收藏

    Selenium IDE的第一個測試用例

     一周時間過去了,斷斷續續學習selenium也有幾個小時了;今天細想一下學習效率不高的原因在哪,總結出以下幾點:
      1、求“進”心切——總想一步到位,搭建好環境,開始動手寫用例。
      2、學習深度不夠——同樣想著快速瀏覽一遍某大神、高手的日志,教程什么的很立即動手復制,其實很多基礎環境不一樣,無法全部照搬。
      3、學習時間太少——這個是最為關鍵的點,統計一下,一周下來,花在學習Selenium上的時間不過3-5小時,而且時間分布在12點到2點之間,效率也最低下。
      兩天前弄出來的SELENIUM IDE for firefox已經可以進行錄制回放功能,做一些最為簡單的單線流程錄制。但一直無法將用例轉換的JAVA代碼編譯通過,報錯也無法定位與解決,被阻塞了兩天時間 。
      Java for selenium 做WEB測試應具有的知識體系,大致如下(自己感受):
      1、JAVA基礎,與JUnit(不了解)
      2、selenium的JAVA API及selenium基本知識(摸不著北)
      3、測試基礎與WEB前端技術
      通過分析上述的幾點要求后,發現自己在基礎上還是非常薄弱,不能一味的追求快;而是需要一邊夯實基礎、一邊開闊視野、一邊提升;推動整體向前進步。
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head profile="http://selenium-ide.openqa.org/profiles/test-case">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link rel="selenium.base" />
    <title>hyddd</title>
    </head>
    <body>
    <table cellpadding="1" cellspacing="1" border="1">
    <thead>
    <tr><td rowspan="1" colspan="3">hyddd</td></tr>
    </thead><tbody>
    <tr>
    <td>open</td>
    <td>/</td>
    <td></td>
    </tr>
    <tr>
    <td>click</td>
    <td>id=kw1</td>
    <td></td>
    </tr>
    <tr>
    <td>type</td>
    <td>id=kw1</td>
    <td>hyddd</td>
    </tr>
    <tr>
    <td>click</td>
    <td>id=su1</td>
    <td></td>
    </tr>
    </tbody></table>
    </body>
    </html>
    English »
     
    Text-to-speech function is limited to 100 characters

    posted @ 2014-11-06 09:56 順其自然EVO 閱讀(661) | 評論 (0)編輯 收藏

    并發時-修改Linux系統下的最大文件描述符限制

     通常我們通過終端連接到linux系統后執行ulimit -n 命令可以看到本次登錄的session其文件描述符的限制,如下:
      $ulimit -n
      1024
      當然可以通過ulimit -SHn 102400 命令來修改該限制,但這個變更只對當前的session有效,當斷開連接重新連接后更改就失效了。
      如果想永久變更需要修改/etc/security/limits.conf 文件,如下:
      vi /etc/security/limits.conf
      * hard nofile 102400
      * soft nofile 102400
      保存退出后重新登錄,其最大文件描述符已經被永久更改了。
      這只是修改用戶級的最大文件描述符限制,也就是說每一個用戶登錄后執行的程序占用文件描述符的總數不能超過這個限制。
      系統級的限制
      它是限制所有用戶打開文件描述符的總和,可以通過修改內核參數來更改該限制:
      sysctl -w fs.file-max=102400
      使用sysctl命令更改也是臨時的,如果想永久更改需要在/etc/sysctl.conf添加
      fs.file-max=102400
      保存退出后使用sysctl -p 命令使其生效。
      與file-max參數相對應的還有file-nr,這個參數是只讀的,可以查看當前文件描述符的使用情況。
      直接修改內核參數,無須重啟系統。
      sysctl -w fs.file-max 65536
      或者
      echo "65536" > /proc/sys/fs/file-max
      兩者作用是相同的,前者改內核參數,后者直接作用于內核參數在虛擬文件系統(procfs, psuedo file system)上對應的文件而已。
      可以用下面的命令查看新的限制
      sysctl -a | grep fs.file-max
      或者
      cat /proc/sys/fs/file-max
      修改內核參數
      /etc/sysctl.conf
      echo "fs.file-max=65536" >> /etc/sysctl.conf
      sysctl -p
      查看當前file handles使用情況:
      sysctl -a | grep fs.file-nr
      或者
      cat /proc/sys/fs/file-nr
      825 0 65536
      另外一個命令:
      lsof | wc -l
      下面是摘自kernel document中關于file-max和file-nr參數的說明
    file-max & file-nr:
    The kernel allocates file handles dynamically, but as yet it doesn't free them again.
    內核可以動態的分配文件句柄,但到目前為止是不會釋放它們的
    The value in file-max denotes the maximum number of file handles that the Linux kernel will allocate. When you get lots of error messages about running out of file handles, you might want to increase this limit.
    file-max的值是linux內核可以分配的最大文件句柄數。如果你看到了很多關于打開文件數已經達到了最大值的錯誤信息,你可以試著增加該值的限制
    Historically, the three values in file-nr denoted the number of allocated file handles, the number of allocated but unused file handles, and the maximum number of file handles. Linux 2.6 always reports 0 as the number of free file handles -- this is not an error, it just means that the number of allocated file handles exactly matches the number of used file handles.
    在kernel 2.6之前的版本中,file-nr 中的值由三部分組成,分別為:1.已經分配的文件句柄數,2.已經分配單沒有使用的文件句柄數,3.最大文件句柄數。但在kernel 2.6版本中第二項的值總為0,這并不是一個錯誤,它實際上意味著已經分配的文件句柄無一浪費的都已經被使用了

    posted @ 2014-11-04 10:26 順其自然EVO 閱讀(474) | 評論 (0)編輯 收藏

    ADO存取數據庫時如何分頁顯示

    《動態網站設計十八般武藝 --ASP 篇》一文從第一期至今已和朋友們一起度過了大半個年頭,相信通過在這一段時間中的學習、實踐到再學習、再實踐,大家已經能夠熟練運用 ASP 的內建對象、 ActiveX 組件去編寫一些基本的 ASP 應用程序。從我收到的朋友們的來信中可以明顯的感覺到,大家的 ASP 功力正不斷地提升。最近很多朋友來信希望我寫一些 ASP 在現實運用中的實例。因此,從本期開始我決定將《動態網站設計十八般武藝 --ASP 篇》的定位從介紹和學習 ASP 基礎知識轉向到 ASP 實際運行的探討和深化。應朋友們的要求,在本期中我將給大家著重談一談“ADO 存取數據庫時如何分頁顯示”的問題。
      什么是 ADO 存取數據庫時的分頁顯示?如果你使用過目前眾多網站上的電子公告板程序的話,那你應該會知道電子公告板程序為了提高頁面的讀取速度,一般不會將所有的帖子全部在一頁中羅列出來,而是將其分成多頁顯示,每頁顯示一定數目的帖子數,譬如 20 條。這就是數據庫查詢的分頁顯示,如果你還不明白,去看看 yahoo 等搜索引擎的查詢結果就會明白了。
      那么究竟如何才能做到將數據庫的查詢結果分頁顯示呢?其實方法有很多,但主要有兩種:
      一、將數據庫中所有符合查詢條件的記錄一次性的都讀入 recordset 中,存放在內存中,然后通過 ADO Recordset 對象所提供的幾個專門支持分頁處理的屬性: PageSize( 頁大小 )、 PageCount( 頁數目 ) 以及 AbsolutePage( 絕對頁 ) 來管理分頁處理。
      二、根據客戶的指示,每次分別從符合查詢條件的記錄中將規定數目的記錄數讀取出來并顯示。
      兩者的主要差別在于前者是一次性將所有記錄都讀入內存然后再根據指示來依次做判斷分析從而達到分頁顯示的效果,而后者是先根據指示做出判斷并將規定數目的符合查詢條件的記錄讀入內存,從而直接達到分頁顯示的功能。
      我們可以很明顯的感覺到,當數據庫中的記錄數達到上萬或更多時,第一種方法的執行效率將明顯低于第二種方法,因為當每一個客戶查詢頁面時都要將所有符合條件的記錄存放在服務器內存中,然后在進行分頁等處理,如果同時有超過 100 個的客戶在線查詢,那么 ASP 應用程序的執行效率將大受影響。但是,當服務器上數據庫的記錄數以及同時在線的人數并不是很多時,兩者在執行效率上是相差無幾的,此時一般就采用第一種方法,因為第一種方法的 ASP 程序編寫相對第二種方法要簡單明了得多。
      在這里作者就以我們常見的 ASP BBS 程序為例,來給大家分析一下如何在 BBS 程序里實現分頁顯示功能,由于我們一般使用的 BBS 程序的數據庫記錄數和同時訪問的人數都不會太多,所以以下程序實例是使用的先前所介紹的第一種分頁顯示方法。
      進行 ADO 存取數據庫時的分頁顯示,其實就是對 Recordset 的記錄進行操作。所以我們首先必須了解 Reordset 對象的屬性和方法:
      BOF 屬性:目前指標指到 RecordSet 的第一筆。
      EOF 屬性:目前指標指到 RecordSet 的最后一筆。
      Move 方法:移動指標到 RecordSet 中的某一條記錄。
      AbsolutePage 屬性:設定當前記錄的位置是位于哪一頁 AbsolutePosition 屬性:目前指標在 RecordSet 中的位置。
      PageCount 屬性:顯示 Recordset 對象包括多少“頁”的數據。
      PageSize 屬性:顯示 Recordset 對象每一頁顯示的記錄數。
      RecordCount 屬性:顯示 Recordset 對象記錄的總數。
      下面讓我們來詳細認識一下這些重要的屬性和方法
      一、 BOF 與 EOF 屬性
      通常我們在 ASP 程序中編寫代碼來檢驗 BOF 與 EOF 屬性,從而得知目前指標所指向的 RecordSet 的位置,使用 BOF 與 EOF 屬性,可以得知一個 Recordset 對象是否包含有記錄或者得知移動記錄行是否已經超出該 Recordset 對象的范圍。
      如:
      < % if not rs.eof then ... %>
      < % if not (rs.bof and rs.eof) %>
      若當前記錄的位置是在一個 Recordset 對象第一行記錄之前時, BOF 屬性返回 true,反之則返回 false。
      若當前記錄的位置是在一個 Recordset 對象最后一行記錄之后時, EOF 屬性返回 true,反之則返回 false。
      BOF 與 EOF 都為 False:表示指標位于 RecordSet 的當中。
      BOF 為 True:目前指標指到 RecordSet 的第一筆記錄。 EOF 為 True:目前指標指到 RecordSet 的最后一筆記錄。
      BOF 與 EOF 都為 True:在 RecordSet 里沒有任何記錄。
      二、 Move 方法
      您可以用 Move 方法移動指標到 RecordSet 中的某一筆記錄,語法如下:
      rs.Move NumRecords,Start
      這里的“rs”為一個對象變量,表示一個想要移動當當前記錄位置的 Recordset 對象;“NumRecords”是一個正負數運算式,設定當前記錄位置的移動數目;“start”是一個可選的項目,用來指定記錄起始的標簽。
      所有的 Recordset 對象都支持 Move 方法,如果 NumRecords 參數大于零,當前記錄位置向末尾的方向移動;如果其小于零,則當前記錄位置向開頭的方向移動;如果一個空的 Recordset 對象調用 Move 方法,將會產生一個錯誤。
      MoveFirst 方法:將當前記錄位置移至第一筆記錄。
      MoveLast 方法:將當前記錄位置移至最后一筆記錄。
      MoveNext 方法:將當前記錄位置移至下一筆記錄。 MovePrevious 方法:將當前記錄位置移至上一筆記錄。
      Move [n] 方法:移動指標到第 n 筆記錄, n 由 0 算起。
      三、 AbsolutePage 屬性
      AbsolutePage 屬性設定當前記錄的位置是位于哪一頁的頁數編號;使用 PageSize 屬性將 Recordset 對象分割為邏輯上的頁數,每一頁的記錄數為 PageSize( 除了最后一頁可能會有少于 PageSize 的記錄數 )。這里必須注意并不是所有的數據提供者都支持此項屬性,因此使用時要小心。
      與 AbsolutePosition 屬性相同, AbsolutePage 屬性是以 1 為起始的,若當前記錄為 Recordset 的第一行記錄, AbsolutePage 為 1。可以設定 AbsolutePage 屬性,以移動到一個指定頁的第一行記錄位置。
    四、 AbsolutePosition 屬性
      若您需要確定目前指標在 RecordSet 中的位置,您可以用 AbsolutePosition 屬性。
      AbsolutePosition 屬性的數值為目前指標相對於第一筆的位置,由 1 算起,即第一筆的 AbsolutePosition 為 1。
      注意 , 在存取 RecordSet 時,無法保證 RecordSet 每次都以同樣的順序出現。
      若要啟用 AbsolutePosition,必須先設定為使用用戶端 cursor( 指針 ), asp 碼如下:
      rs2.CursorLocation = 3
      五、 PageCount 屬性
      使用 PageCount 屬性,決定 Recordset 對象包括多少“頁”的數據。這里的“頁”是數據記錄的集合,大小等于 PageSize 屬性的設定,即使最后一頁的記錄數比 PageSize 的值少,最后一頁也算是 PageCount 的一頁。必須注意也并不是所有的數據提供者都支持此項屬性。
      六、 PageSize 屬性
      PageSize 屬性是決定 ADO 存取數據庫時如何分頁顯示的關鍵,使用它就可以決定多少記錄組成一個邏輯上的“一頁”。設定并建立一個頁的大小,從而允許使用 AbsolutePage 屬性移到其它邏輯頁的第一條記錄。 PageSize 屬性能隨時被設定。
      七、 RecordCount 屬性
      這也是一個非常常用和重要的屬性,我們常用 RecordCount 屬性來找出一個 Recordset 對象包括多少條記錄。如: < % totle=RS.RecordCount %>
      在了解了 Recordset 對象的以上屬性和方法后,我們來考慮一下,如何運用它們來達到我們分頁顯示的目的。首先,我們可以為 PageSize 屬性設置一個值,從而指定從記錄組中取出的構成一個頁的行數;然后通過 RecordCount 屬性來確定記錄的總數;再用記錄總數除以 PageSize 就可得到所顯示的頁面總數;最后通過 AbsolutePage 屬性就能完成對指定頁的訪問。好象很并不復雜呀,下面讓我們來看看程序該如何實現呢?{上海治療陽痿醫院}
      我們建立這樣一個簡單的 BBS 應用程序,它的數據庫中分別有以下五個字段:“ID”,每個帖子的自動編號;“subject”,每個帖子的主題;“name”,加帖用戶的姓名; “email”,用戶的電子郵件地址;“postdate”,加帖的時間。數據庫的 DSN 為“bbs”。我們將顯示帖子分頁的所有步驟放在一個名為“ShowList()”的過程中,方便調用。程序如下:
      \'----BBS 顯示帖子分頁----
    < % Sub ShowList() %>
    < %
    PgSz=20 \'設定開關,指定每一頁所顯示的帖子數目,默認為20帖一頁
    Set Conn = Server.CreateObject("ADODB.Connection")
    Set RS = Server.CreateObject("ADODB.RecordSet")
    sql = "SELECT * FROM message order by ID DESC"
    \'查詢所有帖子,并按帖子的ID倒序排列
    Conn.Open "bbs"
    RS.open sql,Conn,1,1
    If RS.RecordCount=0 then
    response.write "< P>< center>對不起,數據庫中沒有相關信息!< /center>< /P>"
    else
    RS.PageSize = Cint(PgSz) \'設定PageSize屬性的值
    Total=INT(RS.recordcount / PgSz * -1)*-1 \'計算可顯示頁面的總數
    PageNo=Request("pageno")
    if PageNo="" Then
    PageNo = 1
    else
    PageNo=PageNo+1
    PageNo=PageNo-1
    end if
    ScrollAction = Request("ScrollAction")
    if ScrollAction = " 上一頁 " Then
    PageNo=PageNo-1
    end if
    if ScrollAction = " 下一頁 " Then
    PageNo=PageNo+1
    end if
    if PageNo < 1 Then
    PageNo = 1
    end if
    n=1
    RS.AbsolutePage = PageNo
    Response.Write "< CENTER>"
    position=RS.PageSize*PageNo
    pagebegin=position-RS.PageSize+1
    if position < RS.RecordCount then
    pagend=position
    else
    pagend= RS.RecordCount
    end if
    Response.Write "< P>< font color=\'Navy\'>< B>數據庫查詢結果:< /B>"
    Response.Write "(共有"&RS.RecordCount &"條符合條件的信息,顯示"&pagebegin&"-"&pagend&")< /font>< /p>"
    Response.Write "< TABLE WIDTH=600 BORDER=1 CELLPADDING=4 CELLSPACING=0 BGCOLOR=#FFFFFF>"
    Response.Write "< TR BGCOLOR=#5FB5E2>< FONT SIZE=2>< TD>< B>主題< /B>< /TD>< TD>< B>用戶< /B>< /TD>< TD>< B>Email< /B>< /TD>< TD>< B>發布日期< /B>< /TD>< /FONT>< TR BGCOLOR=#FFFFFF>"
    Do while not (RS is nothing)
    RowCount = RS.PageSize
    Do While Not RS.EOF and rowcount >0
    If n=1 then
    Response.Write "< TR BGCOLOR=#FFFFFF>"
    ELSE
    Response.Write "< TR BGCOLOR=#EEEEEE>"
    End If
    n=1-n %>
    < TD>< span style="font-size:9pt">< A href=\'view.asp?key=< % =RS("ID")%>\'>< % =RS("subject")%>< /A>< /span>< /td>
    < TD>< span style="font-size:9pt">< % =RS("name")%>< /A>< /span>< /td>
    < TD>< span style="font-size:9pt">< a href="mailto:&lt; % =RS("email")%>">< % =RS("email")%>< /a>< /span>< /TD>
    < TD>< span style="font-size:9pt">< % =RS("postdate")%>< /span>< /td>
    < /TR>
    < %
    RowCount = RowCount - 1
    RS.MoveNext
    Loop
    set RS = RS.NextRecordSet
    Loop
    Conn.Close
    set rs = nothing
    set Conn = nothing
    %>
    < /TABLE>
    < FORM METHOD=GET ACTION="list.asp">
    < INPUT TYPE="HIDDEN" NAME="pageno" VALUE="< % =PageNo %>">
    < %
    if PageNo >1 Then
    response.write "< INPUT TYPE=SUBMIT NAME=\'ScrollAction\' VALUE=\' 上一頁 \'>"
    end if
    if RowCount = 0 and PageNo < >Total then
    response.write "< INPUT TYPE=SUBMIT NAME=\'ScrollAction\' VALUE=\' 下一頁 \'>"
    end if
    response.write "< /FORM>"
    End if
    %>
    < % End Sub %>
      相信大家都應該能完全讀懂上面的程序,因此作者就不在此詳細解釋了。值得注意的是在這段程序中運用了一個小技巧
      < INPUT TYPE="HIDDEN" NAME="pageno" VALUE="< % =PageNo %>">
      ,這是用來在每次調用該 ASP 文件時傳遞數據的“暗道”,由于我們需要在每次調用程序時傳遞代表當前頁碼的參數,可能大家會想到使用 session,但是從節省系統資源和通用性來講,用這樣一個隱藏的 form 來傳遞數據將會達到更好的效果。
      好了,又到了說再見的時候了,如果你沒完全看懂本篇中所列的程序,那你必須加把油,看一看 VbScript 的語法;

    posted @ 2014-11-04 10:25 順其自然EVO 閱讀(323) | 評論 (0)編輯 收藏

    一次關于使用status作為變量引發的bug及思考

     這個bug出現在一年前,當時自己大學還沒畢業,剛剛進入一家公司實習。那個時候還沒有用seajs或者requirejs那樣的模塊化管理的庫,也沒有用一個自執行的函數將要執行的代碼包裹起來,于是bug就在這樣的一個場景下誕生了。當時自己定位了比較久,也不知道status是window下的一個屬性,所以請了高手幫忙定位,高手也是定位了半天才定位出來,只是湊巧將status換了一個名字就正常了,后來我問高手原因,他當時也答不出來,后來就一直沒管它了,也忘記了。就在前幾天,群里有人在討論一些bug以及要注意的一些坑,我突然想起了一年前自己遇到過的坑,于是提了出來,在各位高手的討論下終于搞懂了這個bug出現的原因以及原理,于是記錄下,方便那些跟我一樣做開發的同學能夠繞過這些坑,少走彎路。
      1.場景再現(為了方便最簡化代碼,當時的情景不像下面這么直白的提示錯誤):
      咦,為什么這里status是一個數組,為什么會提示它沒有push函數呢,這到底是為什么呢?這個bug對于當時初出茅廬的我來說簡直就是一個大挑戰,那個時候對調試還不熟,看到bug那個小心臟頓時就有點受不了了,緊張啊,抓狂啊隨之而來。因為當時代碼量比較多,所以當時不能一下子定位到這里的問題。
      2.討論
      我們看到就因為變量名不同,卻一個出錯一個正常,難道不能將一個數組賦值給status嗎?
      我們看到將一個數組賦值給status是完全沒有問題的,它是數組類型。既然是數組為什么就沒有push方法呢?這個時候我們不防打印下status的類型
      我們看到我們將一個數組賦值給status,按理說應該是object類型,可是這里卻是string類型,string類型沒有push方法,這時我們對于為什么報錯就沒有那么疑惑了。按這樣理解的話,就是在給status賦值時確實是將一個數組賦給了它,但是就是在讀取status時瀏覽器強制將status轉化成了字符串。我們不防在chrome控制臺看看。
      看來我們的猜測是對的,賦值成功,在取值的時候將status強制轉化為了字符串,那要是將一個對象賦值給status在讀取status的時候是不是也會將status轉化為json格式的字符串呢?
      我們看到,瀏覽器并沒有按我們的預期將它轉化為一個json格式的字符串,而是轉化為[object Object]這樣的東東,這不是我們經常用來判斷變量的類型嗎?一般我們會調用Object.prototype.toString.call(變量)來查看變量類型,因為使用typeof太不靠譜。于是我們猜到在將status轉化為字符串的時候是調用了toString方法。

     難道status只能是字符串嗎?想想status當初設計出來的初衷,它就是為了臨時在狀態欄展示一些用戶信息,所以必須是字符串。這樣理解的話就順理成章了。
      所以我們看到使用status來定義變量是不可行的,除非定義的status是string類型,但是有的人就說,經常用status,沒啥問題啊。
      看,用得挺好的,妥妥的啊。
      我們再來看另外一種情況。
      xx,報錯了,咋回事?在項目中,由于我們的疏忽,有時候定義的變量忘記寫var關鍵字都是時常有的事,在一個代碼量很龐大的應用中,定位這樣的一個bug肯定需要花費不少時間,而且很容易讓人抓狂。
      上面那種情況將一個數組賦值給status并調用push方法為啥不出錯,這里就涉及到javascript變量作用域的問題了,因為一個自執行函數就是一個作用域,系統在查找這個變量時是先在這個作用域內進行查找,找不到就往上一層作用域中查找,直到作用域的最前端,沒有找到就報錯提示變量is not defined。這里因為在當前作用域中申明了變量status,所以不會去window環境下去查找status變量,所以是ok的,但是下面這種情況因為沒有使用var進行變量的申明,所以status就會成為window下的變量,而status又是window下的一個固有屬性,取值的時候只能是string類型,從而沒有push方法,最終報錯。
      所以,為了不給自己制造那么多麻煩,在定義變量時應該盡量避免使用javascript中的關鍵字、保留字和window下的固有屬性進行命名,這些都是坑,實際項目中應該多注意避免。
      從以上分析中,我們看到全局的status可以設置,但是讀取的時候卻調用了toSting方法返回了字符串,這里我們可以利用es5提供的Object.defineProperty來模擬一下這種行為。代碼如下:
    var a = {};
    Object.defineProperty(a, 'm', (function () {
    var _a = 'xx';
    return {
    get : function () {
    return _a.toString();
    },
    set : function (v) {
    _a = v;
    }
    };
    })());
      利用Object.defineProperty方法,可以對一個變量或者屬性進行監控,當直接賦值給變量的時候就會調用set方法,當直接讀取變量的時候就會將調用tostring方法將變量轉化為字符串。
      我們看到我們模擬的行為和status默認的行為一模一樣。
      一年前遇到的bug今天才豁然開朗,這讓我意識到針對任何一個小的bug都不應該放過,而要報著打破沙鍋問到底的態度去探究,這樣才可以看到別樣的風景以及讓自己更加專業。

    posted @ 2014-11-04 10:23 順其自然EVO 閱讀(239) | 評論 (0)編輯 收藏

    關于使用TestNG的retry問題

    總體是利用TestNG里面的IRetryAnalyzer、TestListenerAdapter接口來實現相關問題
      1、定義一個自己的retryanalyzer
    import org.testng.ITestResult;
    import org.testng.util.RetryAnalyzerCount;
    //這里集成自抽象類RetryAnalyzerCount,該抽象類實現了IRetryAnalyzer
    public class TestRetryAnalyzer extends RetryAnalyzerCount{
    public TestRetryAnalyzer(){
    setCount(1);
    }
    @Override
    public boolean retryMethod(ITestResult arg0) {
    // TODO Auto-generated method stub
    return true;
    }
    }
      2、定義自己的監聽器,集成自TestListenerAdapter
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    import org.testng.IResultMap;
    import org.testng.ITestContext;
    import org.testng.ITestResult;
    import org.testng.Reporter;
    import org.testng.TestListenerAdapter;
    import org.testng.ITestNGMethod;
    import org.testng.collections.Lists;
    import org.testng.collections.Objects;
    public class RetryTestListener extends TestListenerAdapter {
    private List<ITestNGMethod> m_allTestMethods =
    Collections.synchronizedList(Lists.<ITestNGMethod>newArrayList());
    private List<ITestResult> m_passedTests = Collections.synchronizedList(Lists.<ITestResult>newArrayList());
    private List<ITestResult> m_failedTests = Collections.synchronizedList(Lists.<ITestResult>newArrayList());
    private List<ITestResult> m_skippedTests = Collections.synchronizedList(Lists.<ITestResult>newArrayList());
    private List<ITestResult> m_failedButWSPerTests = Collections.synchronizedList(Lists.<ITestResult>newArrayList());
    private List<ITestContext> m_testContexts= Collections.synchronizedList(new ArrayList<ITestContext>());
    private List<ITestResult> m_failedConfs= Collections.synchronizedList(Lists.<ITestResult>newArrayList());
    private List<ITestResult> m_skippedConfs= Collections.synchronizedList(Lists.<ITestResult>newArrayList());
    private List<ITestResult> m_passedConfs= Collections.synchronizedList(Lists.<ITestResult>newArrayList());
    public synchronized void onTestFailure(ITestResult arg0) {
    m_allTestMethods.add(arg0.getMethod());
    m_failedTests.add(arg0);
    }
    @Override
    public void onFinish(ITestContext context) {
    for(int i=0;i<context.getAllTestMethods().length;i++){
    System.out.println("~~~~~~~~~~"+context.getAllTestMethods()[i].getCurrentInvocationCount());
    if(context.getAllTestMethods()[i].getCurrentInvocationCount()==2){
    System.out.println("~~~~~~~~~~~~~~~~~"+context.getAllTestMethods()[i].getParameterInvocationCount());
    System.out.println(context.getAllTestMethods()[i].ignoreMissingDependencies());
    if
    (context.getFailedTests().getResults(context.getAllTestMethods()[i]).size()
    == 2 ||
    context.getPassedTests().getResults(context.getAllTestMethods()[i]).size()
    == 1){
    context.getFailedTests().removeResult(context.getAllTestMethods()[i]);
    }
    }
    }
    }
    ...
    }

    posted @ 2014-11-04 10:22 順其自然EVO 閱讀(790) | 評論 (0)編輯 收藏

    關于Loadrunner12的測試總結

     今天做了個比較全面的測試,簡單在這里說一下吧
      1.LR12是11.52的完成版本,確實覺得整體舒服多了,用起來不是那么別扭了,有些菜單的優化還是不錯的
      2.對于win8.1和ie11支持確實很好,采用了新的證書策略,效果不錯
      3.trueclient的錄制模式還是和以前差不多
      4.對于手機端的模擬測試多了不少的平臺,包括nexus7之類的平臺也有了
      5.錄制支持chrome了,但是我用最新的33還是出現了無響應的問題,不過奇怪的是UFT12對chrome33這樣的最新版本支持的很好。
      6.提供了直接的端口代理錄制模式,用起來很方便直接修改應用的代理地址到LR配置的地址就行了,但是用IE11走代理模式出現了請求錄制成功,但返回的頁面沒有出現的情況,就是請求出去了,但是沒返回到瀏覽器中的情況,實際就是還是沒法用啊。
      7.runtime setting的這類跟蹤調試功能貌似增強了。
      總結:
      如果你已經習慣用lr11.52了,那么12還是非常值得升級的版本,確實很多地方人性了。
      如果你還是傳統用戶,個人覺得11還是一個最合適的版本,至少用起來還是比12快不少。我的虛擬機是i7 930 2X2+4G內存+raid0硬盤,應該不算很差了。
      如果某些特殊的東西實在LR11不支持,你可以試試LR12.
      如果你還不知道怎么“學習版”的話,LR12的默認50個用戶策略和可能一直免費的License,會讓你少處理很多東西。
      如果你是新學LR,個人還是建議你用老版本,因為LR12真沒啥學習資料。
      如果你是老手,用LR12就和普通的一樣,道理明白了新版本真沒啥新意。
      ps.貌似有個bug就是默認裝完了第一次用Load generator的時候系統自動選的是localhost但是其實是沒有這個負載生成機的,需要自己去列表里面添加一個再選擇了才能跑負載。

    posted @ 2014-11-04 10:21 順其自然EVO 閱讀(8475) | 評論 (2)編輯 收藏

    僅列出標題
    共394頁: First 上一頁 22 23 24 25 26 27 28 29 30 下一頁 Last 
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導航

    統計

    常用鏈接

    留言簿(55)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲av乱码一区二区三区| 牛牛在线精品观看免费正| 免费看又爽又黄禁片视频1000| 黄色a级片免费看| 国产91成人精品亚洲精品| 亚洲三级电影网站| 亚洲精品高清国产一久久| 亚洲午夜视频在线观看| 亚洲精品视频在线观看视频| 国产国拍亚洲精品福利 | 免费观看又污又黄在线观看| 精品国产日韩亚洲一区91| 美女视频黄a视频全免费网站一区 美女视频黄a视频全免费网站色 | 曰批视频免费40分钟试看天天| 男人免费视频一区二区在线观看| 色哟哟国产精品免费观看| 亚洲综合中文字幕无线码| 亚洲中文字幕久久精品蜜桃| 亚洲成a人无码亚洲成www牛牛 | 亚洲国产视频网站| 国产成人精品日本亚洲专一区| 亚洲熟妇无码一区二区三区导航| 亚洲GV天堂GV无码男同| 特级做a爰片毛片免费看| 中国人免费观看高清在线观看二区| 2020久久精品亚洲热综合一本 | 亚洲综合小说另类图片动图| 爱情岛亚洲论坛在线观看| 一个人看的www免费在线视频| 亚洲日本一线产区和二线产区对比| 在线电影你懂的亚洲| 亚洲综合偷自成人网第页色| 国产精品久久久久久亚洲小说| 国产精品极品美女自在线观看免费| 成人精品国产亚洲欧洲| 成人免费av一区二区三区| 182tv免费观看在线视频| 免费无码黄动漫在线观看| 久久影视国产亚洲| 亚洲成人午夜电影| 特黄特色大片免费|