2011-10-14 20 views
7

Đây là vấn đề thiết kế thử nghiệm đơn vị C# của tôi:C# Thiết kế thử nghiệm đơn vị Vấn đề: Làm thế nào để giảm dư thừa trong văn bản kiểm tra đơn vị?

Tôi có một thử nghiệm mà tôi muốn chạy trên một số mã sửa đổi tệp. Thử nghiệm của tôi sẽ chạy mã sửa đổi tệp, sau đó kiểm tra kết quả. Khá thẳng về phía trước cho đến nay ...

Vấn đề là, tôi có khoảng 10 tệp (sắp có nhiều hơn) mà tôi muốn chạy cùng một bài kiểm tra đơn vị. Tôi không muốn viết một bài kiểm tra đơn vị mới cho mỗi tệp, khi bản thân bài kiểm tra thực sự giống nhau.

Tôi có thể viết một bài kiểm tra duy nhất truy vấn các tệp trong thư mục và sau đó chạy logic thử nghiệm trên mỗi tệp, nhưng sử dụng phương pháp này sẽ chỉ báo cáo một kết quả vượt qua/lỗi cho toàn bộ tệp.

Id muốn tạo một số loại hệ thống động, trong đó mọi tệp mà tôi đặt trong một thư mục cụ thể sẽ chạy mặc dù thử nghiệm đơn vị giống nhau này. Vì vậy, nếu 25 tệp nằm trong thư mục, thử nghiệm sẽ chạy 25 lần và kiểm tra đơn vị báo cáo rằng 25 thử nghiệm đã được chạy và bao gồm việc vượt qua/thất bại riêng biệt cho mỗi tệp.

Bất kỳ ý tưởng nào hoặc nếu điều này có thể được thực hiện trong bài kiểm tra đơn vị C#? Hoặc với một bài kiểm tra nunit?

Cảm ơn! Và tôi hy vọng đây không phải là một câu hỏi trùng lặp. Tôi nhìn quanh, nhưng tôi không thể tìm thấy gì cả.

+1

Một số người cho rằng thử nghiệm liên quan đến IO (thao tác hệ thống tệp trong trường hợp này) không phải là kiểm tra đơn vị. Một cách tiếp cận khác là đại diện cho các hoạt động IO như các phụ thuộc có thể tiêm được. Tuy nhiên, hầu hết các loại System.IO (và chắc chắn là các số liệu thống kê) không cho vay chính nó. Một cách tiếp cận tôi đã sử dụng là tạo ra các assembly proxy của các kiểu chuyển tiếp phương thức tầm thường và các giao diện tương ứng. Điều này cho phép bạn rời khỏi lớp proxy mỏng chưa được kiểm tra này và lớp logic của bạn đã được kiểm tra đầy đủ. Microsoft Moles thực hiện điều này một cách hiệu quả nhưng đó vẫn là một WIP. –

Trả lời

3

lựa chọn khác là sử dụng các mẫu T4 để tự động tạo ra các bài kiểm tra cho bạn dựa vào số lượng các tập tin trong thư mục của bạn. Thêm tệp ".tt" này vào dự án thử nghiệm đơn vị của bạn.

Bây giờ bất cứ khi nào bạn thực hiện việc xây dựng sẽ xảy ra ngay trước khi bạn nhấn nút "Chạy tất cả các bài kiểm tra trong giải pháp" trong studio trực quan, nó sẽ tạo các bài kiểm tra đơn vị cho tất cả các tệp trong thư mục có tên tệp trong bài kiểm tra đơn vị . Sau đó, chạy thử nghiệm của bạn nên có một danh sách tốt đẹp của tất cả các tập tin nó được thử nghiệm và trạng thái của chúng.

<#@ template debug="false" hostspecific="true" language="C#v3.5" #> 
<#@ assembly name="System.Core.dll" #> 
<#@ assembly name="System.Data.dll" #> 
<#@ import namespace="System.IO" #> 
<#@ import namespace="System.Collections.Generic" #> 
<#@ import namespace="System.Linq" #> 
<#@ output extension=".cs" #> 
<# 
      string inputDirectory = @"d:\temp"; 
      var files = System.IO.Directory.GetFiles(inputDirectory); 
#> 
using System; 
using System.Text; 
using System.Collections.Generic; 
using System.Linq; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 

