Theo mặc định, các bài kiểm tra nunit chạy theo thứ tự bảng chữ cái. Có ai biết bất kỳ cách nào để đặt lệnh thực hiện? Có một thuộc tính tồn tại cho điều này?
Theo mặc định, các bài kiểm tra nunit chạy theo thứ tự bảng chữ cái. Có ai biết bất kỳ cách nào để đặt lệnh thực hiện? Có một thuộc tính tồn tại cho điều này?
Câu trả lời:
Mỗi bài kiểm tra đơn vị của bạn phải có thể chạy độc lập và độc lập. Nếu họ thỏa mãn tiêu chí này thì thứ tự không thành vấn đề.
Tuy nhiên, có những trường hợp bạn sẽ muốn chạy một số thử nghiệm trước. Một ví dụ điển hình là trong tình huống Tích hợp liên tục trong đó một số thử nghiệm chạy lâu hơn những thử nghiệm khác. Chúng tôi sử dụng thuộc tính category để chúng tôi có thể chạy các bài kiểm tra sử dụng chế độ giả trước các bài kiểm tra sử dụng cơ sở dữ liệu.
tức là đặt điều này khi bắt đầu các bài kiểm tra nhanh của bạn
[Category("QuickTests")]
Nơi bạn có kiểm tra mà phụ thuộc vào điều kiện môi trường nhất định, xem xét các TestFixtureSetUp và TestFixtureTearDown thuộc tính, cho phép bạn đánh dấu các phương pháp được thực hiện trước và sau khi xét nghiệm của bạn.
Tôi chỉ muốn chỉ ra rằng trong khi hầu hết những người trả lời cho rằng đây là các bài kiểm tra đơn vị, câu hỏi không chỉ rõ rằng chúng là gì.
nUnit là một công cụ tuyệt vời có thể được sử dụng cho nhiều tình huống thử nghiệm khác nhau. Tôi có thể thấy lý do thích hợp để muốn kiểm soát thứ tự thử nghiệm.
Trong những tình huống đó, tôi đã phải sử dụng đến việc kết hợp lệnh chạy vào tên thử nghiệm. Sẽ thật tuyệt nếu có thể chỉ định thứ tự chạy bằng một thuộc tính.
001_first_test
002_second_test
v.v.?
NUnit 3.2.0 đã thêm một OrderAttribute
, hãy xem:
https://github.com/nunit/docs/wiki/Order-Attribute
Thí dụ:
public class MyFixture
{
[Test, Order(1)]
public void TestA() { ... }
[Test, Order(2)]
public void TestB() { ... }
[Test]
public void TestC() { ... }
}
Muốn các bài kiểm tra chạy theo một thứ tự cụ thể không có nghĩa là các bài kiểm tra phụ thuộc vào nhau - tôi đang làm việc trong một dự án TDD vào lúc này và là một TDDer giỏi, tôi đã chế giễu / khai man mọi thứ, nhưng nó sẽ làm nó dễ đọc hơn nếu tôi có thể chỉ định thứ tự hiển thị kết quả kiểm tra - theo chủ đề thay vì theo bảng chữ cái. Cho đến nay, điều duy nhất tôi có thể nghĩ đến là thêm a_ b_ c_ vào các lớp vào các lớp, không gian tên và phương thức. (Không đẹp) Tôi nghĩ thuộc tính [TestOrderAttribute] sẽ rất hay - không phải tuân theo khuôn khổ một cách nghiêm khắc, nhưng là một gợi ý để chúng ta có thể đạt được điều này
Bất kể việc Kiểm tra có phụ thuộc vào thứ tự hay không ... một số người trong chúng ta chỉ muốn kiểm soát mọi thứ theo một cách có trật tự.
Các bài kiểm tra đơn vị thường được tạo theo thứ tự phức tạp. Vì vậy, tại sao chúng không nên được chạy theo thứ tự phức tạp, hoặc thứ tự mà chúng được tạo ra?
Cá nhân tôi muốn xem các bài kiểm tra chạy theo thứ tự mà tôi đã tạo chúng. Trong TDD, mỗi bài kiểm tra liên tiếp đương nhiên sẽ phức tạp hơn và mất nhiều thời gian hơn để chạy. Tôi muốn xem thử nghiệm đơn giản hơn thất bại trước vì nó sẽ là một chỉ báo tốt hơn về nguyên nhân của sự thất bại.
Tuy nhiên, tôi cũng có thể thấy lợi ích của việc chạy chúng theo thứ tự ngẫu nhiên, đặc biệt nếu bạn muốn kiểm tra rằng các bài kiểm tra của bạn không có bất kỳ sự phụ thuộc nào vào các bài kiểm tra khác. Làm thế nào về việc thêm một tùy chọn cho người chạy thử vào "Chạy thử nghiệm ngẫu nhiên cho đến khi dừng"?
Tôi đang thử nghiệm với Selenium trên một trang web khá phức tạp và toàn bộ bộ thử nghiệm có thể chạy trong hơn nửa giờ và tôi vẫn chưa hoàn thành toàn bộ ứng dụng. Nếu tôi phải đảm bảo rằng tất cả các biểu mẫu trước đó được điền chính xác cho mỗi bài kiểm tra, thì điều này sẽ tăng thêm rất nhiều thời gian, không chỉ một lượng nhỏ thời gian cho bài kiểm tra tổng thể. Nếu có quá nhiều chi phí để chạy các bài kiểm tra, mọi người sẽ không chạy chúng thường xuyên.
Vì vậy, tôi sắp xếp chúng theo thứ tự và phụ thuộc vào các bài kiểm tra trước đó để có các hộp văn bản và hoàn thành như vậy. Tôi sử dụng Assert.Ignore () khi các điều kiện trước không hợp lệ, nhưng tôi cần để chúng chạy theo thứ tự.
Tôi thực sự thích câu trả lời trước.
Tôi đã thay đổi nó một chút để có thể sử dụng thuộc tính để đặt phạm vi đơn hàng:
namespace SmiMobile.Web.Selenium.Tests
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using NUnit.Framework;
public class OrderedTestAttribute : Attribute
{
public int Order { get; set; }
public OrderedTestAttribute(int order)
{
Order = order;
}
}
public class TestStructure
{
public Action Test;
}
class Int
{
public int I;
}
[TestFixture]
public class ControllingTestOrder
{
private static readonly Int MyInt = new Int();
[TestFixtureSetUp]
public void SetUp()
{
MyInt.I = 0;
}
[OrderedTest(0)]
public void Test0()
{
Console.WriteLine("This is test zero");
Assert.That(MyInt.I, Is.EqualTo(0));
}
[OrderedTest(2)]
public void ATest0()
{
Console.WriteLine("This is test two");
MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(2));
}
[OrderedTest(1)]
public void BTest0()
{
Console.WriteLine("This is test one");
MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(1));
}
[OrderedTest(3)]
public void AAA()
{
Console.WriteLine("This is test three");
MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(3));
}
[TestCaseSource(sourceName: "TestSource")]
public void MyTest(TestStructure test)
{
test.Test();
}
public IEnumerable<TestCaseData> TestSource
{
get
{
var assembly =Assembly.GetExecutingAssembly();
Dictionary<int, List<MethodInfo>> methods = assembly
.GetTypes()
.SelectMany(x => x.GetMethods())
.Where(y => y.GetCustomAttributes().OfType<OrderedTestAttribute>().Any())
.GroupBy(z => z.GetCustomAttribute<OrderedTestAttribute>().Order)
.ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());
foreach (var order in methods.Keys.OrderBy(x => x))
{
foreach (var methodInfo in methods[order])
{
MethodInfo info = methodInfo;
yield return new TestCaseData(
new TestStructure
{
Test = () =>
{
object classInstance = Activator.CreateInstance(info.DeclaringType, null);
info.Invoke(classInstance, null);
}
}).SetName(methodInfo.Name);
}
}
}
}
}
}
OrderedTest
không còn được hỗ trợ trong NUnit 3
Tôi biết đây là một bài viết tương đối cũ, nhưng đây là một cách khác để giữ cho bài kiểm tra của bạn có thứ tự mà KHÔNG làm cho tên bài kiểm tra khó xử. Bằng cách sử dụng thuộc tính TestCaseSource và đối tượng bạn chuyển vào có một đại diện (Hành động), bạn hoàn toàn có thể không chỉ kiểm soát thứ tự mà còn đặt tên cho thử nghiệm đó là gì.
Điều này hoạt động bởi vì, theo tài liệu, các mục trong bộ sưu tập được trả về từ nguồn kiểm tra sẽ luôn thực thi theo thứ tự được liệt kê.
Đây là bản demo từ bài thuyết trình mà tôi sẽ trình bày vào ngày mai:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
namespace NUnitTest
{
public class TestStructure
{
public Action Test;
}
class Int
{
public int I;
}
[TestFixture]
public class ControllingTestOrder
{
private static readonly Int MyInt= new Int();
[TestFixtureSetUp]
public void SetUp()
{
MyInt.I = 0;
}
[TestCaseSource(sourceName: "TestSource")]
public void MyTest(TestStructure test)
{
test.Test();
}
public IEnumerable<TestCaseData> TestSource
{
get
{
yield return new TestCaseData(
new TestStructure
{
Test = () =>
{
Console.WriteLine("This is test one");
MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(1));
}
}).SetName(@"Test One");
yield return new TestCaseData(
new TestStructure
{
Test = () =>
{
Console.WriteLine("This is test two");
MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(2));
}
}).SetName(@"Test Two");
yield return new TestCaseData(
new TestStructure
{
Test = () =>
{
Console.WriteLine("This is test three");
MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(3));
}
}).SetName(@"Test Three");
}
}
}
}
TestCaseSource
như một cách để chạy các bài kiểm tra theo thứ tự là một đột phá của thiên tài. Làm tốt. Tôi đã thực hiện phương pháp này cùng với phương pháp bên dưới và thêm một số sửa đổi bổ sung để làm cho nó dễ sử dụng hơn. Xem các liên kết trong câu trả lời của tôi để biết thêm thông tin, nhưng ý tưởng cơ bản là từ câu trả lời tuyệt vời này!
TestCaseSource
phải ở trạng thái tĩnh, loại trừ việc sử dụng mẫu. Bummer.
TestCaseSource
phải là một đối tượng tĩnh trong NUnit 3, nếu không các bài kiểm tra sẽ không thực thi. Và bạn không thể tạo các đối tượng động trong một đối tượng tĩnh. Đó là lý do tại sao nó sẽ không hoạt động trong câu 3.
Tôi đang làm việc với các trường hợp kiểm tra giao diện người dùng đầu cuối của Selenium WebDriver được viết bằng C #, được chạy bằng khung NUnit. (Không phải các trường hợp đơn vị như vậy)
Các bài kiểm tra giao diện người dùng này chắc chắn phụ thuộc vào thứ tự thực hiện, vì các bài kiểm tra khác cần thêm một số dữ liệu như một điều kiện tiên quyết. (Không thể thực hiện các bước trong mọi thử nghiệm)
Bây giờ, sau khi thêm trường hợp thử nghiệm thứ 10, tôi thấy NUnit muốn chạy theo thứ tự sau: Test_1 Test_10 Test_2 Test_3 ..
Vì vậy, tôi đoán bây giờ tôi phải sắp xếp theo thứ tự bảng chữ cái các tên trường hợp thử nghiệm, nhưng sẽ rất tốt nếu tính năng nhỏ này kiểm soát thứ tự thực thi được thêm vào NUnit.
Thông thường Unit Test phải độc lập, nhưng nếu phải, bạn có thể đặt tên các phương thức của mình theo thứ tự bảng chữ cái, ví dụ:
[Test]
public void Add_Users(){}
[Test]
public void Add_UsersB(){}
[Test]
public void Process_Users(){}
hoặc bạn có thể làm ..
private void Add_Users(){}
private void Add_UsersB(){}
[Test]
public void Process_Users()
{
Add_Users();
Add_UsersB();
// more code
}
a_
b_
t1_
, t2_
thay vào đó hoặc dựa vào dễ dàng bỏ lỡ nhân vật trailing
Có những lý do chính đáng để sử dụng cơ chế Đặt hàng thử nghiệm. Hầu hết các bài kiểm tra của riêng tôi đều sử dụng phương pháp thực hành tốt như thiết lập / xé nhỏ. Những người khác yêu cầu một lượng lớn dữ liệu thiết lập, sau đó có thể được sử dụng để kiểm tra một loạt các tính năng. Cho đến nay, tôi đã sử dụng các bài kiểm tra lớn để xử lý các bài kiểm tra tích hợp (Selenium Webdriver) này. Tuy nhiên, tôi nghĩ bài đăng được đề xuất ở trên trên https://github.com/nunit/docs/wiki/Order-Attribute có rất nhiều điểm đáng khen. Dưới đây là một ví dụ về lý do tại sao đặt hàng sẽ cực kỳ có giá trị:
Thời gian chờ 10 phút này làm chậm bộ thử nghiệm. Khi bạn nhân những độ trễ tương tự vào bộ nhớ đệm trong vô số thử nghiệm, nó sẽ tiêu tốn rất nhiều thời gian. Kiểm tra theo thứ tự có thể cho phép thiết lập dữ liệu được thực hiện dưới dạng "Kiểm tra" ngay khi bắt đầu bộ thử nghiệm, với các thử nghiệm dựa vào bộ nhớ đệm để phá vỡ được thực hiện vào cuối quá trình chạy thử nghiệm.
Câu hỏi này thực sự đã cũ rồi, nhưng đối với những người có thể tiếp cận câu hỏi này từ việc tìm kiếm, tôi đã lấy các câu trả lời tuyệt vời từ user3275462 và PvtVandals / Rico và thêm chúng vào kho lưu trữ GitHub cùng với một số bản cập nhật của riêng tôi. Tôi cũng đã tạo một bài đăng trên blog được liên kết với một số thông tin bổ sung mà bạn có thể xem để biết thêm thông tin.
Hy vọng điều này sẽ hữu ích cho tất cả các bạn. Ngoài ra, tôi thường thích sử dụng thuộc tính Category để phân biệt các bài kiểm tra tích hợp hoặc các bài kiểm tra end-to-end khác với các bài kiểm tra đơn vị thực tế của tôi. Những người khác đã chỉ ra rằng các bài kiểm tra đơn vị không nên có sự phụ thuộc vào thứ tự, nhưng các loại thử nghiệm khác thường có, vì vậy điều này cung cấp một cách hay để chỉ chạy danh mục thử nghiệm bạn muốn và cũng sắp xếp các bài kiểm tra đầu cuối đó.
Tôi ngạc nhiên vì cộng đồng NUnit không nghĩ ra bất cứ thứ gì, vì vậy tôi đã tự mình tạo ra một thứ như thế này.
Tôi hiện đang phát triển một thư viện mã nguồn mở cho phép bạn đặt hàng các bài kiểm tra của mình với NUnit. Bạn có thể đặt hàng các thiết bị thử nghiệm và đặt hàng "thông số kỹ thuật thử nghiệm đã đặt hàng".
Thư viện cung cấp các tính năng sau:
Thư viện thực sự được lấy cảm hứng từ cách MSTest kiểm tra việc sắp xếp thứ tự với .orderedtest
các tệp. Hãy xem một ví dụ dưới đây.
[OrderedTestFixture]
public sealed class MyOrderedTestFixture : TestOrderingSpecification {
protected override void DefineTestOrdering() {
TestFixture<Fixture1>();
OrderedTestSpecification<MyOtherOrderedTestFixture>();
TestFixture<Fixture2>();
TestFixture<Fixture3>();
}
protected override bool ContinueOnError => false; // Or true, if you want to continue even if a child test fails
}
Nếu bạn đang sử dụng [TestCase]
, đối số TestName
cung cấp tên cho kiểm tra.
Nếu không được chỉ định, một tên sẽ được tạo dựa trên tên phương thức và các đối số được cung cấp.
Bạn có thể kiểm soát thứ tự thực hiện kiểm tra như dưới đây:
[Test]
[TestCase("value1", TestName = "ExpressionTest_1")]
[TestCase("value2", TestName = "ExpressionTest_2")]
[TestCase("value3", TestName = "ExpressionTest_3")]
public void ExpressionTest(string v)
{
//do your stuff
}
Ở đây tôi đã sử dụng "ExpressionTest"
hậu tố tên phương thức với một số.
Bạn có thể sử dụng bất kỳ tên nào được sắp xếp theo thứ tự bảng chữ cái, xem Thuộc tính TestCase
Bạn không nên phụ thuộc vào thứ tự mà khung thử nghiệm chọn các thử nghiệm để thực thi.Các bài kiểm tra nên được tách biệt và độc lập. Trong đó họ không nên phụ thuộc vào một số thử nghiệm khác để tạo tiền đề cho họ hoặc dọn dẹp sau họ. Chúng cũng phải tạo ra cùng một kết quả bất kể thứ tự thực hiện các thử nghiệm (đối với một ảnh chụp nhanh nhất định của SUT)
Tôi đã làm một chút về googling. Như thường lệ, một số người đã sử dụng các thủ thuật lén lút (thay vì giải quyết vấn đề cơ bản về khả năng kiểm tra / thiết kế
Xem Thêm: đặc điểm của một bài kiểm tra tốt
Trong trường hợp sử dụng TestCaseSource
khóa là override string ToString
phương thức, Cách hoạt động:
Giả sử bạn có lớp TestCase
public class TestCase
{
public string Name { get; set; }
public int Input { get; set; }
public int Expected { get; set; }
}
Và danh sách các TestCases:
private static IEnumerable<TestCase> TestSource()
{
return new List<TestCase>
{
new TestCase()
{
Name = "Test 1",
Input = 2,
Expected = 4
},
new TestCase()
{
Name = "Test 2",
Input = 4,
Expected = 16
},
new TestCase()
{
Name = "Test 3",
Input = 10,
Expected = 100
}
};
}
Bây giờ, hãy sử dụng nó với một phương pháp Kiểm tra và xem điều gì sẽ xảy ra:
[TestCaseSource(nameof(TestSource))]
public void MethodXTest(TestCase testCase)
{
var x = Power(testCase.Input);
x.ShouldBe(testCase.Expected);
}
Điều này sẽ không kiểm tra theo thứ tự và đầu ra sẽ như thế này:
Vì vậy, nếu chúng tôi thêm vào override string ToString
lớp của mình như:
public class TestCase
{
public string Name { get; set; }
public int Input { get; set; }
public int Expected { get; set; }
public override string ToString()
{
return Name;
}
}
Kết quả sẽ thay đổi và chúng tôi nhận được thứ tự và tên của bài kiểm tra như:
Ghi chú: