標籤:style blog http color io 使用 ar strong sp
解剖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個測試。這能夠讓一個完整的測試集合控制在合理的時間,
同時依然保持測試子集能夠很快運行。通常代碼的更改不會對測試造成太多的影響
第六篇完
解剖SQLSERVER 第六篇 對OrcaMDF的系統測試裡避免regressions(譯)