namespace TestProject1 
{ 
    [TestClass] 
    public class UnitTest1 
    { 
     <# foreach (string filePath in files) { #> 
     [TestMethod] 
     public void TestingFile_<#=System.IO.Path.GetFileNameWithoutExtension(filePath).Replace(' ','_').Replace('-','_')#>() 
     { 
     File currentFile = System.IO.File.Open(@"<#= filePath #>", FileMode.Open); 
     // TODO: Put your standard test code here which will use the file you opened above 
     } 
     <# } #> 
    } 
} 
+1

Đây là công cụ tuyệt vời! Tôi không biết tính năng này cho đến bây giờ, vì vậy tôi thực sự vui vì cuối cùng tôi đã hỏi một câu hỏi về stackoverflow! :) – fj40bryan

+1

Cảm ơn tất cả mọi người đã cung cấp đầu vào tuyệt vời cho câu hỏi của tôi! – fj40bryan

10

Có vẻ như những gì bạn cần là trường hợp kiểm tra được tham số hóa: xem http://www.nunit.org/index.php?p=testCaseSource&r=2.5.

Vì vậy:

[TestFixture] 
public class Tests 
{ 
    static string[] FileNames = new string[] 
        { "mary.txt", "mungo.txt", "midge.txt" }; 

    [Test, TestCaseSource("FileNames")] 
    public void TestMethod(string fileName) 
    { 
     Assert.That(File.Exists(fileName)); 
    } 
} 

Thuộc tính [TestCaseSource] nói với NUnit để có được các giá trị của tham số chuỗi từ mảng chuỗi.

Cách tiếp cận đó, tuy nhiên, yêu cầu static hằng số cho tên tệp. Nếu bạn muốn có một cách tiếp cận theo chương trình mà đọc các tập tin từ một cơ sở dữ liệu hoặc như vậy thử một lớp nhà máy như vậy:

[TestFixture] 
public class Tests 
{ 
    [Test, TestCaseSource(typeof(FilenameFactory), "FileNames")] 
    public bool FileCheck(string fileName) 
    { 
     return File.Exists(fileName); 
    } 
} 

public class FilenameFactory 
{ 
    public static IEnumerable FileNames 
    { 
     get 
     { 
      foreach (var filename in 
        Directory.EnumerateFiles(Environment.CurrentDirectory)) 
      { 
       yield return new TestCaseData(filename).Returns(true); 
      } 
     } 
    } 
} 

Lớp TestCaseData tạo ra "trường hợp thử nghiệm" mà có những kỳ vọng có thể được thiết lập thông qua một thông thạo giao diện.

+0

Đây cũng là một giải pháp thực sự tuyệt vời. Cảm ơn Jeremy. – fj40bryan

5

Kiểm tra tham số (http://www.nunit.org/index.php?p=parameterizedTests&r=2.5) có thể được sử dụng cho bạn tùy thuộc vào cách bạn đang thực hiện chúng.

Ví dụ về TestcaseAttribute mà bạn có thể sử dụng sử dụng hoặc có cũng TestCaseSourceAttribute

[TestCase(12,3,4)] 
[TestCase(12,2,6)] 
[TestCase(12,4,3)] 
public void DivideTest(int n, int d, int q) 
{ 
    Assert.AreEqual(q, n/d); 
} 

là Bạn sẽ có được lợi thế của văn bản và việc duy trì một thử nghiệm, nhưng kết quả là cho từng trường hợp.

0

Trước hết, việc thử nghiệm phụ thuộc vào nguồn bên ngoài như tệp trên đĩa không phải là thử nghiệm đơn vị nghiêm ngặt (ý kiến).

Điều bạn đang tìm kiếm là phương pháp thử nghiệm theo hướng dữ liệu và sau đó bạn nên tìm kiếm các công cụ hỗ trợ nó, như MSTest hoặc MBunit. (Theo các liên kết để biết thêm thông tin).

Sau đó, bạn có thể làm một cái gì đó như thế này (sử dụng MbUnit):

[TestFixture] 
public class MyTestFixture 
{ 
    [Test] 
    public void WordCounter([TextData(ResourcePath = "Data.txt")] string text) 
    { 
     var wordCounter = new WordCounter(text); 
     int count = wordCounter.Count("Firecrest"); 
     Assert.AreEqual(4, count); // Should not include the plural form "Firecrests". 
    } 
} 
Các vấn đề liên quan