C# 您能像调用类字段一样以编程方式调用方法吗?

C# 您能像调用类字段一样以编程方式调用方法吗?,c#,class,oop,testing,C#,Class,Oop,Testing,我正在为我的程序编写一个自动化测试套件,并一直在寻找简化和重新考虑大量代码的方法 目前,我有许多try/catch块(因为我希望能够从一个测试移动到下一个测试,即使是在失败的情况下),它们可以记录其他信息。看起来有点像这样: try { PerformTest1(); } catch(Exception e) { file.WriteLine("Unable to perform test number 1."); file.WriteLine("Error: " + e

我正在为我的程序编写一个自动化测试套件,并一直在寻找简化和重新考虑大量代码的方法

目前,我有许多try/catch块(因为我希望能够从一个测试移动到下一个测试,即使是在失败的情况下),它们可以记录其他信息。看起来有点像这样:

try
{
    PerformTest1();
}
catch(Exception e)
{
    file.WriteLine("Unable to perform test number 1.");
    file.WriteLine("Error: " + e.Message);
    file.WriteLine("StackTrace: " + e.StackTrace);
}

try
{
    PerformTest2();
}
catch(Exception e)
{
    file.WriteLine("Unable to perform test number 2.");
    file.WriteLine("Error: " + e.Message);
    file.WriteLine("StackTrace: " + e.StackTrace);
}
等等。我想知道我是否可以做一系列这些测试,这样我就可以使用一个循环。比如:

foreach(Test t in testsArray)
{
    try
    {
        t.RunTest();
    }
    catch(Exception e)
    {
        file.WriteLine(t.failDescription);
        file.WriteLine("Error: " + e.Message);
        file.WriteLine("StackTrace: " + e.StackTrace);
    }
}

我如何执行它,但不使每个测试都成为自己的类(使用RunTest()方法)?我在考虑制作一个测试类,它有必要的字段,其中一个是方法。然后我可以创建一个测试对象,并调用objects方法。这样的事情可能吗?或者我必须创建多个测试类吗?

您需要一个带有
runTest()方法的
test
接口,但是您可以使用匿名类或lambda表达式实现逻辑(如果您使用的是Java 8),这样您就不必为每个测试创建显式类

例如:

Test test1 = new Test () {
    public void runTest () {
    // logic of first test here
    }
};
实际上,您不需要创建自己的接口。使用现有的
Runnable
接口及其
run()
方法

Runnable test1 = new Runnable () {
    public void run () {
    // logic of first test here
    }
};
或使用lambda表达式:

Runnable test1 = () -> {
                        // logic of first test here
                       };
然后,您可以将这些
Runnable
s中的每一个添加到列表(或数组)中,并根据需要在循环中运行它们:

for (Runnable test in testsArray)
{
    try {
       test.run();
    }
    catch(Exception e)
    {
       ...
    }
} 

您可以使用一些Lambda技巧:

var actions = new List<Action>();
actions.Add(PerformTest1);  // requires a void PerformTest1() method
actions.Add(PerformTest2);
//...  and so on...

好的,这似乎是老生常谈,但这是第一件事,你应该了解接口。

你有没有研究过.Net/Java可用的测试框架?我相信Nunit(或JUnit)提供了许多您想要的功能,包括在发生故障时写出堆栈跟踪和异常详细信息


还可以将多个测试封装在一个测试夹具中,因此允许您在失败后仍然执行后续测试,而不会在各个测试之间泄漏数据或状态。

我使用的是TestStack.White,一个用于.Net的自动化UI测试框架。事实上我很喜欢它。我不确定它提供了什么样的“测试”接口,但肯定会研究它。在.Net中,用I作为首字母命名接口被认为是最佳实践,因此
Testable
应该是
ITestable
。@Chris:啊,好的。在Java中,这将是一种糟糕的风格。有趣的是,有很多不同的命名约定仍然让我感到困惑(我主要来自Java背景,但现在使用.Net)。不过界面背后的概念是一样的,谢谢你的帮助!你在这里没有使用任何lambada,只使用代理。是的。。。我知道。。。在第一个版本中,我使用了lambda,但随后我在VS中再次检查了解决方案,以防止一些打字错误。那一刻,ReSharper介入并简化了代码:)对不起,我从来没有接受过这一点,我最终使用了类似的方法。在Test类中,我创建了一个名为
RunTest
的虚拟方法,该方法为我的每个测试重写,并使用它来运行和记录它们。谢谢
foreach(var action in actions)
{
   action();
}
public interface Testable {
    void doTest();
}
public class Test1 implements Testable {
    // implement doTest()
}
private static Testable[] testables = new Testabable[] {
    new Test1()
};
// now iterate your testables and call doTest()