Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我可以设置一个单元测试运行多次并返回成功百分比吗?_C#_Visual Studio_Unit Testing - Fatal编程技术网

C# 我可以设置一个单元测试运行多次并返回成功百分比吗?

C# 我可以设置一个单元测试运行多次并返回成功百分比吗?,c#,visual-studio,unit-testing,C#,Visual Studio,Unit Testing,我是单元测试新手,一直在浏览web,试图找出如何进一步自动化单元测试。我正在建立一个注册方案,我想做的是用各种硬盘序列号、应用程序号等对其进行测试。我想生成一个注册密钥,然后检查它以确保它正确解码。我希望通过各种输入自动运行测试(使用集成的VisualStudio测试环境),并在数千次运行后,找出成功和失败的测试百分比。这可能吗?以下是我的测试方法: [TestMethod] public void GeneratingValidKeyTest() { int n

我是单元测试新手,一直在浏览web,试图找出如何进一步自动化单元测试。我正在建立一个注册方案,我想做的是用各种硬盘序列号、应用程序号等对其进行测试。我想生成一个注册密钥,然后检查它以确保它正确解码。我希望通过各种输入自动运行测试(使用集成的VisualStudio测试环境),并在数千次运行后,找出成功和失败的测试百分比。这可能吗?以下是我的测试方法:

[TestMethod]
    public void GeneratingValidKeyTest()
    {
        int numReadDevices;
        string appNum = "123";
        string hddSerial = "1234567890";
        string numDevices = "12";
        string regNumber = Registration.GenerateKey(appNum, numDevices, hddSerial);
        Assert.IsTrue(Registration.CheckKey(regNumber, appNum, out numReadDevices, hddSerial), "Generated key does not pass check.");
        Assert.AreEqual(int.Parse(numDevices), numReadDevices,"Number of registered devices does not match requested number");
    }

如果您使用NUnit,您可以设置一系列ValueSources以提供给您的方法

如果appNum、hddSerial和numDevices有单独的值源,那么将获得appNum*hddSerial*numDevices的测试数

不过,你不应该试图找出考试通过的百分比。单元测试的目的是确保所有测试场景都通过

以Max为例,使其成为ValueSources:

[Test]
public void DivideTest([ValueSource("AppNums")]string appNum, [ValueSource("Serials")]string hddSerial, [ValueSource("NumDevices")]string numDevices)
{
    string regNumber = Registration.GenerateKey(appNum, numDevices, hddSerial);
    Assert.IsTrue(Registration.CheckKey(regNumber, appNum, out numReadDevices, hddSerial), "Generated key does not pass check.");
    Assert.AreEqual(int.Parse(numDevices), numReadDevices,"Number of registered devices does not match requested number");
}

static object[] AppNums =
{
    "1", "2", "3", "4", "5", "6", "7"
};

static object[] Serials =
{
    "EXAMPLE", "ANOTHER", "AND AGAIN"
};

static object[] NumDevices =
{
    "1", "2", "3", "4", "5", "6", "7"
};
在里面看起来像

[Test, TestCaseSource("DivideCases")]
public void DivideTest(string appNum, string hddSerial, string hddSerial)
{
    string regNumber = Registration.GenerateKey(appNum, numDevices, hddSerial);
    Assert.IsTrue(Registration.CheckKey(regNumber, appNum, out numReadDevices, hddSerial),              "Generated key does not pass check.");
    Assert.AreEqual(int.Parse(numDevices), numReadDevices,"Number of registered devices does not match requested number");
}

static object[] DivideCases =
{
    new object[] { "123", "3", "4" },
    new object[] { "12223", "35", "54" },
    new object[] { "12123123", "23", "14" }
};

就我个人而言,我发现“在方法中抛出大量随机数据并确保其全部工作”的方法没有什么价值

如果你给这个方法提供500个不同的序列号,它们都能工作,那就好了。但是他们在您的代码中测试了哪些特定场景?如果您不能回答这个问题,那么您可能是在重复测试场景,更重要的是,缺少测试场景

不要把测试用例扔到墙上,看看到底是什么粘住了你,而是分析你的代码,确定关键的成功和失败标准,并手工测试这些标准。这有一个附带的好处,就是让您的测试更加冗长,并让您的团队成员通过读取测试名称更好地了解代码应该做什么。与生成ValidKeyTest不同的是,您的测试应该命名为描述它们正在测试的内容

例如,假设您正在构建一个计算器。使用这种方法,您可能会抛出大量的加法用例——1+1、1+3、5+30等等,但很可能会错过1+
Int32.MaxValue
。或者你不会尝试添加负数。或者测试输入不是有效数字时会发生什么。等等


好的测试迫使您在编写它们时仔细考虑所有这些类型的场景。

您可以使用Microsoft的单元测试框架,并使其从数据源读取测试数据。使用MSTest的优点是它将在VisualStudio的快速版上运行

但是你不会得到一个百分比的错误,我同意@DanielMann的观点,相反,你必须确保你的测试覆盖了所有的可能性,并且它们都通过了

因此,考虑到您已经做到了这一点,现在您有了一个要测试的案例列表,您可以使用下面的代码。它使用了:

在测试资源管理器窗口中,您将获得如下输出(失败的测试将首先显示):

测试名称:GeneratingValidKeyTest
测试全名:MySolution.UnitTest.RegistrationTests.GeneratingValidKeyTest
测试源:C:\MySolution\MySolution.UnitTest\RegistrationTests.cs:第15行
测试结果:失败
测试持续时间:0:00:00017832
结果1名称:GeneratingValidKeyTest(数据行1)
结果1结果:失败
结果1持续时间:0:00:000082728
结果1堆栈跟踪:在C:\MySolution\MySolution.UnitTest\RegistrationTests.cs:第27行中的MySolution.UnitTest.RegistrationTests.GeneratingValidKeyTest()处
结果1消息:Assert.AreEqual失败。预期:。实际值:。已注册设备的数量与请求的数量不匹配
结果3名称:GeneratingValidKeyTest(数据行0)
结果3结果:通过
结果3持续时间:0:00:000089332
结果跟踪:
结果3消息:

NUnit
提供了方便的方法,看看这篇文章,这样的测试可能有价值,但它不是单元测试。对于自动单元测试,您需要通过或失败的代码,并且给定相同的输入,总是返回相同的结果。您可能想签出-但这更像是“我的代码是否满足许多输入的这些属性?”+1以确保所有场景都通过。如果单元测试失败,单元的逻辑就不正确。当然,除非您正在测试代码生成的随机值的特定界限。例如,我有一个返回x长度数字的方法。它还可以采用允许或不允许第一个数字为零的布尔值。我想确保它一直有效。由于该方法本身会生成数字,因此对该方法进行数百次测试可能是确保其按预期工作的最佳方式(不允许在不应该的情况下使用前导零)。
[TestClass]
public class RegistrationTests
{
    public TestContext TestContext { get; set; }

    [TestMethod]
    [DataSource(
        "System.Data.OleDb", 
        @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=""C:\MySolution\Serial numbers.mdb""",
        "Serials",
        DataAccessMethod.Sequential
    )]
    public void GeneratingValidKeyTest()
    {
        // Arrange
        int numReadDevices;
        var appNum = TestContext.DataRow["appNum"].ToString();
        var hddSerial = TestContext.DataRow["hddSerial"].ToString();
        var numDevices = TestContext.DataRow["numDevices"].ToString();

        // Act
        var regNumber = Registration.GenerateKey(appNum, numDevices, hddSerial);

        // Assert
        Assert.IsTrue(
            Registration.CheckKey(regNumber, appNum, out numReadDevices, hddSerial), 
            "Generated key does not pass check."
        );
        Assert.AreEqual(
            int.Parse(numDevices), numReadDevices, 
            "Number of registered devices does not match requested number"
        );
    }
}