從代碼里提取的測試需求

? ? ? ?服務器端的測試,軟件需求基本等于產品說明書,只有大概,沒有詳盡。再需求不充分的情況下,我們可以從哪些方面來挖掘測試需求呢?

現已知需求:服務器支持對客戶端的版本升級,存在兩種升級規則:

第一:最低版本升級:按照客戶端的類型,如果當前版本小于最低版本要求則需要進行升級

第二:指定版本升級:根據某個客戶端類型+版本信息,強制或者提示升級到指定版本

????? 如果同時滿足2種升級規則,優先匹配第二種。配置文件如下:

一般測試人員都能分析到以下兩點如下:

  1. 兩種規則同時滿足時,怎么選擇?
  2. 第一種規則:當前版本《 最低版本,則提示需要進行升級。那當前版本》最低版本的時候呢?

? ? ? ? ? 第二種規則:當前版本《 最低版本,則需要強制升級,那當前版本》最低版本的時候呢?

?假設當前客戶端類型只有一種,設只有PC客戶端,一般都能寫出以下的測試用例:

?

??那這樣的設計,算全面了么,再深入一層分析,又缺少了什么呢?

1、? 產品和兩個規則的關系如何?1對1,1對多?每個產品都可能存在多個指定版本升級的規則?

2、? 總共運營上存在14個產品,每類產品都需要覆蓋測試?

3、? 客戶端與服務器是怎么進行交互的,客戶端傳遞什么數據到服務器,服務器返回什么給客戶端?升級的整個流程是什么樣的,清楚么?

4、? 之前考慮的第二點,太粗糙,》之外的,除了《,還有 = 。

?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

客戶端和服務器端的接口核心函數代碼如下:

//GetProductItem為服務器端與客戶端之間的接口函數,客戶端傳szProductID,szVersion給服務器端,然后服務器就此作出判斷,返回正確的數據到item類中,供客戶端調用。

bool CConfig::GetProductItem(const CHAR *szProductID, const CHAR *szVersion, ProductItem &item)

{

// 先根據ProductID確定產品的ProductDetail

??? ProductDetail *pProduct = FindProduct(szProductID);

??? //如果客戶端傳遞的szProductID為空,則用默認的

??? if (!pProduct)

??? {

? ?//m_strDefaultProduct存儲從配置文件中讀取的DefaultProduct的ID

????? pProduct = FindProduct(m_strDefaultProduct.c_str());

?? //如果默認的為空,則直接返回false

??????? if (!pProduct)

??????? {

??????????? return false;

??????? }

?}

?

//根據szVersion在確定的ProductID內得到grayupdate配置的版本

//find()函數返回一個迭代器指向鍵值為key的元素,如果沒找到就返回指向map尾部的迭代器

??? auto iter = pProduct->mapVersionInfo.find(szVersion);

??? //如果沒有找到,就用默認版本信息(強制升級塊)

??? if (iter == pProduct->mapVersionInfo.end())

??? {

??????? iter = pProduct->mapVersionInfo.find(DEFAULT_VERSION);

??????? if (iter == pProduct->mapVersionInfo.end())

??????? {

??????????? return false;

??????? }

??? }

?

// 在服務器端將strMinVersion,strNewVersion,lsDownloadUrl存在item,返回給客戶端,由客戶端控制怎么強制升級還是提示升級。

??? item.strProductID = pProduct->strProductID;

??? item.strWebServicesURL = m_strWebServicesURL;

??? item.strMinVersion = iter->second.strMinVersion;

??? item.strNewVersion = iter->second.strNewVersion;

??? item.lsDownloadUrl = iter->second.lsDownloadUrl;

?

??? return true;

}

FindProduct的實現過程如下:

服務器在等待客戶端發送客戶端相關數據過來前,服務器啟動時,就加載配置文件,讀取對應服務器下的配置文件<CONFIG>里的數據到szConfig中,然后調用LoadConfig的方法。

//LoadConfig方法作用:將配置文件里的數據,默認配置的產品ID讀取到szProductID,產品的其他所有信息讀取到pProductDetail中。

BOOL CConfig::LoadConfig(const CHAR *szConfig)

