Secara default, pengujian nunit dijalankan menurut abjad. Apakah ada yang tahu cara mengatur urutan eksekusi? Apakah ada atribut untuk ini?
Secara default, pengujian nunit dijalankan menurut abjad. Apakah ada yang tahu cara mengatur urutan eksekusi? Apakah ada atribut untuk ini?
Jawaban:
Pengujian unit Anda masing-masing harus dapat berjalan secara independen dan berdiri sendiri. Jika mereka memenuhi kriteria ini maka urutannya tidak masalah.
Namun ada kalanya Anda ingin menjalankan tes tertentu terlebih dahulu. Contoh tipikal adalah dalam situasi Integrasi Berkelanjutan di mana beberapa tes berjalan lebih lama daripada yang lain. Kami menggunakan atribut kategori sehingga kami dapat menjalankan pengujian yang menggunakan mocking sebelum pengujian yang menggunakan database.
misalnya, letakkan ini di awal tes cepat Anda
[Category("QuickTests")]
Di mana Anda memiliki tes yang tergantung pada kondisi lingkungan tertentu, pertimbangkan TestFixtureSetUp dan TestFixtureTearDown atribut, yang memungkinkan Anda untuk menandai metode yang akan dieksekusi sebelum dan sesudah tes Anda.
Saya hanya ingin menunjukkan bahwa sementara sebagian besar responden berasumsi ini adalah tes unit, pertanyaannya tidak menentukan bahwa itu benar.
nUnit adalah alat hebat yang dapat digunakan untuk berbagai situasi pengujian. Saya dapat melihat alasan yang tepat untuk ingin mengontrol urutan pengujian.
Dalam situasi tersebut saya harus menggunakan untuk memasukkan urutan lari ke dalam nama pengujian. Akan sangat bagus untuk dapat menentukan urutan berjalan menggunakan atribut.
001_first_test
002_second_test
dan seterusnya?
NUnit 3.2.0 menambahkan OrderAttribute
, lihat:
https://github.com/nunit/docs/wiki/Order-Attribute
Contoh:
public class MyFixture
{
[Test, Order(1)]
public void TestA() { ... }
[Test, Order(2)]
public void TestB() { ... }
[Test]
public void TestC() { ... }
}
Ingin agar pengujian dijalankan dalam urutan tertentu tidak berarti bahwa pengujian tersebut bergantung satu sama lain - saya sedang mengerjakan proyek TDD saat ini, dan menjadi TDDer yang baik, saya telah mengejek / menghentikan semuanya, tetapi itu akan membuat lebih mudah dibaca jika saya bisa menentukan urutan yang tes hasilnya ditampilkan - tematis bukan abjad. Sejauh ini satu-satunya hal yang dapat saya pikirkan adalah menambahkan a_ b_ c_ ke kelas ke kelas, ruang nama, dan metode. (Tidak bagus) Menurut saya atribut [TestOrderAttribute] akan bagus - tidak diikuti oleh kerangka kerja, tetapi petunjuk agar kita dapat mencapai ini
Terlepas dari apakah Tes bergantung pada urutan atau tidak ... beberapa dari kita hanya ingin mengontrol semuanya, dengan cara yang teratur.
Tes unit biasanya dibuat dalam urutan kerumitan. Jadi, mengapa mereka tidak juga dijalankan dalam urutan kerumitan, atau urutan mereka diciptakan?
Secara pribadi, saya ingin melihat pengujian berjalan sesuai urutan yang saya buat. Dalam TDD, setiap pengujian yang berurutan secara alami akan menjadi lebih kompleks, dan membutuhkan lebih banyak waktu untuk dijalankan. Saya lebih suka melihat tes yang lebih sederhana gagal terlebih dahulu karena ini akan menjadi indikator yang lebih baik untuk penyebab kegagalan.
Namun, saya juga dapat melihat manfaat menjalankannya dalam urutan acak, terutama jika Anda ingin menguji bahwa pengujian Anda tidak memiliki ketergantungan pada pengujian lain. Bagaimana jika menambahkan opsi untuk menguji pelari ke "Jalankan Tes Secara Acak Hingga Dihentikan"?
Saya menguji dengan Selenium di situs web yang cukup kompleks dan seluruh rangkaian pengujian dapat berjalan selama lebih dari setengah jam, dan saya belum hampir mencakup seluruh aplikasi. Jika saya harus memastikan bahwa semua formulir sebelumnya diisi dengan benar untuk setiap tes, ini akan menambah banyak waktu, bukan hanya sedikit waktu, untuk keseluruhan tes. Jika ada terlalu banyak overhead untuk menjalankan tes, orang tidak akan menjalankannya sesering yang seharusnya.
Jadi, saya menyusunnya dan bergantung pada tes sebelumnya untuk menyelesaikan kotak teks dan semacamnya. Saya menggunakan Assert.Ignore () ketika prasyarat tidak valid, tetapi saya harus menjalankannya secara berurutan.
Saya sangat suka jawaban sebelumnya.
Saya mengubahnya sedikit agar dapat menggunakan atribut untuk mengatur kisaran pesanan:
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
tidak lagi didukung di NUnit 3.
Saya tahu ini adalah postingan yang relatif lama, tetapi berikut ini cara lain untuk menjaga agar pengujian Anda tetap teratur TANPA membuat nama pengujian menjadi canggung. Dengan menggunakan atribut TestCaseSource dan memiliki objek yang Anda lewati memiliki sebuah delegasi (Action), Anda tidak hanya dapat mengontrol pesanan tetapi juga memberi nama tes itu apa adanya.
Ini berfungsi karena, menurut dokumentasi, item dalam koleksi yang dikembalikan dari sumber pengujian akan selalu dijalankan dalam urutan yang dicantumkan.
Ini adalah demo dari presentasi yang saya berikan besok:
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
sebagai cara untuk menjalankan tes terurut adalah jenius. Sudah selesai dilakukan dengan baik. Saya telah mengambil pendekatan ini bersama dengan yang di bawah ini dan menambahkan beberapa modifikasi tambahan untuk membuatnya lebih mudah digunakan. Lihat tautan di jawaban saya untuk info tambahan, tetapi ide dasarnya adalah dari jawaban hebat ini!
TestCaseSource
harus statis, yang menghalangi penggunaan pola. Kekecewaan.
TestCaseSource
harus berupa objek statis di NUnit 3, atau pengujian tidak akan dijalankan. Dan Anda tidak dapat membuat objek dinamis dalam objek statis. Itulah mengapa ini tidak akan berhasil dalam v. 3.
Saya bekerja dengan kasus pengujian UI ujung ke ujung Selenium WebDriver yang ditulis dalam C #, yang dijalankan menggunakan kerangka kerja NUnit. (Bukan kasus unit seperti itu)
Pengujian UI ini tentunya bergantung pada urutan eksekusi, karena pengujian lain perlu menambahkan beberapa data sebagai prasyarat. (Tidak mungkin melakukan langkah-langkah di setiap tes)
Sekarang, setelah menambahkan kasus uji ke-10, saya melihat NUnit ingin berjalan dalam urutan ini: Test_1 Test_10 Test_2 Test_3 ..
Jadi saya rasa saya harus terlalu menyusun alfabetis nama kasus uji untuk saat ini, tetapi akan lebih baik jika fitur kecil ini untuk mengontrol urutan eksekusi ditambahkan ke NUnit.
Biasanya Unit Test harus independen, tetapi jika harus, maka Anda dapat menamai metode Anda dalam urutan abjad mis:
[Test]
public void Add_Users(){}
[Test]
public void Add_UsersB(){}
[Test]
public void Process_Users(){}
atau Anda bisa melakukan ..
private void Add_Users(){}
private void Add_UsersB(){}
[Test]
public void Process_Users()
{
Add_Users();
Add_UsersB();
// more code
}
a_
b_
t1_
, t2_
atau mengandalkan karakter yang tertinggal
Ada alasan yang sangat bagus untuk menggunakan mekanisme Pemesanan Tes. Sebagian besar pengujian saya sendiri menggunakan praktik yang baik seperti penyiapan / pembongkaran. Yang lainnya memerlukan pengaturan data dalam jumlah besar, yang kemudian dapat digunakan untuk menguji berbagai fitur. Sampai sekarang, saya telah menggunakan tes besar untuk menangani tes integrasi (Selenium Webdriver) ini. Namun, saya pikir posting yang disarankan di atas di https://github.com/nunit/docs/wiki/Order-Attribute memiliki banyak manfaat. Berikut adalah contoh mengapa memesan akan sangat berharga:
Waktu tunggu 10 menit ini memperlambat rangkaian pengujian. Saat Anda menggandakan penundaan caching yang serupa di banyak pengujian, ini menghabiskan banyak waktu. Mengurutkan pengujian dapat memungkinkan penyiapan data dilakukan sebagai "Pengujian" tepat di awal rangkaian pengujian, dengan pengujian yang mengandalkan cache untuk membobol yang dijalankan menjelang akhir pengujian dijalankan.
Pertanyaan ini sudah sangat tua sekarang, tetapi bagi orang-orang yang mungkin mencapai ini dari pencarian, saya mengambil jawaban yang sangat baik dari user3275462 dan PvtVandals / Rico dan menambahkannya ke repositori GitHub bersama dengan beberapa pembaruan saya sendiri. Saya juga membuat posting blog terkait dengan beberapa info tambahan yang dapat Anda lihat untuk info lebih lanjut.
Semoga bermanfaat bagi Anda semua. Selain itu, saya sering menggunakan atribut Kategori untuk membedakan pengujian integrasi saya atau pengujian ujung ke ujung lainnya dari pengujian unit saya yang sebenarnya. Orang lain telah menunjukkan bahwa pengujian unit seharusnya tidak memiliki ketergantungan urutan, tetapi jenis pengujian lain sering melakukannya, jadi ini memberikan cara yang bagus untuk hanya menjalankan kategori pengujian yang Anda inginkan dan juga mengurutkan pengujian ujung ke ujung tersebut.
Saya terkejut komunitas NUnit belum menemukan apa pun, jadi saya pergi untuk membuat sesuatu seperti ini sendiri.
Saat ini saya sedang mengembangkan pustaka sumber terbuka yang memungkinkan Anda memesan pengujian dengan NUnit. Anda dapat memesan perlengkapan uji dan memesan "spesifikasi uji yang dipesan".
Perpustakaan menawarkan fitur-fitur berikut:
Pustaka ini sebenarnya terinspirasi dari cara MSTest menguji pengurutan dengan .orderedtest
file. Silakan lihat contoh di bawah ini.
[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
}
Jika Anda menggunakan [TestCase]
, argumenTestName
memberikan nama untuk pengujian.
Jika tidak ditentukan, nama akan dibuat berdasarkan nama metode dan argumen yang diberikan.
Anda dapat mengontrol urutan eksekusi uji seperti yang diberikan di bawah ini:
[Test]
[TestCase("value1", TestName = "ExpressionTest_1")]
[TestCase("value2", TestName = "ExpressionTest_2")]
[TestCase("value3", TestName = "ExpressionTest_3")]
public void ExpressionTest(string v)
{
//do your stuff
}
Di sini saya menggunakan nama metode "ExpressionTest"
akhiran dengan angka.
Anda dapat menggunakan nama apa pun yang diurutkan menurut abjad, lihat Atribut TestCase
Anda tidak boleh bergantung pada urutan framework pengujian memilih pengujian untuk dieksekusi.Tes harus diisolasi dan independen. Dalam hal ini mereka tidak harus bergantung pada beberapa tes lain yang mengatur panggung untuk mereka atau membersihkan setelah mereka. Mereka juga harus menghasilkan hasil yang sama terlepas dari urutan pelaksanaan pengujian (untuk snapshot SUT tertentu)
Saya melakukan sedikit googling. Seperti biasa, beberapa orang menggunakan trik licik (alih-alih memecahkan masalah mendasar untuk pengujian / desain
Lihat Juga: karakteristik tes yang baik
Dalam kasus menggunakan TestCaseSource
metode kunci adalah override string ToString
, Bagaimana itu bekerja:
Asumsikan Anda memiliki kelas TestCase
public class TestCase
{
public string Name { get; set; }
public int Input { get; set; }
public int Expected { get; set; }
}
Dan daftar 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
}
};
}
Sekarang mari kita gunakan dengan metode Test dan lihat apa yang terjadi:
[TestCaseSource(nameof(TestSource))]
public void MethodXTest(TestCase testCase)
{
var x = Power(testCase.Input);
x.ShouldBe(testCase.Expected);
}
Ini tidak akan menguji secara berurutan dan hasilnya akan seperti ini:
Jadi jika kita menambahkan override string ToString
ke kelas kita seperti:
public class TestCase
{
public string Name { get; set; }
public int Input { get; set; }
public int Expected { get; set; }
public override string ToString()
{
return Name;
}
}
Hasilnya akan berubah dan kita mendapatkan urutan dan nama tes seperti:
catatan: