解剖SQLSERVER 第六篇 对OrcaMDF的系统测试里避免regressions(译)
解剖SQLSERVER 第六篇 ?對(duì)OrcaMDF的系統(tǒng)測(cè)試?yán)锉苊鈘egressions?(譯)
http://improve.dk/avoiding-regressions-in-orcamdf-by-system-testing/
當(dāng)我繼續(xù)添加新功能和新的數(shù)據(jù)結(jié)構(gòu)支持進(jìn)去OrcaMDF軟件的時(shí)候,bug的風(fēng)險(xiǎn)不斷增加
特別是當(dāng)我開(kāi)發(fā)一個(gè)很大的未知功能時(shí),我不能預(yù)估結(jié)構(gòu)和該結(jié)構(gòu)的關(guān)聯(lián),為了降低風(fēng)險(xiǎn),測(cè)試是很有必要的
?
單元測(cè)試
單元測(cè)試是在面向?qū)ο缶幊汤餃y(cè)試源代碼某一個(gè)功能的最小一部分的測(cè)試。一個(gè)測(cè)試的例子是SqlBigInt數(shù)據(jù)類型解析類,
他應(yīng)該長(zhǎng)這個(gè)樣子
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]));}} }這個(gè)測(cè)試包含了SqlBigInt 類的主入口點(diǎn),測(cè)試long?bigint 數(shù)據(jù)類型是否會(huì)造成上溢或下溢的情況,也包含長(zhǎng)度檢查。
對(duì)于像SqlBigInt這樣簡(jiǎn)單的類型單元測(cè)試會(huì)工作得很好。有時(shí)候單元測(cè)試會(huì)很復(fù)雜當(dāng)相關(guān)聯(lián)的類需要調(diào)用相應(yīng)方法,類等支持他運(yùn)行的底層結(jié)構(gòu)的時(shí)候(mock測(cè)試)
雖然這是一個(gè)工作策略,測(cè)試需要不斷進(jìn)行,特別在項(xiàng)目早期階段,整個(gè)架構(gòu)都是動(dòng)態(tài)的
?
系統(tǒng)測(cè)試
在測(cè)試范圍上,我們需要更大的范圍測(cè)試 -系統(tǒng)測(cè)試。系統(tǒng)測(cè)試旨在測(cè)試系統(tǒng)作為一個(gè)整體,基本上忽略系統(tǒng)內(nèi)部工作原理
如果要分類的話可以被分為 黑盒測(cè)試。對(duì)于OrcaMDF,我估計(jì)可以捕獲90%的所有的regressions?只使用10%的時(shí)間,
相比起單元測(cè)試使用更多時(shí)間只捕獲少量的regressions 。
因此,這是一個(gè)很好的方法在開(kāi)發(fā)期間的測(cè)試,同時(shí)可以引入關(guān)鍵的單元測(cè)試和集成測(cè)試。
例如我想測(cè)試DatabaseMetaData 類里面的用戶表名字的解析,我可以模擬SysObjects的值列表,同時(shí)對(duì)于DatabaseMetaData 類
的構(gòu)造函數(shù)也能模擬MdfFile 所必須的參數(shù),為了做到這一點(diǎn),我必須從MdfFile 提取出一個(gè)接口并且在上面使用mocking framework
?
系統(tǒng)測(cè)試的方法執(zhí)行以下流程:
1、連接到SQLSERVER實(shí)例
2、在測(cè)試固件(Test fixture)里創(chuàng)建測(cè)試架構(gòu)
3、分離數(shù)據(jù)庫(kù)
4、運(yùn)行OrcaMDF 并加載分離的數(shù)據(jù)庫(kù)驗(yàn)證結(jié)果
?
一個(gè)測(cè)試樣例,創(chuàng)建兩個(gè)用戶表并且驗(yàn)證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();}} }?
在實(shí)際的真實(shí)生活場(chǎng)景里這樣可以非常快速的進(jìn)行測(cè)試。想測(cè)試轉(zhuǎn)發(fā)記錄的解析?只需要簡(jiǎn)單地創(chuàng)建一個(gè)新的測(cè)試
編寫TSQL代碼來(lái)生成目標(biāo)數(shù)據(jù)庫(kù)狀態(tài)然后驗(yàn)證掃描到的表數(shù)據(jù)
?
系統(tǒng)測(cè)試的缺點(diǎn)
不幸的是系統(tǒng)測(cè)試不是萬(wàn)能藥,它也有它的缺點(diǎn)。最明顯的一個(gè)缺點(diǎn)是性能。
單元測(cè)試通常需要運(yùn)行非常快,基本上允許您在每個(gè)文件保存后在后臺(tái)運(yùn)行它們。從綁定CPU開(kāi)始到運(yùn)行 ,每一個(gè)這樣的系統(tǒng)測(cè)試都需要半秒
幸運(yùn)的是,它們可以并行運(yùn)行沒(méi)有問(wèn)題。在一臺(tái)四核的機(jī)器能讓我每分鐘運(yùn)行480個(gè)測(cè)試。這能夠讓一個(gè)完整的測(cè)試集合控制在合理的時(shí)間,
同時(shí)依然保持測(cè)試子集能夠很快運(yùn)行。通常代碼的更改不會(huì)對(duì)測(cè)試造成太多的影響
?
第六篇完
總結(jié)
以上是生活随笔為你收集整理的解剖SQLSERVER 第六篇 对OrcaMDF的系统测试里避免regressions(译)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: LinQ to entities 不能识
- 下一篇: 明尼苏达推荐系统导论(第一课 欢迎来到R