2016-11-18 85 views
2

C#新手在这里。Max()函数的测试用例设计

据我所知,测试用例应该是:

  • 简单透明
  • 有最小的重复
  • 保证100%的代码覆盖率

我也明白了边界值分析的基础知识和等价划分,但下面的函数,基本测试用例是什么?

static public int Max(int a, int b, int c) 
    { // Lines of code: 8, Maintainability Index: 70, Cyclomatic Complexity: 4, Class Coupling: 0 
     if (a > b) 
      if (a > c) 
       return a; 
      else 
       return c; 
     else 
      if (b > c) 
       return b; 
      else 
       return c; 
    } 

这是我迄今为止..

using Microsoft.VisualStudio.TestTools.UnitTesting; 
    using ConsoleApplication10; 
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using System.Threading.Tasks; 

    namespace ConsoleApplication10.Tests 
    { 
     [TestClass()] 
     public class ProgramTests 
     { 
      [TestMethod()] 
      public void MaxTestNulls(int a, int b, int c) 
      { 
       Assert.IsNotNull(a, "The first parameter must be present."); 
       Assert.IsNotNull(b, "The second parameter must be present."); 
       Assert.IsNotNull(c, "The third parameter must be present."); 
      } 
      [TestMethod()] 
      public void MaxTestTypes(int a, int b, int c) 
      { 
       Assert.IsInstanceOfType(a, typeof(int)); 
       Assert.IsInstanceOfType(b, typeof(int)); 
       Assert.IsInstanceOfType(c, typeof(int)); 
      } 
      [TestMethod()] 
      public void MaxTestBasics(int a, int b, int c) 
      { 
       if (a > int.MaxValue || b > int.MaxValue || c > int.MaxValue) 
       { 
        Assert.Fail(); 
       } 

       if (a < int.MinValue || b < int.MinValue || c < int.MinValue) 
       { 
        Assert.Fail(); 
       } 
      } 
     } 
    } 

我完全关闭基地在这里?我的老师不会鼓起并给我任何提示..我可以使用哪些其他测试用例会有用?

回答

2

一个可行的测试策略称为分支覆盖。在那里,你尝试编写覆盖被测系统中每个执行分支的单元测试。

在你的情况,不同的执行分支的return说明:return areturn creturn b并再次return c在底部。

您可以覆盖这些用例(分别为值A,B和C)整函数:

4, 2, 3 
4, 2, 5 
4, 2, 4 <-- boundary condition 
2, 4, 3 
2, 2, 3 <-- boundary condition 
2, 4, 5 
2, 4, 4 <-- boundary condition 

正好有被确保所有的树枝上挂满四个测试案例。还有三种情况是为了覆盖仍然在特定分支中结束的边界条件。

下面是xUnit中这些测试用例的实现。我选择的xUnit,因为它支持多个测试用例通过使用InlineData属性的一个测试方法:

[Theory] 
[InlineData(4, 2, 3, 4)] 
[InlineData(4, 2, 5, 5)] 
[InlineData(4, 2, 4, 4)] 
[InlineData(2, 4, 3, 4)] 
[InlineData(2, 2, 3, 3)] 
[InlineData(2, 4, 5, 5)] 
[InlineData(2, 4, 4, 4)] 
public void Max_ReturnsExpectedValue(int a, int b, int c, int expectedMax) 
{ 
    int actualMax = Program.Max(a, b, c); 
    Assert.Equal(expectedMax, actualMax); 
} 

只是为了记录在案,所有七个测试用例是通过您实现以上。

在相关说明中,这种测试称为白盒测试。您可以访问具体的实现,然后您正在为该实现编写测试。如果你想实现黑盒测试,那么你的测试用例只会受到你对函数的期望。例如,这些可能是合法的测试用例黑箱测试:

1, 1, 1 -> 1 
1, 1, 2 -> 2 
1, 2, 1 -> 2 
1, 2, 2 -> 2 
1, 2, 3 -> 3 
1, 3, 1 -> 3 
1, 3, 2 -> 3 
1, 3, 3 -> 3 
2, 1, 1 -> 2 
... 

这里的问题是,我们不知道它的边界条件是相关的,因此,我们必须添加相当多的人来覆盖所有选项。如果你继续朝相同的方向走,测试的总数将是3^3 = 27。

+0

这非常有帮助,谢谢。还有一个问题,我将如何在单元测试中实现它?每当我尝试在我的TestMethods()中调用Max()时,它都会给出一个错误。 – dotKn0ck

+0

我想我对实现感到困惑。 – dotKn0ck

+0

@ dotKn0ck请参阅上面的测试方法实现。 –

0

第一个明显的增加就像itsme86说你应该测试3个输入中的任何一个是否相等。其次,您应该测试依赖性,这意味着输入值可能是每次评估都会改变的函数的输出,所以请确保在测试类中获取输入的单个实例(即评估一次),并继续你的测试这个本地实例,不重新评估输入

我不知道很多关于C#,但让我告诉你一个通用的例子

public static TestFunction (int A, int B, int C) 
{ 
// Your test methods 
} 

如果这被称为像这

boolean Result = TestFunction((int)Math.sin(System.currentTimeMillis()),(int)Math.sin(System.currentTimeMillis()),(int)Math.sin(System.currentTimeMillis())); 

在你的函数可以访问A,B或每时间C它们的价值将被重新评估,并可能可能否定以前的测试结果

我要补充额外的测试样X = A,Y = A,XY = 0以确保A在重新评估时不会发生变化,可能会增加时间延迟,因为它的时间依赖性和程序执行速度太快以至于无法反映(您需要纳秒级分辨率来反映不间断地执行小而简单的代码)