【问题标题】:How to add support for xunit's Theory attribute in Approvaltests如何在 Approvaltests 中添加对 xunit 的 Theory 属性的支持
【发布时间】:2012-08-21 11:46:12
【问题描述】:

当我尝试使用带有[Theory] 属性装饰的单元测试的批准时,它会说:

System.Exception: System.Exception : Approvals is not set up to use your test framework.
It currently supports [NUnit, MsTest, MbUnit, xUnit.net]
To add one use ApprovalTests.StackTraceParsers.StackTraceParser.AddParser() method to add implementation of ApprovalTests.StackTraceParsers.IStackTraceParser with support for your testing framework.
To learn how to implement one see http://blog.approvaltests.com/2012/01/creating-namers.html
   at ApprovalTests.StackTraceParsers.StackTraceParser.Parse(StackTrace stackTrace)
   at ApprovalTests.Namers.UnitTestFrameworkNamer..ctor()
   at ApprovalTests.Approvals.GetDefaultNamer()
   at ApprovalTests.Approvals.Verify(IApprovalWriter writer)
   at ApprovalTests.Approvals.Verify(Object text)

似乎它只识别[Fact] 属性。我尝试关注link from stacktrace,但没有任何关于如何将您自己的命名器/解析器插入审批。

是否有任何入口点可以添加我自己的命名器/解析器?它本身似乎是微不足道的,唯一的问题是如何使用它:

 public class TheoryNamer : AttributeStackTraceParser
    {
        protected override string GetAttributeType()
        {
            return typeof(TheoryAttribute).FullName;
        }

        public override string ForTestingFramework
        {
            get { return "xUnit Extensions"; }
        }
    }

【问题讨论】:

    标签: c# unit-testing xunit.net approval-tests


    【解决方案1】:

    这个答案和问题有几个部分。

    1. 如何添加
    2. 命名者
    3. 在批准测试中处理数据驱动测试

    1) 如何添加

    添加很简单(如果有点粗糙) 提到的方法应该是静态的,但它仍然有效。

    添加一个用途 ApprovalTests.StackTraceParsers.StackTraceParser.AddParser() 方法 添加实现 ApprovalTests.StackTraceParsers.IStackTraceParser 支持 你的测试框架。

    所以你需要做一个

    new StackTraceParser().AddParser(new TheoryNamer());
    

    对此我深表歉意,在下一个版本(v.21)中它将是静态的

    2) 命名者

    命名器应该为每个批准/接收的文件生成一个唯一的名称。这通常在方法的名称上完成,但是这里的名称不会是唯一的,因为基于理论的测试将是数据驱动的,因此对同一方法有多次调用。

    Naming:  classname.methodname(optional: .additionalInformation).received.extension
    

    因此,您可能必须在其自身的方法中包含其他信息

    public class StringTests1
    {
        [Theory,
        InlineData("goodnight moon"),
        InlineData("hello world")]
        public void Contains(string input)
        {
            NamerFactory.AdditionalInformation = input;  // <- important
            Approvals.Verify(transform(input));
        }
    } 
    

    3) 在批准测试中处理数据驱动测试

    说实话,在大多数情况下,Approval Tests 中的数据驱动方法不是通过 Method Decorators 中的参数。它通常通过带有 lambda 变换的 VerifyAll。例如,上面可能看起来像

    [Fact]
    public void UpperCase()
    {
        var inputs = new[]{"goodnight moon","hello world"};
        Approvals.VerifyAll(inputs, i => "{0} => {1}".FormatWith(i, i.ToUpperInvariant()));
    }
    

    这将创建接收到的文件:

    goodnight moon => GOODNIGHT MOON
    hello world => HELLO WORLD
    

    【讨论】:

    • 感谢您的解释!我没有注意到StackTraceParser.parsers 确实是静态的:)
    【解决方案2】:

    最好从 XUnitStackTraceParser 继承 TheoryNamer 类。
    效果很好!
    我认为将此类添加到 ApprovalTests.StackTraceParsers 命名空间会很酷:)

    public class XUnitTheoryStackTraceParser : XUnitStackTraceParser
    {
        public const string TheoryAttribute = "Xunit.Extensions.TheoryAttribute";
    
        protected override string GetAttributeType()
        {
            return TheoryAttribute;
        }
    }
    
    public class ApproveTheoryTest
    {
        static ApproveTheoryTest()
        {
            StackTraceParser.AddParser(new XUnitTheoryStackTraceParser());
        }
    
        [Theory]
        [UseReporter(typeof(DiffReporter))]
        [InlineData("file1.txt")]
        [InlineData("file2.txt")]
        public void approve_file(string fileName)
        {
            NamerFactory.AdditionalInformation = fileName;
            Approvals.Verify("sample text");
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-06
      • 1970-01-01
      • 1970-01-01
      • 2015-07-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多