Question

I have some code that generates a report based off the attributes of my CodedUI test project. I want to be able to add the TestCategoryAttribute to this report but I don't know how to adapt my code to allow for duplicate attributes like below:

[TestMethod]
[TestCategory("Smoke")]
[TestCategory("Feature1")]
public void CodedUITest()
{
}

The code below works when I only have one TestCategory but will not work with multiple test categories as above:

//Other code above to find all CodedUI classes and all public, nonstatic methods with the TestMethod attribute

//find method with testcategory attribute
if (attrs.Any(x => x is TestCategoryAttribute))
{
   var testcategoryAttr = (TestCategoryAttribute)attrs.SingleOrDefault(x => x is TestCategoryAttribute);
   string testCategories = string.Join(", ", testcategoryAttr.TestCategories.Select(v => v.ToString()));
}
Was it helpful?

Solution 3

Here is the solution that ultimately worked for me. I asked an actual developer this question instead of trying to figure it out myself (I'm QA) :) I had to add some special logic to format the string properly because the attr.TestCategories object is a List.

//find method with testcategory attribute
if (attrs.Any(x => x is TestCategoryAttribute))
{
    var testCategoryAttrs = attrs.Where(x => x is TestCategoryAttribute);
    if (testCategoryAttrs.Any())
    {
        foreach (var testCategoryAttr in testCategoryAttrs)
        {
            TestCategoryAttribute attr = (TestCategoryAttribute)testCategoryAttr;
            testCategories += string.IsNullOrEmpty(testCategories)
                ? string.Join(", ", attr.TestCategories)
                : string.Format(", {0}", string.Join(", ", attr.TestCategories));
        }
    }                               
}

OTHER TIPS

Replace the SingleOrDefault with the Where:

var testcategoryAttrs = attrs.Where(x => x is TestCategoryAttribute)
                             .Select(x => ((TestCategoryAttribute)x).TestCategory);
string testCategories = string.Join(", ", testcategoryAttrs.ToArray());

I don't know the property name in the TestCategoryAttribute, so I used the TestCategory in this sample.

SingleOrDefault throws an exception if there is more than one item that mathes with your condition.In this case you have two attributes and that's why you are getting the exception.

If you want to get only one item, then use FirstOrDefault. It returns the first item that mathces with the condition otherwise it returns null so you should be careful when casting returning result of FirstOrDefault, you may want to add a null-check before the cast,since you are using Any method and make sure there is at least one TestCategoryAttribute exists, null-check is not necessary in this case.

var testcategoryAttr = (TestCategoryAttribute)attrs
                       .FirstOrDefault(x => x is TestCategoryAttribute);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top