所以我有一个负载的实例类的名称空间,我不能改变。这些实际上是导出的硒测试,但该细节与此无关。
每个类都有几个需要调用的方法。有些方法名是基于类名的。方法看起来像
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();
}
但是这不起作用,因为driver属性是私有的。这意味着我认为我需要重写SetupTest()方法。这将是很好的,如果我可以从登录继承,但我不知道如何做到这一点时,类型只有通过反射。
您已经通过反射获取并调用了一个方法,所以设置一个字段也没什么大不了的:
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();
}