{

??? if (NULL == szConfig)

??????? return FALSE;

?

??? TiXmlElement element("");

element.Parse(szConfig, NULL, TIXML_ENCODING_UTF8);

?

// 取配置信息中DefaultProduct元素的數據存在szProductID中。

??? const CHAR *szProductID = TiXmlGetValue(&element, "DefaultProduct");

??? if (!szProductID || strcmp(szProductID, "") == 0)

??? {

??????? return FALSE;

??? }

??? m_strDefaultProduct = szProductID;

?

// szWebServicesURL 變量暫時未被使用(以前的舊代碼),可以忽略

? const CHAR *szWebServicesURL = TiXmlGetValue(&element, "WebServicesURL");

??? if (szWebServicesURL)

??? {

??????? m_strWebServicesURL = szWebServicesURL;

}

?

//讀取配置文件中Product的第一個元素的信息,將里面的值返回pProductDetail類中

?? TiXmlElement *pProductDetail=element.FirstChildElement("Product");

??? if (!pProductDetail || !ReadProductDetail(pProductDetail))

??? {

??????? return FALSE;

??? }

??? return TRUE;

}

?ReadProductDetail函數的作用就是將product下對應的部分數據,讀取到pProductDetail的成員變量strProductID和mapVersionInfo(版本集合內).

? ? ?看完代碼,得知的大致流程如下:首先服務一啟動,就會將每個Product下的pProductDetail保存起來,然后客戶端發送szProductID,szVersion給服務器端,服務器端首先是在m_lsProduct(list)下查找出自己對應的pProductDetail信息,如果沒有找到,則使用默認版本,然后根據szVersion在確定的ProductID內得到grayupdate配置的版本,如果沒有找到,就用默認版本信息,將得到的數據都保存在item類,返回給客戶端。

那思考之前的疑惑,解答如下:

  1. 存在一個產品,有多個指定版本升級的情況,測試用例需要增加。
  2. 運營線是有14個,但是根據程序內部實現方法(容器循環控制找產品ID),是沒必要配置14個的,測試4個,4個產品都能依次正常通過測試,就能保證14個沒問題。
  3. 交互過程,接口輸入輸出已表明。
  4. 等于的時候是什么情況,得與開發溝通。

?修正測試點如下:

?

轉載于:https://www.cnblogs.com/loleina/p/5091114.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/375215.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/375215.shtml
英文地址,請注明出處:http://en.pswp.cn/news/375215.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PUSH/POP

棧操作指令PUSH 寄存器/段寄存器/內存單元POP 寄存器/段寄存器/內存單元PUSH AX1)SPSP-2 ,SS:SP指向新的內存單元2)將AX送入SS:SP指向的內存單元POP AX1)將SS:SP指向的內存單元處的數據送入AX中2)SPSP2

Android Ant 和 Gradle 打包流程和效率對照

一、Ant 打包&#xff1a;&#xff08;下載ant、配置環境變量就不說了&#xff09; 1、進入命令行模式&#xff0c;并切換到項目文件夾。運行例如以下命令為ADT創建的項目加入ant build支持&#xff1a; android update project -p . -t "android-17" 2、build腳本默…

讀軟件工程這本書的感悟(第一次作業)

在還沒上這門課之前&#xff0c;我認為軟件工程是讓我們學會編寫軟件&#xff0c;但是在看到這本書后&#xff0c;我才知道我們學的不是如何的開發軟件&#xff0c;而是在學習開發和維護軟件&#xff0c;以及如何把經過時間考驗而證明正確的管理技術和當前能夠得到的最好的技術…

請大家編譯連接并執行一下

由于是筆記&#xff0c;也許記得有點糟糕&#xff0c;也許班門弄斧沒有獨到見解 &#xff0c;見諒見諒

KVC和KVO

OC中的一個比較有特色的知識點&#xff1a;KVC和KVO一、KVC操作OC中的KVC操作就和Java中使用反射機制去訪問類的private權限的變量&#xff0c;很暴力的&#xff0c;這樣做就會破壞類的封裝性&#xff0c;本來類中的的private權限就是不希望外界去訪問的&#xff0c;但是我們這…

8086加法指令ADD

加法指令ADD(ADDition) ADD OPRD1,OPRD2 ;OPRD1<--OPRD1OPRD2 ;完成OPRD1與OPRD2相加 ,結果保存在OPRD1中CODE SEGMENT MOV AX,1 MOV BX,2 ADD AX,BX ;AX<--AXBX ,結果AX3CODE ENDS參與運算的操作數類型必須保持一致,同為字節或字可組合以下幾種形式&…

Fragment基礎講解

//新建一個碎片public class LeftFragment extends Fragment { Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // 加載一個碎片界面 View view inflater.inflate(R.layout.leftfragment, container, false)…

[bzoj1012](JSOI2008)最大數maxnumber(Fenwick Tree)

Description 現在請求你維護一個數列&#xff0c;要求提供以下兩種操作&#xff1a; 1、 查詢操作。語法&#xff1a;Q L 功能&#xff1a;查詢當前數列中末尾L個數中的最大的數&#xff0c;并輸出這個數的值。限制&#xff1a;L不超過當前數列的長度。 2、 插入操作。語法&…

