業務邏輯中的測試總結(一)----比值類需求測試分解


      最近一直都在做測試用例設計,主要是針對服務器端的業務進行測試,除了編寫測試用例,實現接口的自動化測試外,還需要對核心代碼段進行走讀,然后查漏補缺測試用例。其中也有了不少的收獲,想着還是把它們先記錄下來吧,往后有新的想法還可以繼續修改或者增加。今天總結的比值類測試分解,先說明下比值類需求大概意思就是:A/B的這類小需求點,首先我會以最近我測試遇到的實例為例,然后慢慢給出實際測試過程中我的一些經典總結。

     提取出來的需求是這樣的:服務器之間流量的比值判斷,每台服務器給其定義一個流量閥值(服務器的配置文件中),這個閥值就是這台服務器的最高流量值了。然后有一個當前流量值,就是獲取當前系統的下載流量值,流量比值就是當前流量值與流量閥值的比較(當前流量值/流量閥值)值。現在就是需要對服務器間的流量比值進行測試;會怎樣設計測試用例呢?

     有覺得這個需求好像沒啥可測的童鞋么?嘿嘿,當初我就覺得好像也沒啥可測性,不就一個除法么,貌似看着不需要多加分析神馬?流量閥值是保存在配置文件中的,默認值非0,如果運維童鞋硬是寫了0導致服務器出問題,那應該是他們自己的責任,當前流量值是直接從服務器上獲取下載流量值然后在數據庫中,判斷流量比值的時,就是拿這2個值進行比較罷了,況且流量比值只是一個算法(就是選擇一台最優服務器)中的一部分,當時就把時間放在算法的業務邏輯上了。而后針對算法設計測試用例后就開始先進行手工測試了,針對這個忽略的需求點,大致也以下2個測試用例:

    1. 設置服務器A: 流量閥值為102400,當前流量為3000;服務器B: 流量閥值為102400,當前流量為2000, 有時候算法選了A服務器,有時候執行又是選了B服務器;

    2.  設置服務器A: 流量閥值為102400,當前流量為204800;服務器B: 流量閥值為102400,當前流量為307200, 結果正確,選了A。

     開發哥哥修改一遍后,測試不通過,修改第二遍才通過。oh mygod!如此一個簡單的除法,怎么會醬紫~~開發解釋一通后,看了下代碼(c++),才造不是簡單的/ 和比較大小的事情,開始覺得自己漏掉的神馬~~~

    流量閥值是int類型的,當前流量值存在數據庫也是一個int類型的,開發哥哥沒有進行處理,直接相除。這樣如果是3000/102400=0;2000/102400=0 除出來的結果都是0了,所以就相等了;后將分子(當前流量)轉換成double后,發現還是比較不了,還是會出現同一個條件隨機選擇服務器的結果,這是因為對比值大小比較時未進行精度控制,當兩個比值相差很小的時候,比如相差為0.0001的時候,不同的服務器可能會給出不同的結果,精度大於0.0001的服務器能做出正確的判斷,而小於0.0001的,會隨機生成不足的位數,導致比較結果也出現隨機。

    得知這些結果后,暗自偷笑了一把,若是當時設置測試數據時,隨手設置流量閥值為10,設置當前流量巧妙的設置成其倍數等,會有多少bug會因此未被測試出來。后面回頭一想,這何嘗不是思維的不嚴謹的一種表現呢,這個需求實際就是比值類需求,就是兩個數相除,測試經常會強調,發散思維的思考;但是實際上的此類發散,我覺得是在嚴謹的邏輯思維后再居於此類的發散,是一種有規律的發散,而不是毫無根據的隨意發散。最后看了下測試結果完全正確后的該部分的代碼,如下所示:

