Varsayılan olarak nunit testleri alfabetik olarak çalışır. Yürütme emrini belirlemenin herhangi bir yolunu bilen var mı? Bunun için bir nitelik var mı?
Varsayılan olarak nunit testleri alfabetik olarak çalışır. Yürütme emrini belirlemenin herhangi bir yolunu bilen var mı? Bunun için bir nitelik var mı?
Yanıtlar:
Ünite testlerinizin her biri bağımsız ve tek başına çalışabilmelidir. Bu kriteri karşılarlarsa, sıra önemli değildir.
Bununla birlikte, önce belirli testleri çalıştırmak isteyeceğiniz durumlar vardır. Tipik bir örnek, bazı testlerin diğerlerinden daha uzun sürdüğü Sürekli Entegrasyon durumudur. Veritabanını kullanan testlerden önce alay kullanan testleri çalıştırabilmemiz için kategori özelliğini kullanıyoruz.
yani bunu hızlı testlerinizin başına koyun
[Category("QuickTests")]
Belirli çevresel koşullara bağlı testleriniz olduğunda, testlerinizden önce ve sonra yürütülecek yöntemleri işaretlemenize olanak tanıyan TestFixtureSetUp ve TestFixtureTearDown özelliklerini göz önünde bulundurun .
Sadece şunu belirtmek isterim ki, yanıt verenlerin çoğu bunların birim testleri olduğunu varsaysa da, soru bunların olduklarını belirtmedi.
nUnit, çeşitli test durumları için kullanılabilecek harika bir araçtır. Test sırasını kontrol etmek istemenin uygun nedenlerini görebiliyorum.
Bu durumlarda, test adına bir çalışma emri eklemeye başvurmak zorunda kaldım. Bir öznitelik kullanarak çalıştırma sırasını belirtebilmek harika olurdu.
001_first_test
002_second_test
?
NUnit 3.2.0 bir ekledi OrderAttribute
, bakınız:
https://github.com/nunit/docs/wiki/Order-Attribute
Misal:
public class MyFixture
{
[Test, Order(1)]
public void TestA() { ... }
[Test, Order(2)]
public void TestB() { ... }
[Test]
public void TestC() { ... }
}
Testlerin belirli bir sırayla çalıştırılmasını istemek, testlerin birbirine bağlı olduğu anlamına gelmez - Şu anda bir TDD projesi üzerinde çalışıyorum ve iyi bir TDDer olarak her şeyle alay ettim / vurdum ama yapacaktı Test sonuçlarının alfabetik yerine tematik olarak görüntüleneceği sırayı belirleyebilirsem daha okunaklı olur . Şimdiye kadar düşünebildiğim tek şey, a_ b_ c_'yi sınıfların, ad alanlarının ve yöntemlerin başına eklemek. (Hoş değil) Bir [TestOrderAttribute] özniteliğinin güzel olacağını düşünüyorum - çerçevenin sıkı bir şekilde takip etmesi değil, ancak bunu başarabilmemiz için bir ipucu
Testlerin siparişe bağlı olup olmadığına bakılmaksızın ... bazılarımız sadece her şeyi düzenli bir şekilde kontrol etmek istiyoruz.
Birim testleri genellikle karmaşıklık sırasına göre oluşturulur. Öyleyse, neden karmaşıklık sırasına veya yaratıldıkları sıraya göre çalıştırılmamalılar?
Şahsen, testlerin onları oluşturduğum sırayla çalıştırıldığını görmeyi seviyorum. TDD'de, birbirini izleyen her test doğal olarak daha karmaşık olacak ve çalıştırılması daha fazla zaman alacaktır. Başarısızlığın nedeni konusunda daha iyi bir gösterge olacağı için önce daha basit testin başarısız olduğunu görmeyi tercih ederim.
Ancak, onları rastgele sırayla çalıştırmanın faydasını da görebiliyorum, özellikle testlerinizin diğer testlere herhangi bir bağımlılığı olmadığını test etmek istiyorsanız. "Durana Kadar Testleri Rastgele Çalıştır" için koşucuları test etmek için bir seçenek eklemeye ne dersiniz?
Selenium ile oldukça karmaşık bir web sitesinde test ediyorum ve tüm testler yarım saatten fazla çalışabilir ve henüz tüm uygulamayı ele almaya yakın değilim. Her test için önceki tüm formların doğru bir şekilde doldurulduğundan emin olmam gerekirse, bu, genel teste sadece küçük bir süre değil, büyük bir zaman ekler. Testleri yürütmek için çok fazla ek yük varsa, insanlar bunları gerektiği kadar sık çalıştırmazlar.
Bu yüzden, onları sıraya koyuyorum ve metin kutularının ve benzerlerinin tamamlanması için önceki testlere güveniyorum. Ön koşullar geçerli olmadığında Assert.Ignore () kullanıyorum, ancak bunların sırayla çalıştırılması gerekiyor.
Önceki cevabı gerçekten beğendim.
Sipariş aralığını ayarlamak için bir öznitelik kullanabilmek için biraz değiştirdim:
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
artık NUnit 3'te desteklenmiyor.
Bunun nispeten eski bir gönderi olduğunu biliyorum, ancak test isimlerini garip hale getirmeden sınavınızı düzenli tutmanın başka bir yolu da burada. TestCaseSource özniteliğini kullanarak ve ilettiğiniz nesnenin bir temsilciye (Eylem) sahip olmasını sağlayarak, yalnızca siparişi kontrol etmekle kalmaz, aynı zamanda testin ne olduğunu da adlandırabilirsiniz.
Bu işe yarar çünkü belgelere göre, koleksiyondaki test kaynağından döndürülen öğeler her zaman listelendikleri sırayla yürütülür.
İşte yarın yapacağım bir sunumdan bir demo:
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
sıralı testleri yürütmenin bir yolu olarak kullanmak bir dahidir. Aferin. Bu yaklaşımı aşağıdakiyle birlikte uyguladım ve kullanımını kolaylaştırmak için birkaç ek değişiklik ekledim. Ek bilgi için cevabımdaki bağlantılara bakın, ancak temel fikir bu harika cevaptan geliyor!
TestCaseSource
modelin kullanılmasını engelleyen kaynak statik olmalıdır. Aylak.
TestCaseSource
NUnit 3'te statik bir nesne olmalıdır, aksi takdirde testler çalışmayacaktır. Ve statik bir nesne içinde dinamik nesneler oluşturamazsınız. Bu yüzden 3.
C # ile yazılmış, NUnit çerçevesi kullanılarak çalıştırılan Selenium WebDriver uçtan uca UI test durumları ile çalışıyorum. (Bu tür birim durumlar değil)
Diğer testlerin ön koşul olarak bazı verileri eklemesi gerektiğinden, bu UI testleri kesinlikle yürütme sırasına bağlıdır. (Her testte adımları uygulamak mümkün değildir)
Şimdi, 10. test durumunu ekledikten sonra, NUnit'in şu sırayla çalıştırmak istediğini görüyorum: Test_1 Test_10 Test_2 Test_3 ..
Sanırım şimdilik test durum isimlerini alfabetik olarak sıralamak zorundayım, ancak bu küçük yürütme sırasını kontrol etme özelliğinin NUnit'e eklenmesi iyi olacaktır.
Genellikle Birim Testi bağımsız olmalıdır, ancak gerekiyorsa, yöntemlerinizi alfabetik sırayla adlandırabilirsiniz, örn:
[Test]
public void Add_Users(){}
[Test]
public void Add_UsersB(){}
[Test]
public void Process_Users(){}
ya da yapabilirsin ..
private void Add_Users(){}
private void Add_UsersB(){}
[Test]
public void Process_Users()
{
Add_Users();
Add_UsersB();
// more code
}
a_
b_
t1_
, t2_
sondaki karakterleri kaçırmak yerine veya kolay güvenerek
Bir Test Sıralama mekanizmasını kullanmak için çok iyi nedenler vardır. Kendi testlerimin çoğu kurulum / sökme gibi iyi uygulamaları kullanıyor. Diğerleri, daha sonra bir dizi özelliği test etmek için kullanılabilecek büyük miktarda veri kurulumu gerektirir. Şimdiye kadar, bu (Selenium Webdriver) entegrasyon testlerini işlemek için büyük testler kullandım. Ancak, https://github.com/nunit/docs/wiki/Order-Attribute adresindeki yukarıda önerilen gönderinin çok fazla değeri olduğunu düşünüyorum. İşte sipariş vermenin neden son derece değerli olduğuna dair bir örnek:
Bu 10 dakikalık bekleme süresi, test paketini yavaşlatır. Çok sayıda testte benzer önbelleğe alma gecikmelerini çarptığınızda, çok fazla zaman harcar. Testlerin sıralanması, test çalışmasının sonuna doğru yürütülen önbelleğe dayanan testlerle, test paketinin hemen başında bir "Test" olarak veri kurulumunun yapılmasına izin verebilir.
Bu soru artık çok eski, ancak buna arama yaparak ulaşabilecek insanlar için, user3275462 ve PvtVandals / Rico'dan mükemmel yanıtları aldım ve bunları kendi güncellemelerimle birlikte bir GitHub deposuna ekledim . Ayrıca , daha fazla bilgi için bakabileceğiniz bazı ek bilgilerle ilişkili bir blog yazısı da oluşturdum .
Umarım bu hepinize yardımcı olur. Ayrıca, entegrasyon testlerimi veya diğer uçtan-uca testleri gerçek birim testlerimden ayırmak için Kategori özniteliğini sıklıkla kullanmayı seviyorum. Diğerleri, birim testlerinin bir sıra bağımlılığına sahip olmaması gerektiğini, ancak diğer test türlerinin çoğu zaman olduğunu belirtti, bu nedenle bu, yalnızca istediğiniz test kategorisini çalıştırmak ve aynı zamanda bu uçtan uca testleri sipariş etmek için güzel bir yol sağlar.
NUnit topluluğunun hiçbir şey bulamamasına şaşırdım, bu yüzden kendim buna benzer bir şey yaratmaya gittim.
Şu anda , testlerinizi NUnit ile sipariş etmenizi sağlayan açık kaynaklı bir kitaplık geliştiriyorum . Test fikstürleri sipariş edebilir ve "sipariş edilen test spesifikasyonları" sipariş edebilirsiniz.
Kitaplık aşağıdaki özellikleri sunar:
Kütüphane aslında MSTest'in .orderedtest
dosyalarla nasıl test sıralaması yaptığından esinlenmiştir . Lütfen aşağıdaki bir örneğe bakın.
[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
}
Eğer kullanıyorsanız [TestCase]
, argüman TestName
test için bir isim sağlar.
Belirtilmezse, yöntem adına ve sağlanan bağımsız değişkenlere göre bir ad oluşturulur.
Test yürütme sırasını aşağıda verildiği gibi kontrol edebilirsiniz:
[Test]
[TestCase("value1", TestName = "ExpressionTest_1")]
[TestCase("value2", TestName = "ExpressionTest_2")]
[TestCase("value3", TestName = "ExpressionTest_3")]
public void ExpressionTest(string v)
{
//do your stuff
}
Burada yöntem adı "ExpressionTest"
son ekini bir sayı ile kullandım.
Alfabetik sıralı herhangi bir adı kullanabilirsiniz, bkz. TestCase Özniteliği
Test çerçevesinin yürütme için testleri seçtiği sıraya bağlı olmamalısınız. Testler izole ve bağımsız olmalıdır. Bu nedenle, onlar için sahneyi hazırlayan veya onlardan sonra temizlik yapan başka bir teste güvenmemeleri gerekir. Ayrıca, testlerin gerçekleştirilme sırasına bakılmaksızın aynı sonucu üretmelidirler (SUT'nin belirli bir anlık görüntüsü için)
Biraz googling yaptım. Her zaman olduğu gibi, bazı insanlar sinsi numaralara başvurdu (temelde yatan test edilebilirlik / tasarım sorununu çözmek yerine
Ayrıca bkz: iyi bir testin özellikleri
TestCaseSource
Anahtarın kullanılması durumunda, override string ToString
yöntemdir, Bu nasıl çalışır:
TestCase sınıfınız olduğunu varsayın
public class TestCase
{
public string Name { get; set; }
public int Input { get; set; }
public int Expected { get; set; }
}
Ve TestCases listesi:
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
}
};
}
Şimdi onu bir Test yöntemi ile kullanalım ve neler olduğunu görelim:
[TestCaseSource(nameof(TestSource))]
public void MethodXTest(TestCase testCase)
{
var x = Power(testCase.Input);
x.ShouldBe(testCase.Expected);
}
Bu sırayla test edilmeyecek ve çıktı şöyle olacaktır:
Yani override string ToString
sınıfımıza şöyle eklersek:
public class TestCase
{
public string Name { get; set; }
public int Input { get; set; }
public int Expected { get; set; }
public override string ToString()
{
return Name;
}
}
Sonuç değişecek ve testin sırasını ve adını şu şekilde alıyoruz:
Not: