? ? ? ?服務器端的測試,軟件需求基本等于產品說明書,只有大概,沒有詳盡。再需求不充分的情況下,我們可以從哪些方面來挖掘測試需求呢?
現已知需求:服務器支持對客戶端的版本升級,存在兩種升級規則:
第一:最低版本升級:按照客戶端的類型,如果當前版本小于最低版本要求則需要進行升級
第二:指定版本升級:根據某個客戶端類型+版本信息,強制或者提示升級到指定版本
????? 如果同時滿足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類,返回給客戶端。
那思考之前的疑惑,解答如下:
- 存在一個產品,有多個指定版本升級的情況,測試用例需要增加。
- 運營線是有14個,但是根據程序內部實現方法(容器循環控制找產品ID),是沒必要配置14個的,測試4個,4個產品都能依次正常通過測試,就能保證14個沒問題。
- 交互過程,接口輸入輸出已表明。
- 等于的時候是什么情況,得與開發溝通。
?修正測試點如下:
?