static FS_INT32 FlowRatioCompare(ServiceInstanceStateItem &a, ServiceInstanceStateItem &b)
{
    double a_ratio, b_ratio;
    FS_INT32 ret;

    // avoid taking 0 as divisor
    if (a.stServiceInstanceState.nFlowrateOverloadThreshold == 0)
    {
        a.stServiceInstanceState.nFlowrateOverloadThreshold = 1UL;
    }
    if (b.stServiceInstanceState.nFlowrateOverloadThreshold == 0)
    {
        b.stServiceInstanceState.nFlowrateOverloadThreshold = 1UL;
    }
    a_ratio = (double)a.stServiceInstanceState.nUploadRate / a.stServiceInstanceState.nFlowrateOverloadThreshold;
    b_ratio = (double)b.stServiceInstanceState.nUploadRate / b.stServiceInstanceState.nFlowrateOverloadThreshold;

    // FLT_EPSILON = 1.19209290E-07F defined in float.h
    if (fabs(a_ratio - b_ratio) < FLT_EPSILON)
    {
        ret = 0;
    }
    else if (a_ratio - b_ratio > FLT_EPSILON)
    {
        ret = 1;
    }
    else
    {
        ret = -1;
    }

    return ret;
}

      函數FlowRatioCompare的入參是需要比較的兩台服務器的對象的引用,主要做了三件事:

A. 首先就是對每台機器的閥值進行了判斷,畢竟是要做被除數的,如果出現運維誤配導致生產線上機器崩潰此類重大問題,還是很不應該的,如果閥值是0,則給其賦予一個非0的值。

B. 接着就是對其進行除法比較了,之前學習了python,知道python中除法就有2個相關概念,一個叫Floor Division(17//3=5;17//3.0=5.0),還有一種叫Classic  Division(17/3=5;17/3.0=5.66666667), 對c++來說就只有/ 一個操作符,也就只有Classic Division,如果兩個都是int類,16/3和17/3的結果是一樣的,就都會是5.所以應該把其中一個除數轉換成double類型后相除就能得到小數點后面的位數了。

C. 最后對兩個浮點數比較時的精度問題考慮。明確給出精度的大小值,如果兩個浮點數相減的絕對值比精度值還小,表示兩個數相差很近,這時程序判斷兩者就是一樣的;否則就表示兩個浮點數相除較遠,就可以正常判斷大小了。

      了解正常的處理邏輯后,再做比值類測試,至少要考慮以下幾點:

 A. 分子,分母單位一致么?(本實例均為kbit/s)

 B. 分子為0,怎么辦?

 C. 分子,分母是什么類型的數據?需求是Classic Division,還是Floor Division?

 D. 浮點數值比較時,如果處理其精度問題? 

       為此,增加下面測試用例(假設精度為小數點后2位):

  1. 設置服務器A: 流量閥值為100,當前流量為200;服務器B: 流量閥值為100,當前流量為100,A 比值:2;B比值:1 ,此類情況下,流量比值:A > B

  2.  設置服務器A: 流量閥值為500,當前流量為120;服務器B: 流量閥值為500,當前流量為120 ,A 比值:0.24;B比值:0.24.由於當前精度保證為小數點后2位,此類情況下,流量比值:A = B

  3. 設置服務器A: 流量閥值為500,當前流量為120;服務器B: 流量閥值為400,當前流量為100 ,A 比值:0.24;B比值:0.25.由於當前精度保證為小數點后2位,此類情況下,流量比值:A < B

  4.  設置服務器A: 流量閥值為500,當前流量為312;服務器B: 流量閥值為800,當前流量為500,A比值:0.624;B比值:0.625.由於當前精度保證為小數點后2位,此類情況下,流量比值:A = B

  5.  設置服務器A: 流量閥值為0

      有沒有覺得這樣摸清邏輯思路后再寫測試用例,好像思路也大開了感覺,雖然這類小需求是測試常見的需求,但是弄清原理對測試來說是非常重要的,再此基礎上,結合實際的業務,可以發撒出更多的測試用例。其他類的測試需求分解總結后面會陸續補上,未完待續~~

       

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM