12

我正在使用Approval Tests。在我的开发机器上,当我的测试结果与批准的不同时,我很高兴DiffReporter启动TortoiseDiff :

    [UseReporter(typeof (DiffReporter))]
    public class MyApprovalTests
    { ... }

但是,当在 Teamcity 上运行相同的测试并且结果不同时,测试会失败并出现以下错误:

System.Exception : Unable to launch: tortoisemerge.exe with arguments ...
Error Message: The system cannot find the file specified
---- System.ComponentModel.Win32Exception : The system cannot find the file 
                                                                 specified

显然它找不到 tortoisemerge.exe,这很好,因为它没有安装在构建代理上。但是如果安装了呢?然后每次失败都会启动另一个 tortoisemerge.exe 实例,没有人会关闭它。最终,大量的 tortoisemerge.exe 实例会杀死我们的服务器 :)

所以问题是——应该如何修饰测试以在本地机器上运行 Tortoise Diff 并在构建服务器上报告错误?我知道, #IF DEBUG [UseReporter(typeof (DiffReporter))]但如果可能的话,我更喜欢另一种解决方案。

4

4 回答 4

9

Reporters 和 CI 的问题有几个解决方案。我将它们全部列出,然后指出一个更好的解决方案,该解决方案尚未完全启用。

  1. 使用 AppConfigReporter。这允许您在 AppConfig 中设置报告器,并且您可以使用 QuietReporter 进行 CI。这里有一段视频,还有许多其他记者。AppConfigReporter 出现在 6:00。这具有单独配置的优点,您可以在程序集级别进行装饰,但缺点是如果您在类/方法级别覆盖,您仍然会遇到问题。

  2. 创建您自己的 (2) 个记者。值得注意的是,如果您使用记者,无论它是否在环境中工作,它都会被调用。IEnvironmentAwareReporter 允许复合报告器,但不会阻止直接调用报告器。您很可能需要 2 个记者,一个什么都不做(就像一个安静的记者)但只在您的 CI 服务器上工作,或者在被 TeamCity 调用时工作。将其称为 TeamCity 记者。还有一个,它是一个 multiReporter,如果它正在工作,它会调用 teamCity,否则遵从 .

  3. 使用 FrontLoadedReporter(还没有准备好)。这就是 ApprovalTests 当前使用 NCrunch 的方式。它在您的 UseReporter 属性中加载的任何内容之前执行上述方法。我一直想添加一个装配级属性来配置它,但还没有(抱歉)我会尽快添加它。

希望这可以帮助。卢埃林

于 2012-03-30T15:19:16.187 回答
4

我最近自己也遇到了这个问题。

借用 xunit 以及他们如何处理 TeamCity 日志记录,我想出了一个基于 NCrunch Reporter 的 TeamCity Reporter。

public class TeamCityReporter : IEnvironmentAwareReporter, IApprovalFailureReporter
{
    public static readonly TeamCityReporter INSTANCE = new TeamCityReporter();

    public void Report(string approved, string received) { }

    public bool IsWorkingInThisEnvironment(string forFile)
    {
        return Environment.GetEnvironmentVariable("TEAMCITY_PROJECT_NAME") != null;
    }
}

所以我可以将它与 NCrunch 记者结合起来:

public class TeamCityOrNCrunchReporter : FirstWorkingReporter
{
    public static readonly TeamCityOrNCrunchReporter INSTANCE = 
        new TeamCityOrNCrunchReporter();

    public TeamCityOrNCrunchReporter()
        : base(NCrunchReporter.INSTANCE,
        TeamCityReporter.INSTANCE) { }
}

[assembly: FrontLoadedReporter(typeof(TeamCityOrNCrunchReporter))]
于 2012-08-12T14:23:01.010 回答
2

我只是想出了一个小主意。

您可以实现自己的报告器,我们称之为 DebugReporter

public class DebugReporter<T> : IEnvironmentAwareReporter where T : IApprovalFailureReporter, new()
{
    private readonly T _reporter;

    public static readonly DebugReporter<T> INSTANCE = new DebugReporter<T>();

    public DebugReporter()
    {
        _reporter = new T();
    }

    public void Report(string approved, string received)
    {
        if (IsWorkingInThisEnvironment())
        {
            _reporter.Report(approved, received);
        }
    }

    public bool IsWorkingInThisEnvironment()
    {
#if DEBUG
        return true;
#else
        return false;
#endif
    }
}

使用示例,

[UseReporter(typeof(DebugReporter<FileLauncherReporter>))]
public class SomeTests
{
    [Test]
    public void test()
    {
        Approvals.Verify("Hello");
    }
}

如果测试失败,它仍然会是红色的——但记者不会出现。

IEnvironmentAwareReporter是专门为此定义的,但不幸的是,无论我返回那里,它仍然调用 Report() 方法。所以,我把 IsWorkingInThisEnvironment() 调用放在了里面,这有点骇人听闻,但有效:)

希望 Llywelyn 能解释为什么会这样。(漏洞?)

于 2012-03-30T09:35:23.447 回答
1

我正在使用 CC.NET,并且我确实在服务器上安装了 TortoiseSVN。

我重新配置了我的构建服务器以允许 CC.NET 服务与桌面交互。当我这样做时, TortiseMerge 启动了。所以我认为正在发生的事情是 Approvals 试图启动该工具,但它不能,因为 CC.NET 作为服务运行并且操作系统默认阻止该行为。如果 TeamCity 作为服务运行,您应该没问题,但您可能需要进行测试。

于 2012-03-30T14:24:22.460 回答