是否可以参数化 NUnit 测试?

发布于 2024-10-14 11:20:05 字数 239 浏览 2 评论 0原文

我想编写一个可调用函数,它接受两个对象,并将这些对象的 30 多个属性与断言进行比较。问题是这需要对大约 20 个现有单元测试和大多数未来测试进行,并且每次写出 30 多个断言既耗时又耗时。

我目前有一个非单元测试函数,它比较对象,并返回带有“通过”或“失败”消息的字符串,并使用断言在每个单元测试中验证它。然而,它非常混乱,我觉得我正在反对正确的单元测试方法。

有没有办法制作一个可从内部单元测试调用的函数,该函数使用断言来检查条件?

I would like to write a callable function that accepts two objects, and compares 30+ properties of those objects with asserts. The issue is this needs to be done for about 20 existing unit tests and most future tests, and writing out the 30+ asserts each time is both time and space consuming.

I currently have a non unit test function that compares the objects, and returns a string with "pass" or a "failure" message, and use an assert to validate that in each unit test. However, its quite messy and I feel like I'm going against proper unit testing methods.

Is there a way to make a function that is callable from inside unit tests that uses asserts to check conditions?

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

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

发布评论

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

评论(7

难忘№最初的完美 2024-10-21 11:20:05

如果您使用的是 NUnit 2.5.5 或更高版本,则可以使用 TestCase 属性

正常的单元测试将用 [Test] 装饰,但我们可以将其替换如下:

[TestCase("0", 1)]
[TestCase("1", 1)]
[TestCase("2", 1)]
public void UnitTestName(string input, int expected)
{
    // Arrange
    
    // Act
    
    // Assert
}

这种类型的事情将是这样做的方式 - 显然采用不同的参数。

请查看此帮助:http://nunit.org/?p=testCase&r= 2.5

If you are using NUnit 2.5.5 or above, this is possible using the TestCase attribute.

Normal unit tests would be decorated with [Test], but we can replace that as follows:

[TestCase("0", 1)]
[TestCase("1", 1)]
[TestCase("2", 1)]
public void UnitTestName(string input, int expected)
{
    // Arrange
    
    // Act
    
    // Assert
}

That type of thing will be the way to do it - obviously take different params.

Look at this for help: http://nunit.org/?p=testCase&r=2.5

生生漫 2024-10-21 11:20:05

为了回答最后一部分,您当然可以在另一个函数中包含断言。断言通过引发测试运行程序捕获的异常来工作,并将其解释为失败,因此像这样进行测试将可以正常工作:

public void CheckAsserts(string value)
{
    Assert.IsNotNull(value);
}

[TestCase("yes!")]
public void MyTest(string value)
{
    CheckAsserts(value);
}

To answer the final part, you can of course have Asserts inside another function. Asserts work by raising exceptions which the test runner catches, and interprets as a failure, so have a Test like so will work fine:

public void CheckAsserts(string value)
{
    Assert.IsNotNull(value);
}

[TestCase("yes!")]
public void MyTest(string value)
{
    CheckAsserts(value);
}
在你怀里撒娇 2024-10-21 11:20:05

是的,单元测试就像任何其他代码一样。

特别是,请查看 NUnit.TestCaseAttribute

Yes, unit tests are just like any other code.

In particular, check out NUnit.TestCaseAttribute.

2024-10-21 11:20:05

您可以使用 TestCase属性

[TestCase("hostname1parameter")]
[TestCase("hostname2parameter")]
public void Example_TestHostName(string hostname)
{
    ...
}

You can use the TestCase attribute:

[TestCase("hostname1parameter")]
[TestCase("hostname2parameter")]
public void Example_TestHostName(string hostname)
{
    ...
}
凡间太子 2024-10-21 11:20:05

您将需要 TestCase 属性:

[TestCase("string1",...)
public void test_UnitTest(string Parameter)
{
    ...
    Assert.AreEqual(Parameter, result)
}

请注意,这仅适用于字符串和整数等原始数据类型 - 您无法实例化自己的类并将其用作参数。

You'll need the TestCase attribute :

[TestCase("string1",...)
public void test_UnitTest(string Parameter)
{
    ...
    Assert.AreEqual(Parameter, result)
}

Note that this only works with primitive data types like strings and ints - you can't instantiate your own class and use it as a parameter.

愿得七秒忆 2024-10-21 11:20:05

NUnit [TestCase] 属性提供使用一组不同的参数运行单个测试,您不必为每个参数编写单独的测试。假设我们有以下类并想要测试 IsLatitudeValid() 方法:

public class CoordinateValidator
{
    public bool IsLatitudeValid(double latitude)
    {
        return latitude is >= -90 and <= 90;
    }
    
    public bool IsLongitudeValid(double longitude)
    {
        return longitude is >= -180 and <= 180;
    }
}

我们可以使用以下测试方法:

    [TestCase(-90, true)]
    [TestCase(0, true)]
    [TestCase(10, true)]
    [TestCase(90, true)]
    [TestCase(-91, false)]
    [TestCase(91, false)]
    public void TestLatitude(double latitude, bool expected)
    {
        // ARRANGE
        var validator = new CoordinateValidator();

        // ACT
        bool valid = validator.IsLatitudeValid(latitude);

        // ASSERT
        Assert.AreEqual(expected, valid);
    }

这种参数化测试一开始有些令人困惑,但诀窍是提供一个测试方法(以上)具有输入和输出/预期参数。请注意,[TestCase] 属性和方法参数的数据类型(即 double 和 bool)必须匹配,并且我们测试有效值和无效值。

对于更高级的参数化测试,您可以查看 [TestCaseSource][ValueSource ] NUnit 文档中的属性。

如果您的参数遇到组合爆炸,请查看[值][Random][Range] 属性。

NUnit [TestCase] attribute provides running a single test with a different set of parameters and you don't have to write separate tests for each parameter. Let us say we have the following class and want to test the IsLatitudeValid() method:

public class CoordinateValidator
{
    public bool IsLatitudeValid(double latitude)
    {
        return latitude is >= -90 and <= 90;
    }
    
    public bool IsLongitudeValid(double longitude)
    {
        return longitude is >= -180 and <= 180;
    }
}

We can use the following test method:

    [TestCase(-90, true)]
    [TestCase(0, true)]
    [TestCase(10, true)]
    [TestCase(90, true)]
    [TestCase(-91, false)]
    [TestCase(91, false)]
    public void TestLatitude(double latitude, bool expected)
    {
        // ARRANGE
        var validator = new CoordinateValidator();

        // ACT
        bool valid = validator.IsLatitudeValid(latitude);

        // ASSERT
        Assert.AreEqual(expected, valid);
    }

This parameterized tests are somehow confusing at first but the trick is to provide a test method (the above) with both input and output/expected parameters. Note that data types of the [TestCase] attributes and the method parameters (that is, double and bool) must match and we test both valid and invalid values.

For more advanced parameterized tests you can look at the [TestCaseSource] and [ValueSource] attributes in the NUnit docs.

If you face with a combinatorial explosion with your parameters, look at the [Values], [Random] and [Range] attribues.

无妨# 2024-10-21 11:20:05

您还可以从使用 C# 自省中受益。这允许您获取字段的名称,而无需在代码中指定它们。然后您可以通过名称调用它们。

System.Attribute[] attrs = System.Attribute.GetCustomAttributes(t);

这允许您编写某些类型的测试,这些测试将应用于您尚未编写的类。

You may also benefit from using C# introspection. This allows you to get the names of fields without specifying them in code. You can then invoke them by name.

System.Attribute[] attrs = System.Attribute.GetCustomAttributes(t);

This allows you to write certain sorts of tests that will apply to classes that you haven't even written yet.

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