如何在调用代码中找到任何属性?

How do I find any attributes in calling code?

我有一个测试设置,我用属性来装饰测试,告诉测试是否可以 运行 在某些情况下。在我的代码深处,我想检查测试方法是否具有某个属性。这能实现吗?

我的测试是这样的:

[TestClass, ParallelSeleniumTest, ExcludeFromCodeCoverage]
public class ExportIncident : ViewTest
{
    [TestMethod, TestCategory("ExcludeFromBuildServer"), SupportedBrowsers(Browser.FireFox)]
    public void Export()
    {
        ...
    }
}

在我想要断言 SupportedBrowserAttribute 值的深处,我的代码如下所示:

internal static RemoteWebDriver CreateDriver()
{
    // ReSharper disable HeuristicUnreachableCode
    switch (TestRunSettings.BrowserToUse)
    {
        case Browser.Firefox:
            return CreateFirefoxDriver();
        case Browser.Chrome:
            return CreateChromeDriver();
        default:
            throw new ArgumentOutOfRangeException();
    }
}

BrowserToUse 是文件中的常量。

CreateDriverViewTest 构造函数调用:

public abstract class ViewTest : WebTest
{
    protected ViewTest()
    {
        Driver = SeleniumManager.CreateDriver();
    }

    public RemoteWebDriver Driver { get; set; }
}

您可以像这样爬取堆栈帧:

MethodBase testMethod = null;
int framesSkipped = 0;

do 
{
    testMethod = (new StackFrame(framesSkipped++)).GetMethod();
} while (!testMethod.GetCustomAttributes(typeof(TestMethodAttribute), false).Any());

SupportBrowserAttribute sba = testMethod.GetCustomAttributes(typeof(SupportBrowserAttribute)).
    FirstOrDefault() as SupportBrowserAttribute;

所以我在堆栈中向上移动,直到找到具有 TestMethod 属性的方法。然后我尝试获取 SupportBrowser 属性。

如果测试方法没有这样的属性,sba将是null。否则你可以阅读它的属性并在你的 switch.

中使用它们

我改用 class 属性解决了它(不完美):

[TestClass, ParallelSeleniumTest, ExcludeFromCodeCoverage, SupportedBrowsers(Browser.FireFox)]
public class ExportIncident : ViewTest
{
    [TestMethod, TestCategory("ExcludeFromBuildServer")]
    public void Export()
    {
        ...
    }
}

ViewTest 我做的是:

public abstract class ViewTest : WebTest
{
    private RemoteWebDriver _driver;

    protected ViewTest()
    {
        Driver = SeleniumManager.CreateDriver();
    }

    public RemoteWebDriver Driver
    {
        get { return _driver; }
        set
        {
            var attribute = GetType().GetCustomAttribute<OnlySupportsBrowsersAttribute>();

            if (attribute != null && !attribute.Browsers.Any(x => x == TestRunSettings.BrowserToUse))
            {
                Assert.Inconclusive($"Browser {TestRunSettings.BrowserToUse} is not supported by this test");
            }

            _driver = value;
        }
    }
}