所以我在命名空间中加载了一个实例类,我无法改变。这些实际上是出口硒测试,但细节不相关。
每个类都有几个我需要调用的方法。一些方法名称基于类名。所以方法看起来像
public void The[Class]Test{ blah blah}
我有代码来获取所有类的类似列表
var tests = (from t in Assembly.GetExecutingAssembly().GetTypes()
where t.IsClass && t.Namespace == "SeleniumTests"
select t).ToList();
然后我想循环遍历这些类型并执行该方法。
我无法弄清楚如何使用动态创建的对象动态继承测试类,该对象具有覆盖或替代我想要调用的方法。
然后我尝试使用expando对象并复制该类的各个部分。这不起作用,因为我需要的一些属性保留在类实例中并且是私有的,所以只能在我需要覆盖的方法中设置。
所以基本上我认为我需要一些方法来修改其名称在运行时已知的类的行为。
修改
我想覆盖的方法在实例上设置私有属性。 基类看起来像这样。
[TestFixture]
public class Login
{
private IWebDriver driver;
[SetUp]
public void SetupTest()
{
driver = new FirefoxDriver();
}
[TearDown]
public void TeardownTest()
{
}
[Test]
public void TheLoginTest()
{
}
}
我想将FirefoxDriver()更改为Chrome或IE驱动程序。
所以我试过了
static void Main(string[] args)
{
var tests = (from t in Assembly.GetExecutingAssembly().GetTypes()
where t.IsClass && t.Namespace == "SeleniumTests"
select t).ToList();
foreach (var t in tests)
{
var test = (dynamic)Activator.CreateInstance(t);
test.driver = new ChromeDriver();
test.SetupTest();
t.GetMethod(String.Format("The{0}Test", t.Name)).Invoke(test, null);
test.TeardownTest();
}
Console.ReadLine();
}
但这不起作用,因为驱动程序属性是私有的。这意味着我认为我需要覆盖SetupTest()方法。如果我可以从Login继承,那么没关系,但是当仅通过反射知道类型时我不知道如何做到这一点。
答案 0 :(得分:1)
您已经通过反射获取并调用方法,因此设置字段也没什么大不了的:
foreach (var t in tests)
{
var test = (dynamic)Activator.CreateInstance(t);
test.SetupTest();
t.GetField("driver", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(test, new ChromeDriver());
t.GetMethod(String.Format("The{0}Test", t.Name)).Invoke(test, null);
test.TeardownTest();
}