2016-04-01 14 views
0

Daha sonra kullanacağım özel öznitelikler, SpecificationAttribute ve VerificationAttribute ile MSTest testlerimi yapıyorum.Bir önceki Linq ifadesinin parçası olmak için bu foreach'ı nasıl yeniden yazabilirim?

nitelikleri şu şekilde görünür:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] 
public class SpecificationAttribute : Attribute 
{ 
    public SpecificationAttribute(int step, string text) 
    { 
     Step = step; 
     Text = text; 
    } 

    public int Step { get; set; } 

    public string Text { get; set; } 
} 

Bir test yöntemi niteliklerin kullanımında benzersiz adımları olması gerektiğini belirtmektedir bir test yazdım. olması gerektiği gibi Örneğin, aşağıdaki kullanımı, benim deneyi geçemiyor:

[Specification(1, "Click Button)]
[Verification(1, "Verify popup")]
[Specification(1, "Click close")]

Testim şöyle görünür:

[TestMethod] 
public void TestForNoDuplicateStepsOnMethod() 
{ 
    var specificationMethods = Assembly.GetExecutingAssembly().GetTypes() 
     .Where(type => 
      type.GetCustomAttribute<CompilerGeneratedAttribute>() == null && 
       type.GetCustomAttribute<TestClassAttribute>() != null) 
     .SelectMany(type => type.GetMethods()) 
     .Where(methodInfo => 
      methodInfo.GetCustomAttribute<TestMethodAttribute>() != null && 
      methodInfo.GetCustomAttributes<SpecificationAttribute>().Any()) 
     .ToArray(); 

    foreach (var method in specificationMethods) 
    { 
     var specificationAttributes = method.GetCustomAttributes<SpecificationAttribute>(); 

     var duplicates = specificationAttributes.GroupBy(s => s.Step).Where(grp => grp.Count() > 1).SelectMany(x => x).ToList(); 

     if (duplicates.Any()) 
     { 
      var initialMessage = [email protected]"{Environment.NewLine}{method.DeclaringType}.{method.Name} contains several SpecificationAttribute with the same step number." + Environment.NewLine + Environment.NewLine; 

      var message = duplicates.Aggregate(initialMessage, (s, attribute) => s + attribute.Step + " " + attribute.Text + Environment.NewLine); 

      Assert.Fail(message); 
     } 
    } 
} 

ben yeniden yazmak istiyorum Son kısım, böylece Linq sorgusunun bir parçası olur. Mümkün mü? Ayrıca, şu anki testim sadece başarısız bir yöntem çıktılar. Linq sorgusu, benzersiz adım numarasında başarısız olan tüm yöntemleri içerebiliyorsa, bu arzu edilebilir olacaktır.

cevap

1

bu deneyin ama IMHO okumak çok daha zordur.

[TestMethod] 
public void TestForNoDuplicateStepsOnMethod() 
{ 
    var errors = Assembly.GetExecutingAssembly().GetTypes() 
     .Where(type => 
      type.GetCustomAttribute<CompilerGeneratedAttribute>() == null && 
       type.GetCustomAttribute<TestClassAttribute>() != null) 
     .SelectMany(type => type.GetMethods()) 
     .Where(methodInfo => 
      methodInfo.GetCustomAttribute<TestMethodAttribute>() != null && 
      methodInfo.GetCustomAttributes<SpecificationAttribute>().Any()) 
     .Select(method => 
      method.GetCustomAttributes<SpecificationAttribute>() 
     .GroupBy(s => s.Step) 
      .Where(grp => grp.Count() > 1) 
      .Select(x => x.Aggregate(
       [email protected]"{Environment.NewLine}{method.DeclaringType}.{method.Name} contains several SpecificationAttribute with the same step number." 
       + Environment.NewLine, 
       (s, attribute) => s + attribute.Step + " " + attribute.Text + Environment.NewLine)) 
       .Aggregate("", (s, message) => s + message)) 
      .Aggregate("", (s, message) => s + message); 
     Assert.AreEqual("", errors); 
} 
+0

Awesome! Yine de 100 \ r \ n üretir, bu yüzden hatalar boş değildir. – Drutten

+0

Küçük hack'imle çalışıyorum: 'error = Regex.Replace (error, @"^\ s + $ [\ r \ n] * "," ", RegexOptions.Multiline);' 'Assert.IsTrue (string.IsNullOrEmpty (hatalar), hatalar); ' – Drutten

+1

Son üç satırı değiştirerek Regex olmadan giderildi. –

1

Bunu deneyebilirsiniz var specificationMethods üzerinde ameliyat daha yapmak gerekir yoksa:

(pozitif testlerle sorunu çözmek için Düzenlendi)
[TestMethod] 
    public void TestForNoDuplicateStepsOnMethod() 
    { 
     Assembly.GetExecutingAssembly().GetTypes() 
      .Where(type => 
       type.GetCustomAttribute<CompilerGeneratedAttribute>() == null && 
        type.GetCustomAttribute<TestClassAttribute>() != null) 
      .SelectMany(type => type.GetMethods()) 
      .Where(methodInfo => 
       methodInfo.GetCustomAttribute<TestMethodAttribute>() != null && 
       methodInfo.GetCustomAttributes<SpecificationAttribute>().Any()) 
      .ToList().ForEach (method=> 
     { 
      var specificationAttributes = method.GetCustomAttributes<SpecificationAttribute>(); 

      var duplicates = specificationAttributes.GroupBy(s => s.Step).Where(grp => grp.Count() > 1).SelectMany(x => x).ToList(); 

      if (duplicates.Any()) 
      { 
       var initialMessage = [email protected]"{Environment.NewLine}{method.DeclaringType}.{method.Name} contains several SpecificationAttribute with the same step number." + Environment.NewLine + Environment.NewLine; 

       var message = duplicates.Aggregate(initialMessage, (s, attribute) => s + attribute.Step + " " + attribute.Text + Environment.NewLine); 

       Assert.Fail(message); 
      } 
    } 
    } 
}