javaScript轉換日期合格式

javascript如何將時間日期轉換為Date對象:有時候需要講一個字符串型的時間日期轉換為Date時間對象&#xff0c;下面就通過一個簡單的實例提供一種解決方案&#xff0c;當然也是一種思路&#xff0c;可以進行一定的變通&#xff0c;以達到舉一反三的效果。例如這里有一個時間日期…

8086減法指令SUB

減法指令SUB(SUBtraction) SUB OPRD1,OPRD2 ; OPRD1<-- OPRD1-OPRD2 都影響FLAG標志寄存器,同樣的包含兩種含義(有符號減法和無符號減法)

奇怪吸引子---Dadras

奇怪吸引子是混沌學的重要組成理論&#xff0c;用于演化過程的終極狀態&#xff0c;具有如下特征&#xff1a;終極性、穩定性、吸引性。吸引子是一個數學概念&#xff0c;描寫運動的收斂類型。它是指這樣的一個集合&#xff0c;當時間趨于無窮大時&#xff0c;在任何一個有界集…

8086 INC, DEC

INC OPRD ;OPRD<--OPRD1 ;自加1指令code segmentmov ax,0inc ax ;ax<--ax1 ,ax1inc ax ;ax<--ax1 ,ax2code endsDEC OPRD ;OPRD<--OPRD-1 ;自減1指令code segmentmov ax,5dec ax ;ax<--ax-1 ,ax4 code ends

iPhone UITableViewCell如何滾動到視圖頂端。

如何讓UITableViewCell滾動到視圖頂端。 - (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated;- (void)scrollToNearestSelectedRowAtScrollPosition:(UITableViewScrollPosition)s…

app 一些常用的

發短信 &#xff1a;sms:10086 打電話&#xff1a;tel:10086 1、-webkit-tap-highlight-color:rgba(255,255,255,0)可以同時屏蔽ios和android下點擊元素時出現的陰影。備注&#xff1a;transparent的屬性值在android下無效。 2、-webkit-appearance:none可以同時屏蔽輸入框怪異…

8086乘法指令MUL,IMUL

對于加減指令來說CPU對有符號加減和無符號加減一視同仁,根據我們需要把它作為有符號的結果還是無符號的結果,但是乘除法指令區分有符號乘除和無符號乘除指令 無符號數乘法指令MUL(MULtiply) MUL OPRD(OPRD可以用除立即數以外的任何尋址方式)OPRD是八位一個乘數默認在AL中 則&am…

hdu 4857 逃生 拓撲排序

逃生題目連接&#xff1a; http://acm.hdu.edu.cn/showproblem.php?pid4857 Description 糟糕的事情發生啦&#xff0c;現在大家都忙著逃命。但是逃命的通道很窄&#xff0c;大家只能排成一行。 現在有n個人&#xff0c;從1標號到n。同時有一些奇怪的約束條件&#xff0c;每個…

指針數組,數組指針,指針函數,函數指針(轉)

int *p[4]; //指針數組。 是個有4個元素的數組&#xff0c; 每個元素的是指向整型的指針。(數組的每個元素都是指針)int (*p)[4]; //數組指針。 它是一個指針&#xff0c;指向有4個整型元素的數組。 (一個指針指向有4個整型元素的數組)int *…

8086除法指令DIV,IDIV

無符號除法指令DIV(DIVision) DIV OPRD ;除數OPRD決定是8位除法還是16位除法;OPRD8位,則被除數默認在AX中,AX除以OPRD的商保存在AL中,余數保存在AH中;OPRD16位,則被除數默認在DX與AX中,結果的商保存在AX中,余數保存到DX中assume cs:code data segmentdb 2,4 data ends code se…

Hibernate 基礎配置及常用功能(二)

本章主要是描述幾種經典映射關系&#xff0c;順帶比較Hibernate4.x和Hibernate5.x之間的區別。 一、建立測試工程目錄 有關實體類之間的相互映射關系&#xff0c;Hibernate官方文檔其實描述的非常詳細&#xff0c;這里只提供幾種常見映射。&#xff08;推薦4.3.11版本的 hibern…

三言兩語

人生中總是在選擇。每當做一件事我們都應該問問我們的內心&#xff0c;或多或少我們都能理解一點人生的真諦。 最近時間很充裕&#xff0c;也就想了好多事情。首先我想明白的第一件事就是做任何事就要勇敢的去面對、去追求。喜歡一個女孩子大概有8年了吧&#xff01;這期間我們…