A. 軟體開發資料庫如何進行測試
比如:數據冗餘,功能和性能方面存在的問題已經嚴重影響應用軟體的使用。軟體測試人員往往重視對軟體功能和編碼的測試,而忽略對軟體性能,特別是資料庫訪問並發測試。因為,他們固有的思想中認為資料庫設計存在問題對系統性能影響不大,或從根本上忽略了資料庫在軟體開發中的地位,直到出現了問題,才想到對資料庫的測試,但往往也是僅僅通過對編碼的測試工作中捎帶對資料庫進行一定的測試,這遠遠是不夠的。目前,中鐵網上訂票系統在大用戶同時在線訂票中系統頻頻癱瘓,就是最好的佐證。 所以,在應用軟體的測試工作中,應該將資料庫作為一個獨立的部分進行充分的測試,這樣才可以得到應用軟體所需要的性能優化的資料庫。那麼,應該對哪些內容進行測試,如何進行測試呢? 2、資料庫設計的測試 資料庫是應用的基礎,其性能直接影響應用軟體的性能。為了使資料庫具有較好的性能,需要對資料庫中的表進行規范化設計。規范化的範式可分為第一範式、第二範式、第三範式、BCNF範式、第四範式和第五範式。一般來說,邏輯資料庫設計應滿足第三範式的要求,這是因為滿足第三範式的表結構容易維護,且基本滿足實際應用的要求。因此,實際應用中一般都按照第三範式的標准進行規范化。但是,規范化也有缺點:由於將一個表拆分成為多個表,在查詢時需要多表連接,降低了查詢速度。故資料庫設計的測試包括前期需求分析產生資料庫邏輯模型和後期業務系統開發中的測試兩部分(這里指的是後者),我在這里稱為實體測試。 資料庫是由若乾的實體組成的,包括(表,視圖,存儲過程等),資料庫最基本的測試就是實體測試,通過對這些實體的測試,可以發現資料庫實體設計得是否充分,是否有遺漏,每個實體的內容是否全面,擴展性如何。 實體測試,可以用來發現應用軟體在功能上存在的不足,也可以發現數據冗餘的問題。經過測試,測試人員對有異議的問題要及時和資料庫的設計人員進行溝通解決。 3、數據一致性測試 在進行實體測試後,應進一步檢查下面的內容以保障數據的一致性: 3.1 表的主鍵測試根據應用系統的實際需求,對每個表的主鍵進行測試,驗證是否存在記錄不唯一的情況,如果有,則要重新設置主鍵,使表中記錄唯一。 3.2 表之間主外鍵關系的測試資料庫中主外鍵欄位在名稱,數據類型,欄位長度上的一致性測試。 3.3 級聯表,刪除主表數據後,相應從報表數據應同時刪除的問題例如學生表和學生成績表,學生數據已經刪除,成績表中相應學生的成績記錄應同時刪除。 3.4 存儲過程和觸發器的測試存儲過程可以人工執行,但觸發器不能人工處理,所以在對存儲過程和觸發器執行的過程中針對SQL SERVER2005及以上版本可以使用Microsoft SQL Server Profiler性能測試工具進行測試。 Microsoft SQL Server Profiler 是 SQL 跟蹤的圖形用戶界面,用於監視資料庫引擎或 Analysis Services 的實例。測試人員可以捕獲有關每個事件的數據並將其保存到文件或表中供以後分析。例如:可以對生產環境進行監視,了解哪些存儲過程由於執行速度太慢影響了性能。 4、資料庫的容量測試 隨著資料庫系統的使用,數據量在飛速增長,如何在使用前對數據容量的增長情況進行初步估算,為最終用戶提供參考,這在資料庫使用和維護過程中,是非常重要的。可以通過對資料庫設計中基本表的數據大小,和每天數據表的數據產生量進行初步估算。 記錄數據量=各個欄位所佔位元組數的總和表的數據量=記錄數據量*記錄數資料庫大小=各表數據量的總和 當然,資料庫的大小不僅僅只是基本表的大小,還有系統表,視圖,存儲過程等其它實體所佔的容量,但最基本的數據是表的數據。另外,資料庫的容量還包括資料庫日誌文件的容量,一般應預留資料庫文件的2倍左右。 5、資料庫的性能測試 應用軟體除了功能外,很重要的一部分就是軟體的性能,而對於資料庫系統,資料庫性能的好壞會直接影響應用軟體的性能,這部分的測試,一般手工測試就顯得無能為力了,這時就要藉助自動化的測試軟體,例如:DataFactory,DataFactory是一種強大的數據產生器,它允許開發人員和測試人員很容易產生百萬行有意義的正確的測試資料庫,該工具支持DB2、Oracle、Sybase、SQL Server資料庫。這樣,就可以模擬出應用軟體長期使用後,海量數據存儲的資料庫的性能狀況。從而盡早發現問題,進行資料庫性能的優化。 這里要注意,進行性能測試的時候,一定要注意測試環境的一致性,包括:操作系統、應用軟體的版本以及硬體的配置等,而且在進行資料庫方面的測試的時候一定要注意資料庫的記錄數、配置等要一致,只有在相同條件下進行測試,才可以對結果進行比較。否則無法和用戶對軟體的性能的觀點達成一致。 6、資料庫的壓力測試 說起測試,我們首先想到的就是軟體正確性的測試,即常說的功能測試。軟體功能正確僅是軟體質量合格指標之一。在實際開發中,還有其它的非功能因素也起著決定性的因素,例如軟體的響應速度。影響軟體響應速度的因素有很多,有些是因為演算法不夠高效;還有些可能受用戶並發數的影響。 在眾多類型的軟體測試中,壓力測試正是以軟體響應速度為測試目標,尤其是針對在較短時間內大量並發用戶的訪問時,軟體的抗壓能力。但壓力測試往往是手工難以測試的,必須藉助自動化測試工具。常用的壓力測試有:Web測試、資料庫測試等。 資料庫在大多數軟體項目中是不可缺少的,對於它進行壓力測試是為了找出資料庫對象是否可以有效地承受來自多個用戶的並發訪問。這些對象主要是:索引、觸發器、存儲過程和鎖。通過對SQL語句和存儲過程的測試,自動化的壓力測試工具可以間接的反應資料庫對象是否需要優化。 這些自動化的測試工具很多,各有特點,基於Java的項目可以使用JMeter,.Net項目可以採用.Net集成開發環境中提供的測試方案。 7、結束語 總之,在應用系統的測試中,把資料庫應當作為獨立的系統來測試,這無疑會為應用軟體的質量增加可靠的保障,同時還必須結合應用軟體進行集成測試,只有二者有機結合起來,才能最大限度的發揮資料庫和應用軟體的功能。
B. 如何:編寫在單個事務范圍內運行的資料庫單元測試
如果您使用此方法,則可以在測試結束之後回滾在測試過程中執行的任何更改。下面的過程說明了具體的做法:在使用 BEGIN TRANSACTION 和ROLLBACK TRANSACTION 的Transact-SQL 測試腳本中創建事務。為某個測試類中的單個測試方法創建一個事務。為給定測試類中的所有測試方法創建一個事務。系統必備組件對於本主題中的某些過程,運行單元測試的計算機必須正在運行 Distributed Transaction Coordinator 服務。有關更多信息,請參見本主題末尾的過程。使用Transact-SQL 創建事務使用Transact-SQL 創建事務在資料庫單元測試設計器中打開單元測試。指定要創建事務的腳本類型。例如,可以指定預先測試、測試或後期測試。在Transact-SQL 編輯器中輸入測試腳本。插入BEGIN TRANSACTION 和ROLLBACK TRANSACTION 語句,如下面的簡單示例所示。此示例使用名為 OrderDetails 並包含 50 行數據的資料庫表:BEGIN TRANSACTION TestTransaction UPDATE "OrderDetails" set Quantity = Quantity + 10 IF @@ROWCOUNT!=50 RAISERROR('Row count does not equal 50',16,1) ROLLBACK TRANSACTION TestTransaction注意在執行 COMMIT TRANSACTION 語句之後不能對事務進行回滾。有關ROLLBACK TRANSACTION 如何與存儲過程和觸發器一起使用的更多信息,請參見 Microsoft 網站上的 ROLLBACK TRANSACTION (Transact-SQL)。為單個測試方法創建事務在該示例中,在使用 TransactionScope 類型時,會使用環境事務。默認情況下,「執行連接」和「特權連接」將不使用環境事務,因為這些連接是在執行該方法之前創建的。SqlConnection 具有一個 EnlistTransaction 方法,該方法將活動連接與某個事務相關聯。環境事務在創建之後會自行注冊為當前的事務,您可以通過 Current 屬性來訪問它。在該示例中,環境事務在釋放之後進行回滾。如果要提交在運行單元測試時進行的任何更改,則必須調用 Complete 方法。為單個測試方法創建事務在「解決方案資源管理器」中,右擊測試項目中的「引用」節點,然後單擊「添加引用」。將顯示"添加引用"對話框。單擊「.NET」選項卡。在程序集列表中,單擊「System.Transactions」,然後單擊「確定」。打開單元測試的 Visual Basic 或 C# 文件。包裝預先測試、測試和後期測試操作,如下面的 Visual Basic 代碼示例所示: <TestMethod()> _ Public Sub dbo_InsertTable1Test() Using ts as New System.Transactions.TransactionScope( System.Transactions.TransactionScopeOption.Required) ExecutionContext.Connection.EnlistTransaction(Transaction.Current) PrivilegedContext.Connection.EnlistTransaction(Transaction.Current) Dim testActions As DatabaseTestActions = Me.dbo_InsertTable1TestData 'Execute the pre-test script ' System.Diagnostics.Trace.WriteLineIf((Not (testActions.PretestAction) Is Nothing), "Executing pre-test script...") Dim pretestResults() As ExecutionResult = TestService.Execute(Me.PrivilegedContext, Me.PrivilegedContext, testActions.PretestAction) 'Execute the test script System.Diagnostics.Trace.WriteLineIf((Not (testActions.TestAction) Is Nothing), "Executing test script...") Dim testResults() As ExecutionResult = TestService.Execute(ExecutionContext, Me.PrivilegedContext, testActions.TestAction) 'Execute the post-test script ' System.Diagnostics.Trace.WriteLineIf((Not (testActions.PosttestAction) Is Nothing), "Executing post-test script...") Dim posttestResults() As ExecutionResult = TestService.Execute(Me.PrivilegedContext, Me.PrivilegedContext, testActions.PosttestAction) 'Because the transaction is not explicitly committed, it 'is rolled back when the ambient transaction is 'disposed. 'To commit the transaction, remove the comment delimiter 'from the following statement: 'ts.Complete() End Sub Private dbo_InsertTable1TestData As DatabaseTestActions注意如果使用的是 Visual Basic,則除了 Imports Microsoft.VisualStudio.TestTools.UnitTesting、Imports Microsoft.VisualStudio.TeamSystem.Data.UnitTesting 和Imports Microsoft.VisualStudio.TeamSystem.Data.UnitTest.Conditions,還必須添加 Imports System.Transactions。如果使用的是 Visual C#,則除了 Microsoft.VisualStudio.TestTools、Microsoft.VisualStudio.TeamSystem.Data.UnitTesting 和 Microsoft.VisualStudio.TeamSystem.Data.UnitTesting.Conditions 的 using 語句,還必須添加 using System.Transactions。還必須在這些程序集中添加對項目的引用。為某個測試類中的所有測試方法創建一個事務為某個測試類中的所有測試方法創建一個事務打開單元測試的 Visual Basic 或 C# 文件。在TestInitialize 中創建事務,並在 TestCleanup 中釋放它,如下面的 Visual C# 代碼示例所示:TransactionScope _trans; [TestInitialize()] public void Init() { _trans = new TransactionScope(); base.InitializeTest(); } [TestCleanup()] public void Cleanup() { base.CleanupTest(); _trans.Dispose(); } [TestMethod()] public void TransactedTest() { DatabaseTestActions testActions = this.DatabaseTestMethod1Data; // Execute the pre-test script // System.Diagnostics.Trace.WriteLineIf((testActions.PretestAction != null), "Executing pre-test script..."); ExecutionResult[] pretestResults = TestService.Execute(this.PrivilegedContext, this.PrivilegedContext, testActions.PretestAction); // Execute the test script // System.Diagnostics.Trace.WriteLineIf((testActions.TestAction != null), "Executing test script..."); ExecutionResult[] testResults = TestService.Execute(this.ExecutionContext, this.PrivilegedContext, testActions.TestAction); // Execute the post-test script // System.Diagnostics.Trace.WriteLineIf((testActions.PosttestAction != null), "Executing post-test script..."); ExecutionResult[] posttestResults = TestService.Execute(this.PrivilegedContext, this.PrivilegedContext, testActions.PosttestAction); }啟動Distributed Transaction Coordinator 服務本主題中的某些過程使用 System.Transactions 程序集內的類型。在按照這些過程操作之前,必須確保要運行單元測試的計算機上正在運行 Distributed Transaction Coordinator 服務。否則,測試將失敗,並出現下面的錯誤消息:「測試方法 項目名稱.測試名稱.方法名稱 引發異常: System.Data.SqlClient.SqlException: 伺服器『計算機名稱』上的 MSDTC 不可用」。啟動Distributed Transaction Coordinator 服務打開「控制面板」。在「控制面板」中打開「管理工具」。在「管理工具」中打開「服務」。在「服務」窗格中,右擊 「Distributed Transaction Coordinator」 服務,再單擊「啟動」。該服務的狀態應當更新為「已啟動」。現在應當能夠運行那些使用 System.Transactions 的單元測試。重要事項即使您啟動了分布式事務處理控制器服務,仍然可能出現以下錯誤:System.Transactions.: Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool. ---> System.Runtime.InteropServices.COMException: The transaction manager has disabled its support for remote/network transactions. (Exception from HRESULT: 0x8004D024)。如果出現此錯誤,您必須為網路訪問配置分布式事務處理控制器。有關更多信息,請參見啟用網路 DTC 訪問 。
C. 請問.net mvc 怎麼對EF中對資料庫的增刪改查通過mock單元測試
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Web;
usingSystem.Data.Entity;
usingSystem.ComponentModel.DataAnnotations;
namespacekwstu.Models
{
publicclassSys_User
{
#regionModel
[Required(ErrorMessage="ID號是必須的!")]
publicstringID{get;set;}
[Required(ErrorMessage="系統ID號是必須的!")]
publicstringSYSID{get;set;}
[StringLength(5,ErrorMessage="最多20個字元!")]
publicstringUSER_NAME{get;set;}
publicstringUSER_PASSWORD{get;set;}
publicstringUSER_FULLNAME{get;set;}
publicstringUSER_TYPE{get;set;}
publicstringUSER_POWER{get;set;}
publicstringUSER_SCOPE1{get;set;}
publicstringUSER_SCOPE2{get;set;}
publicstringUSER_SCOPE3{get;set;}
publicstringUSER_SCOPE4{get;set;}
publicstringUSER_MANAGE{get;set;}
publicstringLOGIN_IP{get;set;}
publicstringLOGIN_MARK{get;set;}
publicstringIMAGE_PATH{get;set;}
publicstringREMARK{get;set;}
#endregionModel
}
publicclassKwstuDbContext:DbContext
{
publicDbSet<Sys_User>Sys_User{get;set;}
}
}