2010-11-19 13 views
34

Veri yoğun bir uygulama yazıyorum. Aşağıdaki testlerim var. Çalışıyorlar, ama oldukça gereksizler.Dinamik nesneleri bir NUnit TestCase işlevine nasıl geçirirsiniz?

[Test] 
public void DoSanityCheck_WithCountEqualsZeroAndHouseGrossIsGreater_InMerchantAggregateTotals_SetsWarning() 
{ 
    report.Merchants[5461324658456716].AggregateTotals.ItemCount = 0; 
    report.Merchants[5461324658456716].AggregateTotals._volume = 0; 
    report.Merchants[5461324658456716].AggregateTotals._houseGross = 1; 

    report.DoSanityCheck(); 

    Assert.IsTrue(report.FishyFlag); 
    Assert.That(report.DataWarnings.Where(x=> x is Reports.WarningObjects.ImbalancedVariables && x.mid == 5461324658456716 && x.lineitem == "AggregateTotals").Count() > 0); 
} 
[Test] 
public void DoSanityCheck_WithCountEqualsZeroAndHouseGrossIsGreater_InAggregateTotals_SetsWarning() 
{ 
    report.AggregateTotals.ItemCount = 0; 
    report.AggregateTotals._volume = 0; 
    report.AggregateTotals._houseGross = 1; 

    report.DoSanityCheck(); 

    Assert.IsTrue(report.FishyFlag); 
    Assert.That(report.DataWarnings.Where(x=> x is Reports.WarningObjects.ImbalancedVariables && x.mid == null && x.lineitem == "AggregateTotals").Count() > 0); 
} 
[Test] 
public void DoSanityCheck_WithCountEqualsZeroAndHouseGrossIsGreater_InAggregateTotalsLineItem_SetsWarning() 
{ 
    report.AggregateTotals.LineItem["WirelessPerItem"].ItemCount = 0; 
    report.AggregateTotals.LineItem["WirelessPerItem"]._volume = 0; 
    report.AggregateTotals.LineItem["WirelessPerItem"]._houseGross = 1; 

    report.DoSanityCheck(); 

    Assert.IsTrue(report.FishyFlag); 
    Assert.That(report.DataWarnings.Where(x=> x is Reports.WarningObjects.ImbalancedVariables && x.mid == null && x.lineitem == "WirelessPerItem").Count() > 0); 
} 

aynı özellikleri sadece farklı konteyner nesnelerin çocuklar ve sonunda iddia değişikliği birkaç değerleri olarak, başında değiştirilir. Bunların birkaç düzine, farklı özellikleri kontrol etmem gerekiyor. Bu yüzden testi parametrelemek istiyorum. Hile, kapsayıcı nesneyi sınama için bir parametre olarak geçiriyor. Kapsayıcı nesnesi, Test fikstürü SetUp'da başlatılır.

[TestCase(report.AggregateTotals.LineItem["WirelessPerItem"], 0, "WirelessPerItem")] 
[TestCase(report.AggregateTotals, 4268435971532164, "AggregateTotals")] 
[TestCase(report.Merchants[5461324658456716].AggregateTotals, 5461324658456716, "WirelessPerItem")] 
[TestCase(report.Merchants[4268435971532164].LineItem["EBTPerItem"], 4268435971532164, "EBTPerItem")] 
public void DoSanityCheck_WithCountEqualsZeroAndHouseGrossIsGreater_TestCase_SetsWarning(object container, long mid, string field) 
{ 
    container.ItemCount = 0; 
    container._volume = 0; 
    container._houseGross = 1; 

    report.DoSanityCheck(); 

    Assert.IsTrue(report.FishyFlag); 
    Assert.That(report.DataWarnings.Where(x=> x is Reports.WarningObjects.ImbalancedVariables && x.mid == mid && x.lineitem == field).Count() > 0); 
} 

Ama bu işe yaramazsa ve ben o iş ya eğer mümkünse nasıl emin değilim: Böyle bir şey olmazdı ulaşmak istediğiniz ne

.

cevap

87

bunu buldum. Öznitelikler kesinlikle statik meta verilere sahip olduğundan, örneklenmiş bir nesneyi TestCase aracılığıyla bir sınamaya geçiremiyorum. Ancak NUnit ekibinin bunun için bir çözümü var, TestCaseSource. Soruyu cevaplayan NUnit listesindeki yayın here. Ben ümit olarak

public IEnumerable<TestCaseData> CountEqualsZeroAndHouseGrossIsGreaterTestCases 
{ 
    get 
    { 
     Setup(); 
     yield return new TestCaseData(report, report.Merchants[4268435971532164].LineItem["EBTPerItem"], 4268435971532164, "EBTPerItem").SetName("ReportMerchantsLineItem"); 
     yield return new TestCaseData(report, report.Merchants[5461324658456716].AggregateTotals, 5461324658456716, "WirelessPerItem").SetName("ReportMerchantsAggregateTotals"); 
     yield return new TestCaseData(report, report.AggregateTotals, null, "AggregateTotals").SetName("ReportAggregateTotals"); 
     yield return new TestCaseData(report, report.AggregateTotals.LineItem["WirelessPerItem"], null, "WirelessPerItem").SetName("ReportAggregateTotalsLineItem"); 
    } 
} 
[TestCaseSource("CountEqualsZeroAndHouseGrossIsGreaterTestCases")] 
public void DoSanityCheck_WithCountEqualsZeroAndHouseGrossIsGreater_TestCase_SetsWarning(Reports.ResidualsReport report, Reports.LineItemObject container, long? mid, string field) 
{ 
    container.ItemCount = 0; 
    container._volume = 0; 
    container._houseGross = 1; 

    report.DoSanityCheck(); 

    Assert.IsTrue(report.FishyFlag); 
    Assert.That(report.DataWarnings.Where(x=> x is Reports.WarningObjects.ImbalancedVariables && x.mid == mid && x.lineitem == field).Count() > 0); 
} 

