هل حقق أي شخص أي نجاح في وحدة اختبار إجراءات SQL المخزنة؟

StackOverflow https://stackoverflow.com/questions/12374

  •  08-06-2019
  •  | 
  •  

سؤال

لقد وجدنا أن اختبارات الوحدة التي كتبناها لكود C#/C++ الخاص بنا قد أتت بثمارها بالفعل.ولكن لا يزال لدينا الآلاف من خطوط منطق الأعمال في الإجراءات المخزنة، والتي يتم اختبارها فقط في حالة الغضب عندما يتم طرح منتجنا لعدد كبير من المستخدمين.

ما يجعل الأمر أسوأ هو أن بعض هذه الإجراءات المخزنة ينتهي بها الأمر إلى أن تكون طويلة جدًا، بسبب الأداء الذي يصل عند تمرير الجداول المؤقتة بين مقدمي الخدمات.لقد منعنا هذا من إعادة البناء لجعل الكود أكثر بساطة.

لقد قمنا بعدة محاولات لبناء اختبارات الوحدة حول بعض إجراءاتنا المخزنة الرئيسية (اختبار الأداء في المقام الأول)، ولكننا وجدنا أن إعداد بيانات الاختبار لهذه الاختبارات أمر صعب حقًا.على سبيل المثال، ينتهي بنا الأمر بالنسخ حول قواعد بيانات الاختبار.بالإضافة إلى ذلك، تصبح الاختبارات حساسة جدًا للتغيير، وحتى لأصغر تغيير في العملية المخزنة.أو يتطلب الجدول قدرًا كبيرًا من التغييرات في الاختبارات.لذا، بعد تعطل العديد من الإصدارات بسبب فشل اختبارات قاعدة البيانات هذه بشكل متقطع، كان علينا سحبها من عملية البناء.

لذا فإن الجزء الرئيسي من أسئلتي هو:هل نجح أي شخص في كتابة اختبارات الوحدة لإجراءاته المخزنة؟

الجزء الثاني من أسئلتي هو ما إذا كان اختبار الوحدة سيكون/أسهل مع linq؟

كنت أفكر أنه بدلاً من الاضطرار إلى إعداد جداول بيانات الاختبار، يمكنك ببساطة إنشاء مجموعة من كائنات الاختبار واختبار كود linq الخاص بك في موقف "ربط الكائنات"؟(أنا جديد تمامًا على linq لذا لا أعرف ما إذا كان هذا سيعمل على الإطلاق)

هل كانت مفيدة؟

المحلول

لقد واجهت نفس المشكلة منذ فترة ووجدت أنه إذا قمت بإنشاء فئة أساسية مجردة بسيطة للوصول إلى البيانات التي سمحت لي بإدخال اتصال ومعاملة، فيمكنني اختبار الوحدة الخاصة بي sprocs لمعرفة ما إذا كانوا قد قاموا بالعمل في SQL الذي أقوم به طلب منهم القيام بذلك ثم التراجع حتى لا يتم ترك أي من بيانات الاختبار في قاعدة البيانات.

كان هذا أفضل من المعتاد "تشغيل برنامج نصي لإعداد قاعدة بيانات الاختبار الخاصة بي، ثم بعد تشغيل الاختبارات، قم بتنظيف البيانات غير المرغوب فيها/الاختبار".بدا هذا أيضًا أقرب إلى اختبار الوحدة لأنه يمكن إجراء هذه الاختبارات بمفردها دون الحاجة إلى قدر كبير من "يجب أن يكون كل شيء في قاعدة البيانات "تمامًا" قبل إجراء هذه الاختبارات".

فيما يلي مقتطف من الفئة الأساسية المجردة المستخدمة للوصول إلى البيانات

