新聞中心
一、背景
在進行某項系統(tǒng)測試時,遇到選擇部分保單更新為加急狀態(tài)后,未選中的保單也同步更新成了加急狀態(tài)。

讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領域值得信任、有價值的長期合作伙伴,公司提供的服務項目有:域名注冊、網站空間、營銷軟件、網站建設、海門網站維護、網站推廣。
經過比對分析,發(fā)現(xiàn)是SQL查詢在數(shù)據(jù)庫設計為字符型的字段,SQL語句中用了數(shù)值型來查詢時,查詢結果結果會多了末尾兩位不一致的值,如下圖,100320201000195806搜出100320201000195812等值:
百因必有果,通過度娘,首先了解到原來在MySQL中,當操作符與不同類型的操作數(shù)一起使用時,會發(fā)生類型轉換以使操作數(shù)兼容,即字符型字段與數(shù)值型值比較時,會進行隱式類型轉換:都轉換為數(shù)值型。
即,數(shù)據(jù)庫字段值為字符型1234,查詢條件為數(shù)值1234的時候,數(shù)據(jù)庫字符型1234會轉換為數(shù)值型1234,能夠查詢到對應值。
但為什么數(shù)值型100320201000195806除了搜索出100320201000195806還有100320201000195812這樣的字符型結果?
二、問題根因
數(shù)值隱式轉換成了double型,考慮數(shù)值可能出現(xiàn)溢出。根據(jù)DOUBLE 類型固定占用8個字節(jié)(64位),并且需要一位表示符號,11位表示指數(shù),2的52次方-1:2^53 = 9007199254740992,當輸入的數(shù)值大于9007199254740992時,存在數(shù)值溢出 。
也就是當數(shù)字超過16位以后,數(shù)據(jù)庫不會報錯,而是溢出后轉為最接近的值入庫,如下圖:設置字段類型為double型,9007199254740993入庫后顯示為9007199254740992。
并且如下圖測試,溢出入庫的數(shù)據(jù)轉化后有某種沒明顯規(guī)律的規(guī)則:
同理,取數(shù)據(jù)時,大于9007199254740992的數(shù)值也會發(fā)生轉換,如下圖,9007199254740993可以檢索出9007199254740992的數(shù)值:
所以Bug產生過程為:18位數(shù)值類型 為double類型(1.003202010001958E+18),數(shù)據(jù)庫查詢時將business_no 變成(1.003202010001958E+18),數(shù)據(jù)庫存的business_no值也根據(jù)隱式類型轉換原則也轉為了double類型。最終,過濾末尾兩位的數(shù)值相等。
至此,對不同字符產生的隱式類型轉換 和過程中轉 double 型、數(shù)值溢出問題都有了更新的認知。
三、從表象 bug 展開的測試點思考
1. 反向思考
以上是字符型字段導入數(shù)值型的案例,因為字符型存的也是數(shù)值,因此在未超過 16位的查詢上,不會有其他異常,但如果是數(shù)值型字段導入字符型字段呢?
如下圖測試所示:
插入 id=0 的數(shù)據(jù)后,查詢 id=a 可以查詢出 id=0 的數(shù)據(jù)。
原來 mysql 的隱式轉換,在 int 類型的字段傳入字符串會截取從第一位 int 型開始到第一個非 int 型的值作為條件。因為 a 沒有 int 值,所以等于 0,最終查詢 id=a 可以查詢出 id=0 的數(shù)據(jù)。
特別注意:如果傳入字符串為 01e2 ,則可以查詢出 100。
2. 針對隱式轉換的 bug,之后如何優(yōu)化用例測試點,做主動防范,提高測試覆蓋率?
(1) 功能問題考慮:
表單校驗:使用不同于數(shù)據(jù)庫設計類型的數(shù)據(jù)來進行測試,如數(shù)據(jù)庫數(shù)值型,則用字符型數(shù)據(jù)測試,字符型數(shù)據(jù)用 0 或&等數(shù)值運算符測試,從源頭盡量過濾不一致。
對于非 web 錄入的源頭或者后臺程序代碼看不到的類型轉換的問題,可以使用多個超過 16 位的臨近數(shù)、以及根據(jù)隱式轉換規(guī)則轉換后值一致的字符串進行數(shù)據(jù)鋪底,測試點包括所有涉及后臺查詢的場景。在我們保險軟件測試中,因為單證號是非常重要的基本數(shù)據(jù),因此特別要注意超過 16 位的保單號、投保單等單證的鋪底準備。
除此外,關注數(shù)值統(tǒng)計、時間比較的業(yè)務場景,因為涉及時間和數(shù)值統(tǒng)計時經常需要函數(shù)進行轉換,此時如果格式不一致也會發(fā)生隱式轉換的問題:如date( a.publish_time ) >= date_sub( curdate(), INTERVAL 1 DAY )
Date 顯示格式:YYYY-MM-DD;DateTime 顯示格式:YYYY-MM-DD HH:mm:ss。
所以 2008-12-27 16:25:46.635 經過 dat(e )函數(shù)處理后的時間為:2008-12-27 ,date_sub時間值精確到秒,因此發(fā)生隱式轉換后,date()會轉成 2008-12-27 0:0:0,時間范圍上變窄。
數(shù)據(jù)庫存在NULL值時,需要特別關注。因為當兩個參數(shù)至少有一個是 NULL 時,比較的結果也是 NULL。
當前標題:數(shù)據(jù)庫丨從MySQL數(shù)值隱式轉換成了double型的測試點,值得學習
網站路徑:http://m.fisionsoft.com.cn/article/djseocd.html


咨詢
建站咨詢
