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

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

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

    qileilove

    blog已經(jīng)轉(zhuǎn)移至github,大家請訪問 http://qaseven.github.io/

    設(shè)計報表測試(統(tǒng)計方面)用例方法總結(jié)

     一、數(shù)據(jù)統(tǒng)計方面
      1、報表統(tǒng)計數(shù)據(jù)的正確性
      1)數(shù)據(jù)的正確
      a)數(shù)據(jù)的來源:來源于哪張表,哪個字段,數(shù)據(jù)庫中的數(shù)值與界面上的一致
      b)數(shù)據(jù)的范圍:是否只顯示了報表設(shè)置的對應(yīng)范圍,如:時間選擇2012.11.01-
      2012.11.19,那么是否應(yīng)該包含1和19這天
      c)數(shù)據(jù)的對應(yīng)關(guān)系:數(shù)據(jù)庫中的字段是否與報表中的一致
      d)數(shù)據(jù)的格式:小數(shù)位、千位符,四舍五入等是否正確;單位或稅率轉(zhuǎn)換是否正確;
      組合顯示的數(shù)據(jù)是否合理
      f)數(shù)據(jù)排序是否正確
      g)流水號:如果報表使用流水號,流水號的生成和格式是否正確
      h)明細與合計的一致性:各部分明細或小節(jié)是否與最后總和一致
      2)格式正確
      a)報表的整體風(fēng)格
      b)報表標(biāo)題:報表的標(biāo)題是否是正確的報表名
      c)公司的一些標(biāo)志:如logo,名稱,地址之類的是否正確
      d)報表的頁首與頁尾:是否采用了一致的規(guī)則
      e)分頁:當(dāng)輸出的內(nèi)容多時,分頁是否正確,翻頁功能是否正確
      f)友好性:數(shù)據(jù)或圖表是否清晰,一目了然,數(shù)據(jù)的展示是否符合用戶的習(xí)慣;需要提
      醒的是數(shù)據(jù)(如合計,異常數(shù)據(jù))是否突出顯示;復(fù)雜算法處、用戶不明白或容易混
      淆處是否有注釋;一些默認(rèn)的格式是否讓人感覺舒服,如對齊、邊界、間隔等
      3)權(quán)限的控制
      a) 報表內(nèi)容:報表中的內(nèi)容不能顯示用戶根本沒有權(quán)限的數(shù)據(jù)
      b)報表的條件定義:在條件選擇區(qū)域,有些下拉框中不能顯示權(quán)限以外的數(shù)據(jù)
      2、報表統(tǒng)計數(shù)據(jù)的完整性
      3、報表統(tǒng)計數(shù)據(jù)的合法性;比如:統(tǒng)計金額字段需求要求有‘$’等
      二、報表格式
      1、表頭字段表示的正確性
      2、表頭字段表示的完整性
      3、表頭字段表示的字體、字號,美觀程度
      4、各統(tǒng)計字段的顯示是否滿足需求;比如:數(shù)據(jù)過長時要折行還是縮小
      5、頁眉和頁角的表示
      三、報表輸出界面
      1、報表排列方式可調(diào)
      2、報表標(biāo)題明確,不能含糊誤導(dǎo)用戶
      四、報表打印、預(yù)覽、導(dǎo)出

    posted @ 2014-08-22 09:37 順其自然EVO 閱讀(330) | 評論 (0)編輯 收藏

    成功恢復(fù)無備份RAC環(huán)境數(shù)據(jù)庫

    昨天,一兄弟電話求助,有一套醫(yī)院HIS數(shù)據(jù)庫無法啟動,RAC環(huán)境,無備份,嘗試過重建控制文件操作,但失敗。
      遠程連接后,情況如下:
      1.兩節(jié)點RAC,Oracle11.2.0.1版本,Linux操作系統(tǒng)
      2.recover database時提示需使用backup controlfile
      3.rman list backupset無輸出
      由于沒有記錄具體的操作,這里主要就碰到的異常做一下描述
      1.重啟數(shù)據(jù)庫,在日志中發(fā)現(xiàn)另一節(jié)點沒有被關(guān)閉,首先關(guān)閉另一節(jié)點
      2.由于控制文件已被錯誤重建,并且,溝通后認(rèn)為丟失一部分?jǐn)?shù)據(jù)是可以接受的,因此,決定重新創(chuàng)建控制文件,在創(chuàng)建控制文件時,存在一個知識點:
      RAC環(huán)境重建控制文件報錯:
      ORA-12720: operation requires database is in EXCLUSIVE mode
      這里需要修改參數(shù)文件:
      alter system set cluster_database=false scope=spfile;
      3.重建控制文件后進行恢復(fù)操作
      增加隱含參數(shù):
      alter system set "_allow_resetlogs_corruption"=true scope=spfile;
      recover database using backup controlfile until cancel;
      alter database open resetlogs;
      報錯
      ORA-00600: internal error code, arguments:  [2662]
      這個錯誤以前碰到過,需要使用event調(diào)整SCN
      首先,再增加一個隱含參數(shù):
      alter system set "_allow_error_simulation"=true scope=spfile;
      重啟重建控制文件并恢復(fù)后
      alter session set events '10015 trace name ADJUST_SCN level 10';
      alter database open;
      4.經(jīng)過上一步操作,SCN已經(jīng)OK了,但仍然報錯
      ORA-00600: internal error code, arguments:  [4194]
      4000開頭的錯誤,改UNDO為手動管理模式,修改初始化參數(shù)
      undo_management='MANUAL'
      完成啟動。
      總結(jié):
      1.這個例子,其實最開始控制文件沒有丟失,應(yīng)該先嘗試進行恢復(fù),不知道之前是不是遇到了錯誤,導(dǎo)致選擇了重建控制文件的方法。不過,這里應(yīng)該指出的是,最好不要一上來就重建控制文件。
      2.備份!備份!備份!
      感覺恢復(fù)數(shù)據(jù)庫,就像傷寒論里面說的,觀其脈證,知犯何逆,隨證治之。

    posted @ 2014-08-21 09:52 順其自然EVO 閱讀(179) | 評論 (0)編輯 收藏

    IOS推送功能的實現(xiàn)

     IOS的推送實現(xiàn)由這樣幾步來完成:
      創(chuàng)建Push SSL Certification
      IOS客戶端注冊Push功能并獲得DeviceToken
      使用Provider向APNS發(fā)送Push消息
      IOS客戶端接收處理由APNS發(fā)來的消息
      創(chuàng)建Push SSL Certification
      登錄developer.apple.com,創(chuàng)建新的App ID,要求此ID的Bundle Identifier不包含通配符,否則不能啟用Push以及IAP功能。例如 com.soso.sosoimage。
      在App IDs列表頁面,點擊剛創(chuàng)建的app id右面的Configure鏈接,進入Configure App ID界面,選中"Enable for App Push Notification service"。點擊Development Push SSL Certificate一行的Configure按鈕,彈出"Apple Push Notification service SSL Certificate Assistant"對話框,依對話框操作,類似于創(chuàng)建開發(fā)或發(fā)布用的Certificate。
      最終將Development Push SSL Certificate下載并安裝到本地Keychain Access。導(dǎo)出成p12文件,備用。導(dǎo)出時需要設(shè)置密碼,不得為空。
      在developer.apple.com,創(chuàng)建一個新的Provisioning Profile,使用我們剛剛創(chuàng)建的支持Push功能的App ID。下載并安裝到本地。
      IOS客戶端注冊Push功能并獲得DeviceToken
      創(chuàng)建本地工程,info.plist中設(shè)置Bundle identifier為剛剛創(chuàng)建的Bundle Id。Com.soso.sosoimage。設(shè)定Code Signing Identity為剛剛創(chuàng)建的Provisioning Profile。
      程序第一次執(zhí)行的時候,調(diào)用如下代碼.
      [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
      三個參數(shù)分別代表消息(橫幅或提醒,由用戶Setting決定,程序不可更改)、數(shù)字標(biāo)記、聲音。
      在AppDelegate.m中添加兩個方法.
    //iPhone 從APNs服務(wù)器獲取deviceToken后回調(diào)此方法
    - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
    {
    NSString* dt = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    NSLog(@"deviceToken:%@", dt);
    }
    //注冊push功能失敗 后 返回錯誤信息,執(zhí)行相應(yīng)的處理
    - (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err
    {
    NSLog(@"Push Register Error:%@", err.description);
    }
      獲取DeviceToken后,將其傳給Provider。
      使用Provider向APNS發(fā)送Push消息
      Provider,將推送信息發(fā)送給APNS(蘋果推送服務(wù)器)的程序。有很多開源的實現(xiàn),我們使用javapns ( http://code.google.com/p/javapns/ )。
      首先,Provider要有目標(biāo)DeviceToken,這是發(fā)送目標(biāo),由客戶端傳給Provider之后存在某處。
      安裝javapns,需要導(dǎo)入的jar為bcprov-jdk15-146.jar, log4j-1.2.15.jar, JavaPNS_2.3_Alpha_5.jar。
      將前面導(dǎo)出的P12文件放在Provider的工程目錄下。
    Provider向APNS發(fā)送消息可以參考javapns中NotificationTest.java。也可以參考如下例子。
      (1)使客戶端圖標(biāo)顯示數(shù)字標(biāo)記
      Push.badge(2, keystore, password, false, "7bb8d508e32df651c6c239439737dbd40a88d2461ad2ac1e5dbe49ecea5ccc67");
      其中,2為要顯示的數(shù)字;
      String keystore = "PushCertificates.p12";     //P12文件的路徑;
      String password = "sosoimage";                //P12文件的密碼;
      false,指的是使用測試環(huán)境,使用正式產(chǎn)品環(huán)境應(yīng)傳入true.
      "7bb8d508e32df651c6c239439737dbd40a88d2461ad2ac1e5dbe49ecea5ccc67"為客戶端獲得并傳給Provider的DeviceToken,此參數(shù)還可以傳入String[]對象,以同時向多個客戶端Push消息。
      (2)使客戶端顯示橫幅或提醒
      Provider可以向客戶端Push一條Message,但客戶端有權(quán)限決定這條Message的顯示方式(無、橫幅、提醒)。
      Push.alert("A Message", keystore, password, )false, "7bb8d508e32df651c6c239439737dbd40a88d2461ad2ac1e5dbe49ecea5ccc67");
      (3)混合方式
      可以在一個Push消息里附帶多種信息,Message, 標(biāo)記,聲音,可以使用如下代碼.
      PushNotificationPayload payload = PushNotificationPayload.complex();
      payload.addAlert("A Message");
      payload.addBadge(2);
      payload.addSound("test.aiff");
      Push.payload(payload, , keystore, password, false, "7bb8d508e32df651c6c239439737dbd40a88d2461ad2ac1e5dbe49ecea5ccc67");
      上面的代碼都有可能會有相應(yīng)的Exception拋出來,需要處理。更多的使用方式可以參考 http://code.google.com/p/javapns/
      IOS客戶端接收處理由APNS發(fā)來的消息
      (1)當(dāng)程序未啟動,用戶接收到消息。需要在AppDelegate中的didFinishLaunchingWithOptions得到消息內(nèi)容。代碼如下,
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
    ...
    NSDictionary* payload = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
    if (payload)
    {
    ...
    }
    ...
    }
      (2)當(dāng)程序在前臺運行,接收到消息不會有消息提示(提示框或橫幅)。當(dāng)程序運行在后臺,接收到消息會有消息提示,點擊消息后進入程序,AppDelegate的didReceiveRemoteNotification函數(shù)會被調(diào)用(需要自己重寫),消息做為此函數(shù)的參數(shù)傳入,代碼如下
      - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)payload
      {
      ...
      }
      (3)無論在哪個函數(shù)傳入,消息總是一個NSDictionary對象,處理方式可以參考如下代碼
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)payload
    {
    NSLog(@"remote notification: %@",[payload description]);
    NSString* alertStr = nil;
    NSDictionary *apsInfo = [payload objectForKey:@"aps"];
    NSObject *alert = [apsInfo objectForKey:@"alert"];
    if ([alert isKindOfClass:[NSString class]])
    {
    alertStr = (NSString*)alert;
    }
    else if ([alert isKindOfClass:[NSDictionary class]])
    {
    NSDictionary* alertDict = (NSDictionary*)alert;
    alertStr = [alertDict objectForKey:@"body"];
    }
    application.applicationIconBadgeNumber = [[apsInfo objectForKey:@"badge"] integerValue];
    if ([application applicationState] == UIApplicationStateActive && alertStr != nil)
    {
    UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Pushed Message" message:alertStr delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alertView show];
    }
    }
     

    posted @ 2014-08-21 09:52 順其自然EVO 閱讀(266) | 評論 (0)編輯 收藏

    簡短Javascript代碼實現(xiàn)滑動菜單效果

     整個javascript代碼共42行,其中主要函數(shù)Slide代碼26行,可以改進哦!
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>滑動菜單</title>
    <style>
    a,body,div,h1,h2,li,ul{
    margin:0;
    padding:0
    }
    a{display:block;text-decoration:none;height:25px;color:#456;background-color:#ABC;cursor:pointer;}
    a:hover{color:#123;background-color:#789;font-weight:bold;}
    body{
    font:12px/18px "Times New Roman",Times,"宋體",serif;
    text-align:center;
    }
    h1{
    height:100px;
    width:25px;
    position:absolute;
    top:-1px;
    left:123px;
    cursor:pointer;
    color:#89A;
    font-size:18px;
    line-height:50px;
    background-color:#234;
    }
    h2{
    height:24px;
    font-size:12px;
    border-bottom:1px solid #4C6CB9;
    color:#BBB;
    font-weight:600;
    cursor:pointer;
    }
    li{height:25px;list-style:none}
    #Container{width:800px;background-color:#DDD;border: 1px solid #999;margin:10px auto}
    #Top{height:30px;background-color:#DDD;border: 1px solid #999;}
    #Logo{height:100px;background-color:#DDD;border: 1px solid #999;}
    #Nav{height:30px;background-color:#DDD;border: 1px solid #999;}
    #SideBar{
    position:fixed!important;
    position:absolute;
    top:200px;
    left:0px;
    }
    #SideBar a,#SideBar h2,#SideBar li,#SideBar ul{width:120px}
    #Main{height:800px;background-color:#DDD;border: 1px solid #999;}
    #Footer{height:60px;background-color:#DDD;border: 1px solid #999;}
    .Extracted{width:0px;}
    .Extrended{border:1px solid #555;background-color:#000;padding:1px}
    </style>
    </head>
    <body>
    <div id="Container">
    <div id="Top">頂條
    <div id="Logo">Logo
    <div id="Nav">導(dǎo)航條
    <div id="SideBar" class="Extrended"> <h1>菜單</h1> <ul> <h2>功能欄1</h2> <li><a href="">功能1</li> <li><a href="">功能2</li> <li><a href="">功能3</li> <li><a href="">功能4</li> <li><a href="">功能5</li> </ul> <ul> <h2>功能欄2</h2> <li><a href="www.huiyi8.com">功能1</li> <li><a href="www.enterdesk.com">功能2</li> <li><a href="www.bizhizu.cn">功能3</li> <li><a href="www.679.com">功能4</li> <li><a href="www.enterdesk.org">功能5</li> </ul> <ul> <h2>功能欄3</h2> <li><a href="">功能1</li> <li><a href="">功能2</li> <li><a href="">功能3</li> <li><a href="">功能4</li> <li><a href="">功能5</li> </ul> <ul> <h2>功能欄4</h2> <li><a href="">功能1</li> <li><a href="">功能2</li> <li><a href="">功能3</li> <li><a href="">功能4</li> <li><a href="">功能5</li> </ul> <ul> <h2>功能欄5</h2> <li><a href="">功能1</li> <li><a href="">功能2</li> <li><a href="">功能3</li> <li><a href="">功能4</li> <li><a href="">功能5</li> </ul> <ul> <h2>功能欄6</h2> <li><a href="">功能1</li> <li><a href="">功能2</li> <li><a href="">功能3</li> <li><a href="">功能4</li> <li><a href="">功能5</li> </ul><div id="Main">內(nèi)容區(qū)<div id="Footer">底條<script type="text/javascript"> function $(e){return document.getElementById(e)} function Slide(Element,Mod){ var LongthMax,LongthMin,Property,Count=25,Accum,ID,Dlt,DltDlt; if(Mod){ Property='left'; LongthMax=0; LongthMin=-124; } else{ Property='height'; LongthMax=Element.children.length*25; LongthMin=25; } DltDlt=(LongthMax-LongthMin)/(Count*5); if(Element.style[Property]==LongthMax+'px')DltDlt=-DltDlt; Accum=parseInt(Element.style[Property]); Dlt=7*DltDlt; ID=setInterval(function(){ if(Count--){ if(!(Count%5))Dlt-=DltDlt; Accum+=Dlt; Element.style[Property]=Math.floor(Accum)+'px'; return } clearInterval(ID); Element.style[Property]=(DltDlt>0)? LongthMax+'px':LongthMin+'px'; },20); } $('SideBar').style.left='0px'; $('SideBar').children[0].onclick=function(){ Slide(this.parentNode,1); }; (function(Menu,i,tmp){ Menu=document.getElementsByTagName('ul'); for(i=Menu.length;i--;){ tmp=Menu[i]; tmp.style.overflow='hidden'; tmp.style.height='25px'; tmp.children[0].onclick=function(){ Slide(this.parentNode,0); }; } }()); </script> </body> </html>

    posted @ 2014-08-21 09:50 順其自然EVO 閱讀(234) | 評論 (0)編輯 收藏

    谷歌web站點安全掃描軟件安裝、配置和使用

      一:簡介
      skipfish是什么?
      Skipfish是一個積極的Web應(yīng)用程序的安全性偵察工具。 它準(zhǔn)備了一個互動為目標(biāo)的網(wǎng)站的站點地圖進行一個遞歸爬網(wǎng)和基于字典的探頭。 然后,將得到的地圖是帶注釋的與許多活性(但希望非破壞性的)安全檢查的輸出。 最終報告工具生成的是,作為一個專業(yè)的網(wǎng)絡(luò)應(yīng)用程序安全評估的基礎(chǔ)。
      二:部署安裝
      2.1:部署環(huán)境
      [root@cn-ptmind skipfish-read-only]# uname -a
      Linux cn-ptmind 2.6.32-220.el6.x86_64 #1 SMP Tue Dec 6 19:48:22 GMT 2011 x86_64 x86_64 x86_64 GNU/Linux
      [root@cn-ptmind skipfish-read-only]# more /etc/redhat-release
      CentOS release 6.2 (Final)
      2.2:安裝skipfish依賴包:
      yum -y install gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel zip unzip ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel krb5-devel libidn libidn-devel openssl openssh openssl-devel nss_ldap openldap openldap-devel openldap-clients openldap-servers libxslt-devel libevent-devel ntp  libtool-ltdl bison libtool vim-enhanced python wget lsof iptraf strace lrzsz kernel-devel kernel-headers pam-devel Tcl/Tk  cmake  ncurses-devel bison setuptool popt-devel rsynx openssh system-config-network-tui svn
      2.3:下載skipfish
      svn checkout http://skipfish.googlecode.com/svn/trunk/ skipfish-read-only
      #進入目錄
      cd skipfish-read-only
      #執(zhí)行make 編譯,生成skipfish 命令。
      make
      三:網(wǎng)站掃面實例
      ./skipfish -o ptengine http://www.ptengine.com
      # -o 選項制定生成掃描報告文件夾
      #將報告文件夾進行打包
      tar -cvf ptengine.tar ptengine
      #將壓縮包下載到本地
      sz -bey ptengine.tar
      掃描報告下載到本地PC后并解壓,打開文件夾,找到index.html文件,用瀏覽器打開,即可查看掃描報告。

    posted @ 2014-08-21 09:49 順其自然EVO 閱讀(481) | 評論 (0)編輯 收藏

    LoadRunner同一個腳本運行兩次結(jié)果相差很大的原因

      如果同一個腳本運行兩次結(jié)果相差特別大.后一次的響應(yīng)時間比前一次的響應(yīng)時間慢了特別多,而期間開發(fā)又未修改過程序排查問題:
      1.查看下linux內(nèi)存利用情況 free -m 是查看內(nèi)存情況 (通??捎脙?nèi)存占10%是可接受范圍內(nèi)) 如果可用內(nèi)存很小的話 :一種可能是程序有問題 :另一種可能是磁盤空間不足了 當(dāng)磁盤空間不足就會去寫內(nèi)存
      2.可以先看下第二種情況成立否 : 命令 tf -m 查看磁盤空間情況結(jié)果看到磁盤空間為0了
      3.查看哪個進程占用了這么多 ,最好通過log日志進行分析。在運行性能測試腳本前一定要確認(rèn)好log日志的級別,如果設(shè)置debug,程序就會不斷的寫日志,影響性能測試結(jié)果 通常都是設(shè)置成error級別 當(dāng)然如果再運行腳本過程中 兩次運行結(jié)果不可能完全一樣.通常相差時間要小于100ms是可接受的

    posted @ 2014-08-21 09:48 順其自然EVO 閱讀(775) | 評論 (0)編輯 收藏

    Selenium—三種啟動chrome的方式

      當(dāng)啟動chrome作selenium測試時,如果沒有設(shè)置driver,則會出錯.
      driver下載地址https://code.google.com/p/chromedriver/downloads/list
      三種方式
      1.命令行中帶參數(shù)-Dwebdriver.chrome.driver
      java -Dwebdriver.chrome.driver=chromedriver_win_22_0_1203_0b.exe  org.junit.runner.JUnitCore seleniumtest_name
      2.命令行中可以沒有-Dwebdriver.chrome.driver,但是需要在環(huán)境變量path中添加
      chromedriver.exe(注意此處文件名只能是chromedriver.exe)的路徑.
      例如chromedriver.exe的放在d:/中,  則把"d:/"添加到path變量中
      此時命令簡化為:
      java  org.junit.runner.JUnitCore  seleniumtest_name
      3.可以在.java源文件中顯示設(shè)置chromedriver
      System.setProperty("webdriver.chrome.driver","d:/chromedriver_win_22_0_1203_0b.exe")

    posted @ 2014-08-21 09:46 順其自然EVO 閱讀(2905) | 評論 (0)編輯 收藏

    Bugfree中保存用例失敗

    前幾天安裝了一個bugfree,但是測試人員在用的時候發(fā)現(xiàn)保存bug的時候直接報500了,然后我看了下apache的錯誤日志,內(nèi)容是:
    [Tue Aug 12 14:42:34 2014] [error] [client 192.168.30.67] PHP Fatal error:  Call to undefined function mb_detect_encoding() in /var/www/html/bugfree/protected/extensions/simple_html_dom.php on line 988, referer: http://192.168.30.30/bugfree/index.php/info/edit?type=result&action=opened&case_id=1
      經(jīng)過發(fā)現(xiàn)原來是少安裝了兩個php模塊:
      php-mcrypt 和  php-mbstring
      于是乎安裝吧:
      yum -y install php-mbstring
      yum -y install php-mcrypt
      安裝好后重啟apache,OK,好了

    posted @ 2014-08-21 09:44 順其自然EVO 閱讀(443) | 評論 (0)編輯 收藏

    再談瀏覽器兼容性測試

    今天跟大家聊一個老生常談的話題:瀏覽器兼容性測試。
      測試國內(nèi)網(wǎng)站的同學(xué)是不是已經(jīng)非常頭疼了,因為面對的瀏覽器除了國際大牌如IE, Chrome, Firefox, Opera, Safari, 還有國內(nèi)諸多屌絲級的瀏覽器如:360安全瀏覽器,360極速瀏覽器,360影視瀏覽器(360碉堡了,會不會再搞出一些購物瀏覽器,買火車票瀏覽器???)搜狗雙核瀏覽器,獵豹,淘寶,世界之窗,百度瀏覽器,還沒完呢,聽說過楓樹瀏覽器嗎?沒聽過的趕緊去科普科普吧!另外我今天還被不知不覺安裝了云帆影視瀏覽器。再想想這些瀏覽器有多少個版本?還有運行在Windows和MAC系統(tǒng)上的瀏覽器也是有些差異的。曾經(jīng)在蘭亭時就出現(xiàn)過在MAC/Chrome上有Windows/Chrome上沒有的bug。這么多要覆蓋的瀏覽器你若沒暈說明身體和心理素質(zhì)好,反正我是暈了!
      可是我們需要考慮瀏覽器,版本,系統(tǒng)三個因子去組合嗎?答案當(dāng)然是否定的。
      一般針對普通用戶的網(wǎng)站都會嵌入GA統(tǒng)計代碼,現(xiàn)在google被和諧了,可以換成百度統(tǒng)計,但是它們都可以跟蹤到用戶行為,其中一項就是瀏覽器訪問占比,清清楚楚告訴你每個瀏覽器占比,每個版本占比,所謂好鋼用在刀刃上,有個這項數(shù)據(jù)后,就應(yīng)該清楚的知道我們的工作重點在哪里,根據(jù)二八原則,我們也需要投入大部分精力在占比排名在80%前的上面,投入少量精力在占比比較小的瀏覽器上,我們之前的經(jīng)驗?zāi)鼙WC正常功能能使用,一些小樣式就可以容忍了,這種情況多是IE6,7,不過我一直都沒有想明白,對于IE6,國外發(fā)達國家都已經(jīng)絕跡了,為啥國人不能使用一些更高級的瀏覽器呢?回到正題,其實如果發(fā)布時間緊急,實在沒有時間來做這么多瀏覽器覆蓋的時候,就再分析一下國內(nèi)諸多瀏覽器使用的內(nèi)核以及他們的區(qū)別是什么, 如果是Chrome的內(nèi)核,也許可以跟Chrome一起來測試,如果是IE的話,就跟IE一起來測試,當(dāng)然不同的瀏覽器在渲染原理上必然還是有一些差異的,不過為了趕工,還是要做取舍的。對于IE的話,的確有必要再嘮叨幾句,基本在IE8及以后版本,基本都是標(biāo)準(zhǔn)模式,IE6,7的怪癖模式需要格外注意,如果你的網(wǎng)站在這兩個版本上占比還不小的話,的確需要好好測試下這兩個版本,IE9及之后的版本以及較新的Chrome,F(xiàn)irefox基本上都不會出問題。
      而對于企業(yè)級用戶的網(wǎng)站或者有專人在維護用戶的平臺,就好辦多了,我們可以保證幾個重要的瀏覽器重要版本的兼容性,然后讓公司的運營或者銷售人員與用戶做好溝通,對哪幾個瀏覽器支持比較好,建議他們使用我們支持的瀏覽器,因為有溝通渠道,是不是就好很多了。
      測試國外用戶特別是歐美的網(wǎng)站,就大有福氣了,他們早就不用IE6,7了,而且國外的本土瀏覽器也并沒有像國內(nèi)這么大放異彩,需要覆蓋的就少很多了。就像以前在蘭亭的時候,根據(jù)GA統(tǒng)計數(shù)據(jù),用戶使用量大的基本都是比較新的瀏覽器版本,而且Chrome,F(xiàn)irefox占比比較大。
      對于瀏覽器兼容性測試,你是不是想問有沒有什么工具來幫助我們做?是有,不過像IETester也只是支持IE,而且需要人工檢查兼容性問題, BrowserShots也只是做線上測試工具,并不支持測試環(huán)境。不過我之前用過一個Chrome的插件叫瀏覽器兼容性檢測工具,可以在內(nèi)網(wǎng)測試,會自動監(jiān)測網(wǎng)頁的設(shè)計是否滿足對應(yīng)瀏覽器及版本的規(guī)范,不滿足的話就會詳細提示出來,不過有些過于專業(yè)性了,更適合開發(fā)人員查看,測試人員可以推薦給開發(fā)人員使用,這樣在開發(fā)階段就規(guī)避掉一些兼容性問題豈不是更好。

    posted @ 2014-08-21 09:43 順其自然EVO 閱讀(160) | 評論 (0)編輯 收藏

    初次使用單元測試后的體會

     我們搞開發(fā)的往往覺得自己寫的代碼沒問題,用不著測試,以前,我也這么認(rèn)為,覺得測試?yán)速M時間,也就沒仔細研究過測試。
      最近,閑來想試試單元測試,結(jié)合之前的編程經(jīng)驗,發(fā)現(xiàn),單元測試至少是保證軟件質(zhì)量的最佳方式之一。一波一波程序員開發(fā)、維護一個產(chǎn)品,程序員之間的差別太大了,就像“明顯沒有錯誤”和“沒有明顯錯誤”的區(qū)別,怎么來保證產(chǎn)品在不斷迭代中的質(zhì)量,保留里面正確的部分,去掉bug呢?架構(gòu)設(shè)計里面講究面向接口,單元測試就能起到接口的作用。
      通過單元測試的類,它的行為是符合當(dāng)初單元設(shè)計的目標(biāo)的。只要編寫單元測試時,從多方面檢驗類的行為,就能確保在這樣的情景下,類是符合設(shè)計的。在Vistual Studio中,最簡單的單元測試就是使用本身自帶的功能(不需要從網(wǎng)上找NUnit的程序集,直接在項目上引用"Microsoft.VisualStudio.QualityTools.UnitTestFramework"程序集就ok了)。還有另外一個好處,是方便調(diào)試。單元測試項目可以在測試運行時,對被測試類下斷點,非常節(jié)約調(diào)試時間。
      我是這么做的,單元測試的代碼放到獨立的項目中去,引用要測試的項目,在被測試項目中添加Assembly特性如下:
      [assembly: InternalsVisibleTo("Projky.UnitTests")]
      這樣,單元測試就能對被測試項目中internal修飾符的類可見,又不破壞程序集的可見性。
      舉一個簡單的需求,要將如“30d9132169211a45”或者“30-D9-13-21-69-21-1A-45”或者“30 D9 13 21 69 21 1A 45”這樣的16進制字符串轉(zhuǎn)換為Byte[]數(shù)組。設(shè)計了一個ByteString的類來實現(xiàn)需求。
    internal class ByteString {
    public static Byte[] ConverterToBytes(string value) {
    if (value.IndexOf("-") > -1) {
    value = value.Replace("-", "");
    } else if (value.IndexOf(" ") > -1) {
    value = value.Replace(" ", "");
    }
    Debug.Assert(value.Length % 2 == 0, "Invalid byte string length.");
    List<Byte> list = new List<Byte>(value.Length / 2);
    for (int i = 0; i < value.Length; i += 2) {
    int bHi = GetInteger(value[i]);
    int bLow = GetInteger(value[i + 1]);
    Byte temp = (Byte)(bHi << 4 | bLow);
    list.Add(temp);
    }
    return list.ToArray();
    }
    static int GetInteger(char ch) {
    if (Char.IsDigit(ch)) {
    return ch - '0';
    }
    int value = 10;
    switch (ch) {
    case 'a':
    case 'A':
    value = 10;
    break;
    case 'b':
    case 'B':
    value = 11;
    break;
    case 'c':
    case 'C':
    value = 12;
    break;
    case 'd':
    case 'D':
    value = 13;
    break;
    case 'e':
    case 'E':
    value = 14;
    break;
    case 'f':
    case 'F':
    value = 15;
    break;
    default:
    throw new NotSupportedException(ch.ToString() + " is not valid char.");
    }
    return value;
    }
    }
     那么,簡單驗證該類的行為(接口)可以編寫下面的測試類:
    [TestClass]
    public class ByteStringTest {
    [TestMethod]
    public void ConverterToBytes() {
    string input = "30d9132169211a45";
    Byte[] bytes = ByteString.ConverterToBytes(input);
    Assert.IsTrue(bytes.Length == input.Length / 2);
    Assert.IsTrue(bytes[0] == 0x30);
    Assert.IsTrue(bytes[1] == 0xd9);
    Assert.IsTrue(bytes[2] == 0x13);
    Assert.IsTrue(bytes[3] == 0x21);
    Assert.IsTrue(bytes[4] == 0x69);
    Assert.IsTrue(bytes[5] == 0x21);
    Assert.IsTrue(bytes[6] == 0x1a);
    Assert.IsTrue(bytes[7] == 0x45);
    input = "30-D9-13-21-69-21-1A-45";
    bytes = ByteString.ConverterToBytes(input);
    Assert.IsTrue(bytes.Length == 8);
    Assert.IsTrue(bytes[0] == 0x30);
    Assert.IsTrue(bytes[1] == 0xd9);
    Assert.IsTrue(bytes[2] == 0x13);
    Assert.IsTrue(bytes[3] == 0x21);
    Assert.IsTrue(bytes[4] == 0x69);
    Assert.IsTrue(bytes[5] == 0x21);
    Assert.IsTrue(bytes[6] == 0x1a);
    Assert.IsTrue(bytes[7] == 0x45);
    input = "30 D9 13 21 69 21 1A 45";
    bytes = ByteString.ConverterToBytes(input);
    Assert.IsTrue(bytes.Length == 8);
    Assert.IsTrue(bytes[0] == 0x30);
    Assert.IsTrue(bytes[1] == 0xd9);
    Assert.IsTrue(bytes[2] == 0x13);
    Assert.IsTrue(bytes[3] == 0x21);
    Assert.IsTrue(bytes[4] == 0x69);
    Assert.IsTrue(bytes[5] == 0x21);
    Assert.IsTrue(bytes[6] == 0x1a);
    Assert.IsTrue(bytes[7] == 0x45);
    }
    }
      如果單元測試運行失敗,例如Assert.IsTrue()方法中,參數(shù)為False,則在VS中會拋異常,這樣,就知道哪里不正確了。
      注意用[TestClass]標(biāo)記作為單元測試承載的類,是public可見性,而里面單個的獨立測試方法,則采用[TestMethod]標(biāo)記,同樣是public可見性。
      在Visual Studio里面還有一個技巧,按Ctrl + R,A可以自動運行單元測試項目。如果被測試類有斷點的話,測試到該位置時,也會斷下來。

    posted @ 2014-08-21 09:42 順其自然EVO 閱讀(156) | 評論 (0)編輯 收藏

    僅列出標(biāo)題
    共394頁: First 上一頁 61 62 63 64 65 66 67 68 69 下一頁 Last 
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導(dǎo)航

    統(tǒng)計

    常用鏈接

    留言簿(55)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 黄色免费在线观看网址| 国产亚洲人成网站在线观看不卡 | a级黄色毛片免费播放视频| 深夜A级毛片视频免费| 处破女第一次亚洲18分钟| 国产亚洲成AV人片在线观黄桃| 亚洲日本va午夜中文字幕久久| 亚洲国产精品一区二区三区久久| 深夜国产福利99亚洲视频| 日韩免费高清大片在线| 午夜亚洲国产理论片二级港台二级| 亚洲AV无码乱码在线观看富二代| 国产成人亚洲综合无码精品 | 精品久久免费视频| 免费看一区二区三区四区| a级成人毛片免费图片| 国产精品区免费视频| 1000部禁片黄的免费看| 1000部国产成人免费视频| 成人免费一区二区无码视频| 午夜毛片不卡高清免费| 久久国产色AV免费观看| 日本h在线精品免费观看| 久久综合AV免费观看| 又粗又大又长又爽免费视频 | 人人公开免费超级碰碰碰视频| ssswww日本免费网站片| 久久亚洲AV成人无码国产电影| 粉色视频免费入口| 伊人免费在线观看高清版| 95老司机免费福利| 在线中文高清资源免费观看| 亚洲AV无码一区二区三区国产| 亚洲精品自产拍在线观看| 亚洲欧洲另类春色校园小说| 亚洲欧美日韩综合久久久| 一个人看的免费视频www在线高清动漫| 成人无码a级毛片免费| 免费看污成人午夜网站| 精品熟女少妇av免费久久| 黄瓜视频高清在线看免费下载|