Public MustInherit Class Repository(Of T As Class)
    Implements IRepository(Of T)

    Private mConnectionString As String = ConfigurationManager.ConnectionStrings("Northwind.ConnectionString").ConnectionString
    Private mConnection As IDbConnection
    Private mTransaction As IDbTransaction

    Public Sub New()
        mConnection = Nothing
        mTransaction = Nothing
    End Sub

    Public Sub New(ByVal connection As IDbConnection, ByVal transaction As IDbTransaction)
        mConnection = connection
        mTransaction = transaction
    End Sub

    Public MustOverride Function BuildEntity(ByVal cmd As SqlCommand) As List(Of T)

    Public Function ExecuteReader(ByVal Parameter As Parameter) As List(Of T) Implements IRepository(Of T).ExecuteReader
        Dim entityList As List(Of T)
        If Not mConnection Is Nothing Then
            Using cmd As SqlCommand = mConnection.CreateCommand()
                cmd.Transaction = mTransaction
                cmd.CommandType = Parameter.Type
                cmd.CommandText = Parameter.Text
                If Not Parameter.Items Is Nothing Then
                    For Each param As SqlParameter In Parameter.Items
                        cmd.Parameters.Add(param)
                    Next
                End If
                entityList = BuildEntity(cmd)
                If Not entityList Is Nothing Then
                    Return entityList
                End If
            End Using
        Else
            Using conn As SqlConnection = New SqlConnection(mConnectionString)
                Using cmd As SqlCommand = conn.CreateCommand()
                    cmd.CommandType = Parameter.Type
                    cmd.CommandText = Parameter.Text
                    If Not Parameter.Items Is Nothing Then
                        For Each param As SqlParameter In Parameter.Items
                            cmd.Parameters.Add(param)
                        Next
                    End If
                    conn.Open()
                    entityList = BuildEntity(cmd)
                    If Not entityList Is Nothing Then
                        Return entityList
                    End If
                End Using
            End Using
        End If

        Return Nothing
    End Function
End Class

بعد ذلك سترى نموذجًا لفئة الوصول إلى البيانات باستخدام القاعدة المذكورة أعلاه للحصول على قائمة بالمنتجات

Public Class ProductRepository
    Inherits Repository(Of Product)
    Implements IProductRepository

    Private mCache As IHttpCache

    'This const is what you will use in your app
    Public Sub New(ByVal cache As IHttpCache)
        MyBase.New()
        mCache = cache
    End Sub

    'This const is only used for testing so we can inject a connectin/transaction and have them roll'd back after the test
    Public Sub New(ByVal cache As IHttpCache, ByVal connection As IDbConnection, ByVal transaction As IDbTransaction)
        MyBase.New(connection, transaction)
        mCache = cache
    End Sub

    Public Function GetProducts() As System.Collections.Generic.List(Of Product) Implements IProductRepository.GetProducts
        Dim Parameter As New Parameter()
        Parameter.Type = CommandType.StoredProcedure
        Parameter.Text = "spGetProducts"
        Dim productList As List(Of Product)
        productList = MyBase.ExecuteReader(Parameter)
        Return productList
    End Function

    'This function is used in each class that inherits from the base data access class so we can keep all the boring left-right mapping code in 1 place per object
    Public Overrides Function BuildEntity(ByVal cmd As System.Data.SqlClient.SqlCommand) As System.Collections.Generic.List(Of Product)
        Dim productList As New List(Of Product)
        Using reader As SqlDataReader = cmd.ExecuteReader()
            Dim product As Product
            While reader.Read()
                product = New Product()
                product.ID = reader("ProductID")
                product.SupplierID = reader("SupplierID")
                product.CategoryID = reader("CategoryID")
                product.ProductName = reader("ProductName")
                product.QuantityPerUnit = reader("QuantityPerUnit")
                product.UnitPrice = reader("UnitPrice")
                product.UnitsInStock = reader("UnitsInStock")
                product.UnitsOnOrder = reader("UnitsOnOrder")
                product.ReorderLevel = reader("ReorderLevel")
                productList.Add(product)
            End While
            If productList.Count > 0 Then
                Return productList
            End If
        End Using
        Return Nothing
    End Function
