解剖SQLSERVER 第六篇 ?對OrcaMDF的系統測試里避免regressions?(譯)
http://improve.dk/avoiding-regressions-in-orcamdf-by-system-testing/
當我繼續添加新功能和新的數據結構支持進去OrcaMDF軟件的時候, bug的風險 不斷增加
特別是當我開發一個很大的未知功能時,我不能預估結構和該結構的關聯,為了降低風險,測試是很有必要的
?
單元測試
單元測試 是在面向對象編程里測試源代碼某一個功能的最小一部分的測試。一個測試的例子是 SqlBigInt數據類型 解析類,
他應該長這個樣子
using
System;
using
NUnit.Framework;
using
OrcaMDF.Core.Engine.SqlTypes;
namespace
OrcaMDF.Core.Tests.Engine.SqlTypes
{
[TestFixture]
public
class
SqlBigIntTests
{
[Test]
public
void
GetValue()
{
var
type =
new
SqlBigInt();
byte
[] input;
input
=
new
byte
[] {
0xFF
,
0xFF
,
0xFF
,
0xFF
,
0xFF
,
0xFF
,
0xFF
,
0x7F
};
Assert.AreEqual(
9223372036854775807
, Convert.ToInt64(type.GetValue(input)));
input
=
new
byte
[] {
0x82
,
0x5A
,
0x03
,
0x1B
,
0xD5
,
0x3E
,
0xCD
,
0x71
};
Assert.AreEqual(
8200279581513702018
, Convert.ToInt64(type.GetValue(input)));
input
=
new
byte
[] {
0x7F
,
0xA5
,
0xFC
,
0xE4
,
0x2A
,
0xC1
,
0x32
,
0x8E
};
Assert.AreEqual(
-
8200279581513702017
, Convert.ToInt64(type.GetValue(input)));
}
[Test]
public
void
Length()
{
var
type =
new
SqlBigInt();
Assert.Throws
<ArgumentException>(() => type.GetValue(
new
byte
[
9
]));
Assert.Throws
<ArgumentException>(() => type.GetValue(
new
byte
[
7
]));
}
}
}
這個測試包含了SqlBigInt 類的主入口點,測試long?bigint 數據類型是否會造成上溢或下溢的情況,也包含長度檢查。
對于像SqlBigInt這樣簡單的類型單元測試會工作得很好。有時候單元測試會很復雜當相關聯的類需要調用相應方法,類等支持他運行的底層結構的時候( mock測試 )
雖然這是一個工作策略,測試需要不斷進行,特別在項目早期階段,整個架構都是動態的
?
系統測試
在測試范圍上,我們需要更大的范圍測試 -系統測試。系統測試旨在測試系統作為一個整體,基本上忽略系統內部工作原理
如果要分類的話可以被分為 黑盒測試。對于OrcaMDF,我估計可以捕獲90%的所有的regressions?只使用10%的時間,
相比起單元測試使用更多時間只捕獲少量的regressions 。
因此,這是一個很好的方法在開發期間的測試,同時可以引入關鍵的單元測試和集成測試。
例如我想測試DatabaseMetaData 類里面的用戶表名字的解析,我可以模擬SysObjects的值列表,同時對于DatabaseMetaData 類
的構造函數也能模擬MdfFile 所必須的參數,為了做到這一點,我必須從MdfFile 提取出一個接口并且在上面使用mocking framework
?
系統測試的方法執行以下流程:
1、連接到SQLSERVER實例
2、在 測試固件(Test fixture) 里創建測試架構
3、分離數據庫
4、運行OrcaMDF 并加載分離的數據庫驗證結果
?
一個測試樣例,創建兩個用戶表并且驗證DatabaseMetaData類的輸出
using
System.Data.SqlClient;
using
NUnit.Framework;
using
OrcaMDF.Core.Engine;
namespace
OrcaMDF.Core.Tests.Integration
{
public
class
ParseUserTableNames : SqlServerSystemTest
{
[Test]
public
void
ParseTableNames()
{
using
(
var
mdf =
new
MdfFile(MdfPath))
{
var
metaData =
mdf.GetMetaData();
Assert.AreEqual(
2
, metaData.UserTableNames.Length);
Assert.AreEqual(
"
MyTable
"
, metaData.UserTableNames[
0
]);
Assert.AreEqual(
"
XYZ
"
, metaData.UserTableNames[
1
]);
}
}
protected
override
void
RunSetupQueries(SqlConnection conn)
{
var
cmd =
new
SqlCommand(
@"
CREATE TABLE MyTable (ID int);
CREATE TABLE XYZ (ID int);
"
, conn);
cmd.ExecuteNonQuery();
}
}
}
?
在實際的真實生活場景里這樣可以非常快速的進行測試。想測試轉發記錄的解析?只需要簡單地創建一個新的測試
編寫TSQL代碼來生成目標數據庫狀態然后驗證掃描到的表數據
?
系統測試的缺點
不幸的是系統測試不是萬能藥,它也有它的缺點。最明顯的一個缺點是性能。
單元測試通常需要運行非常快,基本上允許您在每個文件保存后在后臺運行它們。從綁定CPU開始到運行 ,每一個這樣的系統測試都需要半秒
幸運的是,它們可以并行運行沒有問題。在一臺四核的機器能讓我每分鐘運行480個測試。這能夠讓一個完整的測試集合控制在合理的時間,
同時依然保持測試子集能夠很快運行。通常代碼的更改不會對測試造成太多的影響
?
第六篇完
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

