文章出處

解剖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個測試。這能夠讓一個完整的測試集合控制在合理的時間,

同時依然保持測試子集能夠很快運行。通常代碼的更改不會對測試造成太多的影響

 

第六篇完


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()