End Class

والآن في اختبار الوحدة الخاصة بك، يمكنك أيضًا أن ترث من فئة أساسية بسيطة جدًا تقوم بعمل الإعداد/التراجع - أو الاحتفاظ بهذا على أساس اختبار كل وحدة

فيما يلي فئة الاختبار الأساسية البسيطة التي استخدمتها

Imports System.Configuration
Imports System.Data
Imports System.Data.SqlClient
Imports Microsoft.VisualStudio.TestTools.UnitTesting

Public MustInherit Class TransactionFixture
    Protected mConnection As IDbConnection
    Protected mTransaction As IDbTransaction
    Private mConnectionString As String = ConfigurationManager.ConnectionStrings("Northwind.ConnectionString").ConnectionString

    <TestInitialize()> _
    Public Sub CreateConnectionAndBeginTran()
        mConnection = New SqlConnection(mConnectionString)
        mConnection.Open()
        mTransaction = mConnection.BeginTransaction()
    End Sub

    <TestCleanup()> _
    Public Sub RollbackTranAndCloseConnection()
        mTransaction.Rollback()
        mTransaction.Dispose()
        mConnection.Close()
        mConnection.Dispose()
    End Sub
End Class

وأخيرًا - ما يلي هو اختبار بسيط باستخدام فئة الاختبار الأساسية التي توضح كيفية اختبار دورة CRUD بأكملها للتأكد من أن جميع sprocs تؤدي وظيفتها وأن كود ado.net الخاص بك يقوم بالتخطيط لليسار واليمين بشكل صحيح

أعلم أن هذا لا يختبر sprocs "spGetProducts" المستخدم في نموذج الوصول إلى البيانات أعلاه، ولكن يجب أن ترى القوة الكامنة وراء هذا الأسلوب في اختبار الوحدة sprocs

Imports SampleApplication.Library
Imports System.Collections.Generic
Imports Microsoft.VisualStudio.TestTools.UnitTesting

<TestClass()> _
Public Class ProductRepositoryUnitTest
    Inherits TransactionFixture

    Private mRepository As ProductRepository

    <TestMethod()> _
    Public Sub Should-Insert-Update-And-Delete-Product()
        mRepository = New ProductRepository(New HttpCache(), mConnection, mTransaction)
        '** Create a test product to manipulate throughout **'
        Dim Product As New Product()
        Product.ProductName = "TestProduct"
        Product.SupplierID = 1
        Product.CategoryID = 2
        Product.QuantityPerUnit = "10 boxes of stuff"
        Product.UnitPrice = 14.95
        Product.UnitsInStock = 22
        Product.UnitsOnOrder = 19
        Product.ReorderLevel = 12
        '** Insert the new product object into SQL using your insert sproc **'
        mRepository.InsertProduct(Product)
        '** Select the product object that was just inserted and verify it does exist **'
        '** Using your GetProductById sproc **'
        Dim Product2 As Product = mRepository.GetProduct(Product.ID)
        Assert.AreEqual("TestProduct", Product2.ProductName)
        Assert.AreEqual(1, Product2.SupplierID)
        Assert.AreEqual(2, Product2.CategoryID)
        Assert.AreEqual("10 boxes of stuff", Product2.QuantityPerUnit)
        Assert.AreEqual(14.95, Product2.UnitPrice)
        Assert.AreEqual(22, Product2.UnitsInStock)
        Assert.AreEqual(19, Product2.UnitsOnOrder)
        Assert.AreEqual(12, Product2.ReorderLevel)
        '** Update the product object **'
        Product2.ProductName = "UpdatedTestProduct"
        Product2.SupplierID = 2
        Product2.CategoryID = 1
        Product2.QuantityPerUnit = "a box of stuff"
        Product2.UnitPrice = 16.95
        Product2.UnitsInStock = 10
        Product2.UnitsOnOrder = 20
        Product2.ReorderLevel = 8
        mRepository.UpdateProduct(Product2) '**using your update sproc
        '** Select the product object that was just updated to verify it completed **'
        Dim Product3 As Product = mRepository.GetProduct(Product2.ID)
        Assert.AreEqual("UpdatedTestProduct", Product2.ProductName)
        Assert.AreEqual(2, Product2.SupplierID)
        Assert.AreEqual(1, Product2.CategoryID)
        Assert.AreEqual("a box of stuff", Product2.QuantityPerUnit)
        Assert.AreEqual(16.95, Product2.UnitPrice)
        Assert.AreEqual(10, Product2.UnitsInStock)
        Assert.AreEqual(20, Product2.UnitsOnOrder)
        Assert.AreEqual(8, Product2.ReorderLevel)
        '** Delete the product and verify it does not exist **'
        mRepository.DeleteProduct(Product3.ID)
        '** The above will use your delete product by id sproc **'
        Dim Product4 As Product = mRepository.GetProduct(Product3.ID)
        Assert.AreEqual(Nothing, Product4)
    End Sub

