将字符串转换为 C# 代码

发布于 2024-08-17 05:25:50 字数 771 浏览 6 评论 0原文

在当前的 NUnit 版本中,我可以参数化 TestFixture 并多次实例化它。例如:

[TestFixture("var1")]  
[TestFixture("var2")]  
[TestFixture("var3")]  
public class MyTestFixture  
{  
    private string var;  

    public MyTestFixture(string var)  
    {  
        this.var = var;  
    }  

    ...  

}  

这将使用 argument 参数实例化 MyTestFixture 3 次。我的问题是当前的 NUnit 没有 TextFixture 属性的数据源功能(只有 TestCaseSource)。我需要根据数据输入实例化TestFixture,每个TestFixture都有一组不同的测试用例数据输入。得益于 TestCaseSource,测试用例数据驱动没有问题。但是我该如何为 TestFixture 属性执行此操作呢?

我的想法是动态生成 TestFixture 属性,然后将其更改为代码字符串并插入到测试代码中,例如:像这样:

ConvertToCode(GenerateTestFixture());  
public class MyTestFixture  
{  
   ...  
}  

我怎样才能做到这一点?或者有更好的方法吗?

非常感谢您的帮助。

谨致问候,
爱德华

in the current NUnit version, I can parameterized TestFixture and instantiated it multiple times. E.g.:

[TestFixture("var1")]  
[TestFixture("var2")]  
[TestFixture("var3")]  
public class MyTestFixture  
{  
    private string var;  

    public MyTestFixture(string var)  
    {  
        this.var = var;  
    }  

    ...  

}  

This will instantiate the MyTestFixture 3 times with the argument parameter. My problem is the current NUnit doesn't have datasource feature for TextFixture attribute (only TestCaseSource). I need to instantiate the TestFixture based on the data input, and each TestFixture has a different sets of test case data input. No problem with the Test case data driven, thanks to the TestCaseSource. But how can I do this for the TestFixture attribute?

My idea is to generate the TestFixture attribute on the fly then change it to code string and insert into the test code, e.g.: something like this:

ConvertToCode(GenerateTestFixture());  
public class MyTestFixture  
{  
   ...  
}  

How can I do this? Or are there a better way?

Thank you very much for your help.

Best regards,
Edward

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

苄①跕圉湢 2024-08-24 05:25:50

动态地为您的方法创建属性是可能的,但很困难。你最好寻找另一种方法。

当您的代码被编译并自动插入到您的代码中时,编译器会读取您所拥有的类型的属性(例如[TestFixture])。

要为类生成您自己的属性,您需要使用 Reflection.Emit 之类的工具来修改生成的程序集,作为项目的构建后步骤。这就像直接编写汇编语言(您将创建 MSIL),这可能很有趣,但并不容易,并且会使您的代码很难维护!

另一种方法可能是使用枚举控制测试用例,并使用一个方法来检查枚举并返回适当的数据:

public enum TestController
{
    Value1,
    Value2,
    Value3
}

[TestFixture(TestController.Value1)]   
[TestFixture(TestController.Value2)]   
[TestFixture(TestController.Value3)]   
public class MyTestFixture   
{   
    public MyTestFixture(TestController testController)   
    {   
        var dataForTest = GetDataForTest(testController);
    }   

    ...   

}   

方法 GetDataForTest() 然后将生成某种 switch 语句数据。

另一种方法可能是使用类型而不是枚举,然后在 GetDataForTest() 方法中实例化该类型并调用工厂方法 - 但我认为这可能有点过于复杂。

Creating attributes for your method on the fly is possible but hard. You're better off finding another approach.

Attributes (e.g. [TestFixture]) of the kind you have are read by the compiler when your code is compiled and inserted in to your code automatically.

To generate your own attributes for classes you'll need to use something like Reflection.Emit to modify generated assemblies as a post-build step for the project. This is like writing assembly language directly (you'd be creating MSIL) which might be fun but is not easy and would make your code very hard to maintain!

An alternative approach might be to have an enum control the test cases, and have a method that checks the enum and returns the appropriate data:

public enum TestController
{
    Value1,
    Value2,
    Value3
}

[TestFixture(TestController.Value1)]   
[TestFixture(TestController.Value2)]   
[TestFixture(TestController.Value3)]   
public class MyTestFixture   
{   
    public MyTestFixture(TestController testController)   
    {   
        var dataForTest = GetDataForTest(testController);
    }   

    ...   

}   

The method GetDataForTest() would then have some kind of switch statement to generate the data.

An alternative approach might be to use a type rather than an enum, then instantiate the type in the GetDataForTest() method and call a factory method - but I think that might be a bit overcomplicated.

纸短情长 2024-08-24 05:25:50

看看那里:

http://www. dotnetspider.com/resources/26499-Making-NUnit-test-cases-data-driven.aspx

[TestCaseSource] 和 TestCaseData 是您正在寻找的类

Take a look there:

http://www.dotnetspider.com/resources/26499-Making-NUnit-test-cases-data-driven.aspx

[TestCaseSource] and TestCaseData are the classes you're looking for

﹏半生如梦愿梦如真 2024-08-24 05:25:50

现在,在 NUnit 3.x 中可以使用 TestFixtureSource 属性实现这一点。创建一个用您的值实现 IEnumerable 的类,然后像这样使用它:

[TestFixtureSource(typeof(Foo), Category = "Quux")]
public class BarTest
{    
     public BarTest(object baz)
     {
         _baz = baz;
     {
}

TestCaseSource 发生的变化并适用于 TestFixtureSource 是您必须为其提供一个实现 IEnumerable 的类型或为其提供一个静态方法。如果您依赖从构造函数生成数据的属性或方法,那么您需要以静态方式重构,或者只让类实现 IEnumerable 本身并将其自身作为源类型传入。

This is now possible in NUnit 3.x using the TestFixtureSource attribute. Create a class that implements IEnumerable with your values then use it like so:

[TestFixtureSource(typeof(Foo), Category = "Quux")]
public class BarTest
{    
     public BarTest(object baz)
     {
         _baz = baz;
     {
}

One thing that has changed with TestCaseSource and applies to TestFixtureSource is that you have to either give it a type that implements IEnumerable or give it a static method. If you were relying on properties or methods that generate data from the constructor, then you need to either refactor in a static way or just have the class implement IEnumerable itself and pass itself in as the source type.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文