2010-07-28 13 views
7

मैं एक परियोजना की डेटा एक्सेस परत इकाई परीक्षण पर पढ़ रहा हूं। डेटाबेस एक समर्पित परीक्षण डेटाबेस लेकिन सभी इकाई परीक्षण के अंतिम रूप दिया जा चरण में सफाईइकाई डेटा एक्सेस लेयर का परीक्षण

  • उपयोग (या मैन्युअल रूप से ऐसा)
  • उपयोग लेकिन प्रतिबद्ध नहीं है या बस वापस रोल
  • : अधिकांश विकल्पों के लिए नीचे उबाल
  • डेटाबेस

एक पूर्व प्रोजेक्ट में हम रोलबैक तरीके का उपयोग करते थे, लेकिन मैं अन्य विकल्पों के बारे में और अधिक सर्वोत्तम प्रदर्शन करने के बारे में और जानना चाहता हूं। यदि आपके पास नमूने/लेख/वीडियो/हैं ... कृपया उन्हें साझा करें।

उत्तर

3

आपको किसी प्रोजेक्ट के साथ 2 प्रकार के परीक्षण होने की आवश्यकता है। यूनिट परीक्षण और एकीकरण परीक्षण

यूनिट परीक्षण डेटा प्रोजेक्ट और प्रस्तुति पर निर्भरताओं के बिना आपकी परियोजना के एक पहलू का परीक्षण करते हैं। यूनिट परीक्षणों के लिए आप डेटा प्रदाता से अपने कोड को बेकार करने के लिए अपने डेटाबेस और उपयोगकर्ता निर्भरता इंजेक्शन का नकल करेंगे। इससे बेहतर आर्किटेक्चर होता है और यदि आप चाहें तो आपको एक अलग डेटा प्रदाता में प्लग करने में सक्षम बनाता है। जैसे ADO.net से nHibernate तक जा रहा है।

एकीकरण परीक्षण वे हैं जहां आप अपने पूरे सिस्टम का परीक्षण करते हैं और सुनिश्चित करते हैं कि आपका कोड डेटाबेस से सही डेटा प्राप्त कर सके। एकीकरण परीक्षण के लिए प्रत्येक डेवलपर के पास उनके वर्कस्टेशन पर डेटाबेस की प्रति होना चाहिए जिसके खिलाफ वे परीक्षण कर सकते हैं। आपको अपने डेटाबेस के निर्माण और आबादी को स्वचालित करने की कोशिश करनी चाहिए ताकि आप डेटाबेस की एक अच्छी प्रतिलिपि पर जल्दी और आसानी से वापस जा सकें। nant और DBFit जैसे टूल आपको अपने डेटाबेस निर्माण को स्क्रिप्ट करने में मदद करेंगे।

मैं परीक्षण करने के लिए केंद्रीय डेटाबेस का उपयोग नहीं करता क्योंकि अन्य डेवलपर्स एक ही समय में इसका परीक्षण कर सकते हैं और यह एक अच्छी स्थिति में नहीं हो सकता है और आप झूठी सकारात्मक प्राप्त कर सकते हैं और किसी समस्या को डीबग करने की कोशिश कर रहे आयु खर्च कर सकते हैं जो कोई समस्या नहीं है।

2

मैं के बजाय एक परीक्षण डेटाबेस का उपयोग करना पसंद करता हूं विचार नहीं।

मेरे देव डेटाबेस में डमी रिकॉर्ड या उत्पादन डेटा का पूरी तरह से sanitized नमूना है।

मेरा एकीकरण परीक्षण डेटाबेस वास्तविक उत्पादन डेटाबेस की एक प्रति है (यह संस्करण वह है जिसे मैं लाइव में परिवर्तन करने से पहले परीक्षण करने के लिए उपयोग किया जाता है)।

0

मैं डेटाबेस का मज़ाक उड़ाऊंगा। एक परीक्षण में डेटाबेस से निपटना दर्दनाक है क्योंकि आपको डेटाबेस बनाने, स्कीमा बनाने की आवश्यकता है, फिर इसे छोड़ दें, सुनिश्चित करें कि आसपास लटकने वाले कोई कनेक्शन नहीं हैं, आदि दर्दनाक है।

एक और चीज जो मुझे असहज बनाती है यह तथ्य है कि कोड कोड को सत्यापित करना कोड से "बहुत दूर" है। मैं एक नकली वर्ग के पीछे एसक्यूएल फ़ंक्शंस (कनेक्शन, कमांड इत्यादि) डालने की सड़क पर जाउंगा और सत्यापित करूंगा कि डीएएल सही तरीकों को कॉल करता है। इसके अलावा, परीक्षण इस तरह से बहुत तेजी से चलते हैं।

यहां कुछ त्वरित एसक्यूएल एब्स्ट्रक्शन कक्षाएं और उदाहरण उपयोग + यूनिट परीक्षण हैं।

public class SqlConnectionBase : IDisposable { 
    private readonly SqlConnection m_Connection; 

    public SqlConnectionBase(string connString) { 
     m_Connection = new SqlConnection(connString); 
    } 

    public virtual SqlConnection Object { get { return m_Connection; } } 

    public virtual void Open() { 
     m_Connection.Open(); 
    } 
    public virtual void Close() { 
     m_Connection.Close(); 
    } 

    #region IDisposable Members 

    public virtual void Dispose() { 
     m_Connection.Dispose(); 
    } 

    #endregion 
} 

public class SqlCommandBase : IDisposable{ 
    private readonly SqlCommand m_Command; 

    public SqlCommandBase() { 
     m_Command = new SqlCommand(); 
    } 
    public SqlCommandBase(string cmdText, SqlConnectionBase connection) { 
     m_Command = new SqlCommand(cmdText, connection.Object); 
    } 
    public SqlCommandBase(SqlConnectionBase connection) { 
     m_Command = new SqlCommand(); 
     m_Command.Connection = connection.Object; 
    } 

    public virtual int ExecuteNonQuery() { return m_Command.ExecuteNonQuery(); } 
    public virtual string CommandText { get { return m_Command.CommandText; } set { m_Command.CommandText = value; } } 

    public virtual void AddParameter(SqlParameter sqlParameter) { 
     m_Command.Parameters.Add(sqlParameter); 
    } 

    #region IDisposable Members 

    virtual public void Dispose() { 
     m_Command.Dispose(); 
    } 

    #endregion 
} 
public class SqlFactory { 
    public virtual SqlCommandBase CreateCommand(string query, SqlConnectionBase conn) { 
     return new SqlCommandBase(query, conn); 
    } 
    public virtual SqlCommandBase CreateCommand(SqlConnectionBase conn) { 
     return new SqlCommandBase(conn); 
    } 

    public virtual SqlConnectionBase CreateConnection(string connString) { 
     return new SqlConnectionBase(connString); 
    } 

} 

public class DBUser { 
    public DBUser(SqlFactory factory) { 
    m_factory = factory; //dependency constructor, will be used during unit testing 
    } 

    public DBUser() { 
    m_factory = new SqlFactory(); //used during normal execution 
    } 

    public void DoSomething() { 
    var conn = m_factory.CreateConnection("server=servername,database=..."); 
    var cmd = m_factory.CreateCommand(conn); 
    cmd.CommandText = "Select * from users"; 
    cmd.ExecuteNonQuery(); 
    } 

    [TestMethod] 
    public void DoSomethingTest() { 
    var factoryMock = new Mock<SqlFactory>(); 
    var cmdMock = new Mock<CommandBase>(); 
    factoryMock.Setup(f=>f.CreateConnection(It.IsAny<string>())).Returns(cmdMock.Object); 
    DBUser dbUser = new DBUser(factoryMock.Object); 
    dbUser.DoSomething(); 

    //Verify that DoSomething is called. 
    cmdMock.Verify(c=>c.DoSomething()); 
    } 
} 
+0

परीक्षण इस तरह से बहुत तेज़ी से चलते हैं: मैं कल्पना कर सकता हूं। क्या आपके पास वर्णित कुछ नमूना कोड है? – XIII

+0

मेरे पास बिट्स और टुकड़े हैं, मैं गंभीर रूप से 'System.Sql.Abstractions' लाइब्रेरी लिखने पर विचार कर रहा हूं, हालांकि [System.IO.Abstractions] के समान (http://systemioabstractions.codeplex.com/) –

1

डीएएल की मुख्य जिम्मेदारी डेटाबेस से डेटा को जारी/लाने के लिए है, इसलिए परीक्षण के तहत सिस्टम डीएएल + डाटाबेस है। डाटाबेस मॉक का उपयोग करके डीएएल पर परीक्षण लिखने की कोई संभावना नहीं है - जो वास्तव में परवाह करता है कि विशेष इकाई लाने के लिए कौन सी एसक्यूएल क्वेरी निष्पादित की गई थी?यह सत्यापित करने के लिए अनिवार्य है कि सही इकाई का चयन किया गया था या सभी विशेषताओं को सही तरीके से मैप किया गया था।

ऐसा करने के लिए मैं आमतौर पर डेटाबेस साफ़ करता हूं, परीक्षण डेटा के साथ डेटाबेस भरता हूं और इसे डीएएल विधियों के साथ लाता हूं।

 [SetUp] 
    public void SetUp() 
    { 
     Database.Clear(); 
     manager = new ServiceManager(); 
    } 

    [TearDown] 
    public void TearDown() 
    { 
     manager.Dispose(); 
    } 

    [Test] 
    public void InsertAndLoadOrderContract() 
    { 
     MinOrderModel model = new OrderBuilder().InsertMinimalOrder(manager); 

     Contract contract = TestObjectGenerator.GenerateEntity<Contract>(); 
     manager.Contract.InsertOrderContract(model.Order.OrderCompositeId, contract); 

     Contract selectedContract = manager.Contract.SelectById(contract.ContractId); 

     AssertContract(selectedContract, contract); 
    } 

    private static void AssertContract(IContract actual, IContract expected) 
    { 
     Assert.That(actual.AgencyCodeOther, Is.EqualTo(expected.AgencyCodeOther)); 
     Assert.That(actual.AgencyFK, Is.EqualTo(expected.AgencyFK)); 
     Assert.That(actual.ContractId, Is.EqualTo(expected.ContractId)); 
     Assert.That(actual.Ident, Is.EqualTo(expected.Ident)); 
    } 

इस परीक्षण के कुछ हिस्सों और अधिक सुविधाजनक वालों पर बदला जा सकता है:

  1. यह DbUnit उपयोग करने के लिए डेटा के साथ डेटाबेस को भरने के लिए
  2. डेटाबेस लेकिन रोल को साफ न करें संभव है "टीयरडाउन" में वापस लेनदेन विधि
  3. परीक्षणों के लिए अधिक सुविधाजनक डेटाबेस इंजन का उपयोग करें (उदाहरण के लिए SQLLite)
संबंधित मुद्दे