【问题标题】:How to find C# entry point for Non exe program?如何找到非 exe 程序的 C# 入口点?
【发布时间】:2014-05-05 18:39:27
【问题描述】:

我阅读的有关 C# 入口点类的所有信息都涉及:

static int Main(string[] args)

因为这是特定于 EXE 程序的。

但我的程序是一个 C# 自动化测试框架(解决方案中的 .cs),设计有 Specflow 功能文件和步骤定义。

我现在添加了一个名为 Program.cs - Int Main 类的(入口点)类,但我注意到在运行我的自动化测试时不会调用这个入口点类。很可能是因为我的程序不是 EXE 程序而是测试框架。

如何找到非 exe 程序的 C# 入口点?

因为我想使用我每次运行测试时都会调用的类中的“报告”代码:

namespace Project.Core
{
    public class Program
    {
        public static int Main(string[] args)
        {
            Adapter.DefaultSearchTimeout = 5000;

            int error;
            try
            {
                error = TestSuiteRunner.Run(typeof (Program), Environment.CommandLine);
            }
            catch (Exception e)
            {
                TestReport.Setup(ReportLevel.Debug, "myReport.rxlog", true);
                Report.Screenshot();
                throw new ApplicationException("Error Found", e);
            }
            return error;
        }
    }
}

【问题讨论】:

  • 不熟悉 Specflow,但它是加载和运行您的代码的程序吗?如果是这样,您必须查看 Specflow 的文档以了解它如何决定加载哪些类、运行哪些方法以及以什么顺序。最有可能的是,它会实例化您的一个类并在其上调用非静态方法,因此更改放置静态 Main 方法的位置可能不会有任何效果。
  • 尝试在 SpecFlow 上阅读 this tutorial

标签: c# entry-point


【解决方案1】:

非 exe 项目(即 DLL)没有入口点。它们是由其他进程调用的 API,它们有自己的入口点。

您应该针对与 SpecFlow 一起使用的测试框架研究适当的“测试前”方法。例如,在 MSTest 中,此类代码将进入具有以下签名的方法中:

[TestInitialize]
public void TestInitialize()
{
    // Your code
}

MSDN Documentation.

【讨论】:

  • 感谢您对“没有入口点的非 exe 项目(即 DLL)”的解释。这非常有用。我正在使用 MsTest,但不幸的是 [TestInitialize] 没有像我想要的那样充当 Try/Catch。由于我的项目同时使用 MsTest 和 teh Ranorex API,我无法确定在测试运行之前/期间初始化项目的哪个方面。所以我决定将 Try/Catch 代码结构直接添加到我项目中的每个方法中。
  • 您可以尝试添加每个方法和属性之一([AssemblyInitialize][ClassInitialize][TestInitialize][TestCleanup][ClassCleanup][AssemblyCleanup],如 MSDN 文档中所述) 到您的项目并在调试器中逐步执行它,看看会发生什么让您有更多的了解。随着时间的推移,您可能会发现,随着测试数量的增加,在每个方法中都使用 try-catch 变得无法维护。
【解决方案2】:

由于我的项目同时使用 MsTest 和 Ranorex API,我无法确定在测试运行之前/期间正在初始化项目的哪个方面。所以我决定将 Try/Catch 代码结构直接添加到我项目中的每个 Step Defintion 方法中。

Try()
{
    // code
}
Catch (Exception e)
{
    TestReport.Setup(ReportLevel.Debug, "myReport.rxlog", true);
    Report.Screenshot();
    throw new ApplicationException("Error Found", e);
} 

而且我可以轻松地将 Catch 代码移动到辅助类中,这样我的项目中就只有一个代码实例:

catch (Exception)
{
    WpfHelpers.ExtensionMethods.CatchException(null);
}

助手类:

public static class ExtensionMethods
{
    public static void CatchException(SystemException e)
        {
            TestReport.Setup(ReportLevel.Debug, "myReport.rxlog", true);
            Report.Screenshot();
            throw new ApplicationException("Error Found", e);
        }
}

请注意,我使用这种结构是为了在发生故障时可以利用 Ranorex 的 Report.Screenshot 功能。

【讨论】:

  • 我建议您只在 catch 块中使用 throw 而不是抛出新异常,以便在 MSTest 结果中获得所有异常元数据(即类型和原始堆栈跟踪),而不是每一次失败都只是从您的测试代码中抛出的ApplicationException
  • 好点。我现在已经使用这两种方法进行了测试: throw new Exception("Error Found", e);并抛出(e);。投掷(e);返回更清晰的 Exception Handled stacktrace: -> error: No element found for path '//nothing' 在 1000 毫秒内。测试方法 -Tests.Features.ReportScreenshotFeature.ReportScreenshot 抛出异常:Ranorex.ElementNotFoundException: No element found for path '//nothing' within 1000ms.
  • 您应该只在原始捕获中使用throw,而不是在CatchException(Exception) 中使用throw e,以便保留堆栈跟踪。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-10
  • 1970-01-01
  • 2019-09-11
  • 1970-01-01
  • 2015-10-12
  • 1970-01-01
相关资源
最近更新 更多