End Class

أعلم أن هذا مثال طويل، ولكنه ساعد في الحصول على فئة قابلة لإعادة الاستخدام لعمل الوصول إلى البيانات، وفئة أخرى قابلة لإعادة الاستخدام للاختبار الخاص بي، لذلك لم أضطر إلى القيام بأعمال الإعداد/التفكيك مرارًا وتكرارًا؛)

نصائح أخرى

هل جربت DBUnit؟لقد تم تصميمه لوحدة اختبار قاعدة البيانات الخاصة بك، وقاعدة البيانات الخاصة بك فقط، دون الحاجة إلى المرور عبر كود C# الخاص بك.

إذا كنت تفكر في نوع الكود الذي يميل اختبار الوحدة إلى الترويج له:إجراءات صغيرة شديدة التماسك ومنخفضة الترابط، فمن المفترض أن تكون قادرًا إلى حد كبير على معرفة أين قد يكون جزء من المشكلة على الأقل.

في عالمي الساخر، تعد الإجراءات المخزنة جزءًا من محاولة عالم RDBMS الطويلة الأمد لإقناعك بنقل معالجة أعمالك إلى قاعدة البيانات، وهو أمر منطقي عندما تفكر في أن تكاليف ترخيص الخادم تميل إلى أن تكون مرتبطة بأشياء مثل عدد المعالجات.كلما زاد عدد الأشياء التي تقوم بتشغيلها داخل قاعدة البيانات الخاصة بك، كلما زاد حجمها منك.

ولكن لدي انطباع بأنك في الواقع مهتم أكثر بالأداء، وهو ليس حكرا على اختبار الوحدة على الإطلاق.من المفترض أن تكون اختبارات الوحدة ذرية إلى حد ما وتهدف إلى التحقق من السلوك بدلاً من الأداء.وفي هذه الحالة، ستحتاج بالتأكيد إلى أحمال فئة الإنتاج للتحقق من خطط الاستعلام.

أعتقد أنك بحاجة إلى فئة مختلفة من بيئة الاختبار.أقترح أن تكون نسخة الإنتاج هي الأبسط، على افتراض أن الأمان ليس مشكلة.بعد ذلك، بالنسبة لكل إصدار مرشح، تبدأ بالإصدار السابق، ثم تنتقل باستخدام إجراءات الإصدار الخاصة بك (والتي ستمنح تلك الإجراءات اختبارًا جيدًا كأثر جانبي) وتقوم بتشغيل التوقيتات الخاصة بك.

شئ مثل هذا.

إن مفتاح اختبار الإجراءات المخزنة هو كتابة برنامج نصي يملأ قاعدة بيانات فارغة بالبيانات التي تم التخطيط لها مسبقًا لتؤدي إلى سلوك متسق عند استدعاء الإجراءات المخزنة.

لا بد لي من التصويت لصالح الإجراءات المخزنة بشدة ووضع منطق عملك حيث أعتقد (ومعظم مسؤولي قواعد البيانات) أنه ينتمي إلى قاعدة البيانات.

أعلم أننا كمهندسي برمجيات نريد كودًا مُعاد هيكلته بشكل جميل، ومكتوبًا بلغتنا المفضلة، ليحتوي على كل منطقنا المهم، ولكن حقائق الأداء في الأنظمة كبيرة الحجم، والطبيعة الحرجة لتكامل البيانات، تتطلب منا تقديم بعض التنازلات .يمكن أن تكون تعليمات SQL البرمجية قبيحة ومتكررة ويصعب اختبارها، لكن لا يمكنني أن أتخيل صعوبة ضبط قاعدة البيانات دون التحكم الكامل في تصميم الاستعلامات.

غالبًا ما أُجبر على إعادة تصميم الاستعلامات بالكامل، لإدراج تغييرات في نموذج البيانات، لتشغيل الأشياء في فترة زمنية مقبولة.باستخدام الإجراءات المخزنة، يمكنني أن أؤكد أن التغييرات ستكون شفافة للمتصل، نظرًا لأن الإجراء المخزن يوفر مثل هذا التغليف الممتاز.

أفترض أنك تريد اختبار الوحدة في MSSQL.بالنظر إلى DBUnit، هناك بعض القيود في دعمها لـ MSSQL.لا يدعم NVarChar على سبيل المثال. فيما يلي بعض المستخدمين الحقيقيين ومشاكلهم مع DBUnit.

سؤال جيد.

لدي مشاكل مماثلة، وقد سلكت الطريق الأقل مقاومة (بالنسبة لي، على أي حال).

وهناك مجموعة من الحلول الأخرى التي ذكرها الآخرون.وكثير منها أفضل / أطهر / أنسب لغيره.

كنت أستخدم Testdriven.NET/MbUnit بالفعل لاختبار C# الخاص بي، لذلك قمت ببساطة بإضافة اختبارات إلى كل مشروع لاستدعاء الإجراءات المخزنة التي يستخدمها هذا التطبيق.

اعلم اعلم.يبدو هذا فظيعًا، لكن ما أحتاج إليه هو البدء من جديد بعض الاختبار، وانتقل من هناك.ويعني هذا الأسلوب أنه على الرغم من أن التغطية الخاصة بي منخفضة، إلا أنني أقوم باختبار بعض العمليات المخزنة في نفس الوقت الذي أقوم فيه باختبار الكود الذي سيتم الاتصال بهم.هناك بعض المنطق في هذا.

أنا في نفس الوضع تمامًا مثل الملصق الأصلي.يتعلق الأمر بالأداء مقابل قابلية الاختبار.إنحيازي هو نحو القابلية للاختبار (جعلها تعمل، وجعلها صحيحة، وجعلها سريعة)، مما يقترح إبقاء منطق الأعمال خارج قاعدة البيانات.قواعد البيانات لا تفتقر فقط إلى أطر الاختبار، وبنيات تحليل التعليمات البرمجية، وأدوات تحليل التعليمات البرمجية والتنقل الموجودة في لغات مثل Java، ولكن كود قاعدة البيانات عالي التحليل بطيء أيضًا (حيث لا يكون كود Java عالي التحليل).

ومع ذلك، فأنا أدرك قوة معالجة مجموعة قواعد البيانات.عند استخدامها بشكل مناسب، يمكن لـ SQL القيام ببعض الأشياء القوية بشكل لا يصدق باستخدام القليل جدًا من التعليمات البرمجية.لذلك، أنا موافق على وجود بعض المنطق القائم على المجموعة في قاعدة البيانات على الرغم من أنني سأظل أفعل كل ما بوسعي لاختباره.

في ملاحظة ذات صلة، يبدو أن كود قاعدة البيانات الطويل جدًا والإجرائي غالبًا ما يكون أحد أعراض شيء آخر، وأعتقد أن مثل هذا الكود يمكن تحويله إلى كود قابل للاختبار دون تكبد أي ضرر في الأداء.النظرية هي أن مثل هذا الكود غالبًا ما يمثل عمليات مجمعة تقوم بشكل دوري بمعالجة كميات كبيرة من البيانات.إذا تم تحويل هذه العمليات المجمعة إلى أجزاء أصغر من منطق الأعمال في الوقت الفعلي الذي يتم تشغيله كلما تم تغيير بيانات الإدخال، فمن الممكن تشغيل هذا المنطق على الطبقة الوسطى (حيث يمكن اختباره) دون الحصول على نتيجة أداء (نظرًا لأن يتم العمل في أجزاء صغيرة في الوقت الحقيقي).كأثر جانبي، يؤدي هذا أيضًا إلى التخلص من حلقات التغذية الراجعة الطويلة لمعالجة أخطاء العملية المجمعة.بالطبع لن ينجح هذا الأسلوب في جميع الحالات، لكنه قد ينجح في بعضها.وأيضًا، إذا كان هناك الكثير من تعليمات برمجية قاعدة بيانات المعالجة الدفعية غير القابلة للاختبار في نظامك، فقد يكون الطريق إلى الخلاص طويلًا وشاقًا.YMMV.

ولكن لدي انطباع بأنك في الواقع مهتم أكثر بالأداء، وهو ليس حكرا على اختبار الوحدة على الإطلاق.من المفترض أن تكون اختبارات الوحدة ذرية إلى حد ما وتهدف إلى التحقق من السلوك بدلاً من الأداء.وفي هذه الحالة، ستحتاج بالتأكيد إلى أحمال فئة الإنتاج للتحقق من خطط الاستعلام.

أعتقد أن هناك مجالين مختلفين تمامًا للاختبار هنا:الأداء والمنطق الفعلي للإجراءات المخزنة.

لقد أعطيت مثالاً لاختبار أداء قاعدة البيانات في الماضي، ولحسن الحظ، وصلنا إلى نقطة أصبح فيها الأداء جيدًا بما فيه الكفاية.

أوافق تمامًا على أن الوضع مع كل منطق الأعمال في قاعدة البيانات سيء، ولكنه شيء ورثناه قبل انضمام معظم المطورين لدينا إلى الشركة.

ومع ذلك، فإننا نعتمد الآن نموذج خدمات الويب لميزاتنا الجديدة، ونحاول تجنب الإجراءات المخزنة قدر الإمكان، مع الحفاظ على المنطق في كود C# وتشغيل SQLCommands في قاعدة البيانات (على الرغم من أن linq سيكون الآن الطريقة المفضلة).لا يزال هناك بعض الاستخدام لمقدمي الخدمات الحاليين ولهذا السبب كنت أفكر في اختبار الوحدة بأثر رجعي.

يمكنك أيضًا المحاولة Visual Studio لمحترفي قواعد البيانات.يتعلق الأمر بشكل أساسي بإدارة التغيير ولكن لديه أيضًا أدوات لإنشاء بيانات الاختبار واختبارات الوحدة.

انها مكلفة جدا مع ذلك.

نحن نستخدم داتا فريش للتراجع عن التغييرات بين كل اختبار، فإن اختبار sprocs سهل نسبيًا.

ما لا يزال ينقصنا هو أدوات تغطية التعليمات البرمجية.

أقوم باختبار وحدة الرجل الفقير.إذا كنت كسولًا، فإن الاختبار هو مجرد بضع استدعاءات صالحة مع قيم معلمات يحتمل أن تكون إشكالية.

/*

--setup
Declare @foo int Set @foo = (Select top 1 foo from mytable)

--test
execute wish_I_had_more_Tests @foo

--look at rowcounts/look for errors
If @@rowcount=1 Print 'Ok!' Else Print 'Nokay!'

--Teardown
Delete from mytable where foo = @foo
*/
create procedure wish_I_had_more_Tests
as
select....

سوف يقوم LINQ بتبسيط ذلك فقط إذا قمت بإزالة المنطق من إجراءاتك المخزنة وأعدت تنفيذه كاستعلامات linq.والذي سيكون أكثر قوة وأسهل في الاختبار بالتأكيد.ومع ذلك، يبدو أن متطلباتك ستمنع ذلك.

ليرة تركية؛دكتور:التصميم الخاص بك لديه مشاكل.

نقوم باختبار وحدة رمز C# الذي يستدعي مقدمي الخدمة.
لقد قمنا ببناء البرامج النصية وإنشاء قواعد بيانات اختبارية نظيفة.
والأخرى الأكبر حجمًا التي نعلقها ونفصلها أثناء تركيب الاختبار.
قد تستغرق هذه الاختبارات ساعات، ولكن أعتقد أن الأمر يستحق ذلك.

أحد الخيارات لإعادة تحليل الكود (سأعترف بالاختراق القبيح) هو إنشائه عبر CPP (المعالج المسبق لـ C) M4 (لم أجربه مطلقًا) أو ما شابه.لدي مشروع يقوم بذلك وهو في الواقع قابل للتطبيق في الغالب.

الحالة الوحيدة التي أعتقد أن هذا قد يكون صالحًا لها هي 1) كبديل لإجراءات KLOC+ المخزنة و2) وهذه هي حالتي، عندما يكون الهدف من المشروع هو معرفة إلى أي مدى (إلى الجنون) يمكنك دفع التكنولوجيا.

يا ولد.لا تصلح sprocs لاختبار الوحدة (الآلي).أقوم بنوع من "اختبار الوحدة" الخاص بي sprocs المعقدة عن طريق كتابة الاختبارات في ملفات دفعية t-sql والتحقق يدويًا من مخرجات بيانات الطباعة والنتائج.

المشكلة في اختبار الوحدة لأي نوع من البرمجة المتعلقة بالبيانات هي أنه يجب أن يكون لديك مجموعة موثوقة من بيانات الاختبار للبدء بها.يعتمد الكثير أيضًا على مدى تعقيد العملية المخزنة وما تفعله.سيكون من الصعب جدًا أتمتة اختبار الوحدة لإجراء معقد للغاية يؤدي إلى تعديل العديد من الجداول.

لاحظت بعض الملصقات الأخرى بعض الطرق البسيطة لأتمتة اختبارها يدويًا، وكذلك بعض الأدوات التي يمكنك استخدامها مع SQL Server.من ناحية Oracle، عمل خبير PL/SQL ستيفن فيورستين على أداة اختبار وحدة مجانية لإجراءات PL/SQL المخزنة تسمى utPLSQL.

ومع ذلك، فقد تخلى عن هذا الجهد ثم انتقل إلى العمل التجاري مع Quest's Code Tester لـ PL/SQL.تقدم Quest نسخة تجريبية مجانية قابلة للتنزيل.أنا على وشك تجربتها؛ما أفهمه هو أنه من الجيد الاهتمام بالنفقات العامة في إعداد إطار عمل للاختبار بحيث يمكنك التركيز على الاختبارات نفسها فقط، كما أنه يحتفظ بالاختبارات حتى تتمكن من إعادة استخدامها في اختبار الانحدار، وهي إحدى الفوائد العظيمة لـ التطوير القائم على الاختبار.بالإضافة إلى ذلك، من المفترض أن تكون جيدة في أكثر من مجرد التحقق من متغير الإخراج ولديها شرط للتحقق من صحة تغييرات البيانات، ولكن لا يزال يتعين علي إلقاء نظرة فاحصة بنفسي.أعتقد أن هذه المعلومات قد تكون ذات قيمة لمستخدمي Oracle.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top