kadar güzel değilsin, kolay değil okumak için: Burada

benim çözüm şimdi böyle görünüyor. Ancak, kodların çoğaltılmasını azaltmayı başardı;

+1

CountEqualsZeroAndHouseGrossIsGreaterTestCases özelliği statik – moyomeh

+6

olmalıdır. C# 6+ kullanıyorsanız, adı bir dize olarak kullanmak yerine 'nameof' kullanabilirsiniz. [TestCaseSource (yani (CountEqualsZeroAndHouseGrossIsGreaterTestCases))], bu yazı yazmayı güçlü kılar. –

+2

NUnit 3'ten itibaren, TestCaseSource da statik kaynaklarla sınırlıdır. – buckminst

0

Özel bir yönteme, temel sınıf yöntemine veya sizin için bunu yapan yardımcı sınıflara sahip olmak çok daha kolay olmaz mıydı?

Birim testlerim için, çok yoğun bir uygulamaya ihtiyacım var çünkü çok yoğun bir uygulama. Bellekte temsili bir veritabanı yapısı oluşturmak için birleştirebileceğim, başlangıçta varlıkları oluşturulabilen bir sahte depolar yapısı oluşturdum. Böyle

şey sizin için işe yarayabilir:

// Wild guess at the class name, but you get the idea 
private void InitializeTotals(AggregateItem item) 
{ 
    item.ItemCount = 0; 
    item._volume = 0; 
    item._houseGross = 1; 
} 

[Test] 
public void DoSanityCheck_WithCountEqualsZeroAndHouseGrossIsGreater_InMerchantAggregateTotals_SetsWarning() 
{ 
    InitializeTotals(report.Merchants[5461324658456716].AggregateTotals); 

    report.DoSanityCheck(); 

    Assert.IsTrue(report.FishyFlag); 
    Assert.That(report.DataWarnings.Where(x => x is Reports.WarningObjects.ImbalancedVariables && x.mid == 5461324658456716 && x.lineitem == "AggregateTotals").Count() > 0); 
} 

[Test] 
public void DoSanityCheck_WithCountEqualsZeroAndHouseGrossIsGreater_InAggregateTotals_SetsWarning() 
{ 
    InitializeTotals(report.AggregateTotals); 

    report.DoSanityCheck(); 

    Assert.IsTrue(report.FishyFlag); 
    Assert.That(report.DataWarnings.Where(x => x is Reports.WarningObjects.ImbalancedVariables && x.mid == null && x.lineitem == "AggregateTotals").Count() > 0); 
} 

[Test] 
public void DoSanityCheck_WithCountEqualsZeroAndHouseGrossIsGreater_InAggregateTotalsLineItem_SetsWarning() 
{ 
    InitializeTotals(report.AggregateTotals.LineItem["WirelessPerItem"]); 

    report.DoSanityCheck(); 

    Assert.IsTrue(report.FishyFlag); 
    Assert.That(report.DataWarnings.Where(x => x is Reports.WarningObjects.ImbalancedVariables && x.mid == null && x.lineitem == "WirelessPerItem").Count() > 0); 
} 
+0

ama yine de fazlalık bir çok şey bırakır. Bu kodu okumak ve her yinelemede test edilenin özünü çabucak almak zordur. Parametreler aynı şeyin farklı seviyelerde test edildiğini açıkça ortaya koyar. Bütün bu testler bire çökecek. –

+0

Tüm testleri tek bir sınamada daraltmanız önerilmez. Ayrı konular için ayrı testleriniz varsa, neyin doğru gittiğini ve neyin yanlış gittiğini bulmak daha kolaydır. Tek bir teste çok fazla koyarsanız, bir kerede çok fazla test edersiniz ve sorunları çözmek daha da zorlaşır. http://www.infoq.com/presentations/integration-tests-scam, bu konular hakkında da konuşulan iyi bir sunuma sahiptir. –

+3

Sağ. Ama parametreli testler ile kodu bir kere yazarım ama her bir parametre seti ayrı bir test gibi çalışıyor. Her TestCase NUnit test yolunda kendi hattını alır. Bu yüzden, hangi kısmın tam olarak başarısız olduğu hala açıktır, ancak kod yedeklemesi ortadan kalkar, bu da zaman yazmayı ve okumayı daha kolay hale getirir. –

4

Ben bazen ayrıştırmak dizeleri geçmesi, örnek, oldukça iyi okur düşünüyorum: bir ilerleme

[TestCase("15°", "-10°", 25, typeof(Degrees))] 
[TestCase("-10°", "15°", -25, typeof(Degrees))] 
[TestCase("-10°", "0°", -10, typeof(Degrees))] 
[TestCase("-90°", "1.5707 rad", -3.1414, typeof(Radians))] 
[TestCase("1.5707 rad", "-90°", 3.1414, typeof(Radians))] 
[TestCase("1.5707 rad", "1.5707 rad", 0, typeof(Radians))] 
public void SubtractionTest(string lvs, string rvs, double ev, Type et) 
{ 
    var lv = Angle.Parse(lvs); 
    var rv = Angle.Parse(rvs); 
    var diff = lv - rv; 
    Assert.AreEqual(ev, diff.Value, 1e-3); 
    Assert.AreEqual(et, diff.Unit.GetType()); 
} 
İlgili konular