2011-05-30 62 views
1

我开始使用“(NUnit)”学习Unit testing。我知道这种类型的测试用于测试“类”,“功能”和“这些功能之间的相互作用”。Nunit和web应用程序

在我的情况下,我开发“asp.net web应用程序”。

  • 如何使用这个测试来测试我的 页面(因为它被认为是一类 和使用的方法),并在其顺序?我有三个层次:

    1. 接口层(每页的.cs)。

    2. 数据访问层(每个实体的类)(DAL)。

    3. 数据库层(它包含与数据库的连接,打开连接,关闭连接等)。

    4. 业务层(有时进行计算或一些单独的逻辑)。

  • 如何测试连接数据库的方法?

  • 如何确保我的测试不浪费时间?

回答

2

有单元和集成测试。单元测试正在测试单个组件/类/方法/函数以及它们之间的交互,但只有一个实际对象(被测系统SUT)和测试双击。测试双打可以分为残根和嘲讽。存根提供准备好的测试数据给SUT。这样你就可以将SUT与环境隔离开来。因此,您不必访问数据库,Web或wcf服务等,每次都有相同的输入数据。 Mock用于验证SUT是否按预期工作。 SUT调用模拟对象的方法,甚至不知道它不是真正的对象。然后你通过声明模拟对象来验证SUT的工作原理。你可以手工编写存根和嘲讽,或使用许多嘲讽框架之一。其中之一是http://code.google.com/p/moq/

如果你想测试与集成测试的数据库交互,并且通常比较困难。对于集成测试,您必须以众所周知的状态设置外部资源。

让我们把你的图层:

  1. 您将无法进行单元测试。 Page是紧密耦合到ASP.NET运行时。你应该尽量不要在代码背后有太多的代码。只需从后面的代码中调用一些对象并测试这些对象即可。你可以看看MVC设计模式。如果您必须测试您的页面您应该查看http://watin.org/。它自动化您的互联网浏览器,点击页面上的按钮并验证该页面显示预期的结果。

  2. 这是集成测试。您将数据放入数据库,然后将其读回并比较结果。在测试之后或测试之前您必须将测试数据库带到众所周知的状态,以便测试是可重复的。我的建议是在测试运行之前设置数据库,而不是在测试运行之后。这样在测试失败后,您将能够检查数据库中的内容。

  3. 我真的不知道这与点号不同。 2.

  4. 而这是单元测试。在测试中创建对象,调用它的方法并验证结果。

如何测试,使数据库的连接在2点 被addresed如何不浪费时间的方法?这将带有经验。我没有一般的建议,除此之外,不要测试没有任何逻辑的属性。

有关单元测试伟大的信息看这里:

http://artofunittesting.com/

http://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530

http://www.amazon.com/Growing-Object-Oriented-Software-Guided-Tests/dp/0321503627/ref=sr_1_2?ie=UTF8&s=books&qid=1306787051&sr=1-2

http://www.amazon.com/xUnit-Test-Patterns-Refactoring-Code/dp/0131495054/ref=sr_1_1?ie=UTF8&s=books&qid=1306787051&sr=1-1

编辑:

SUT,CUT - 正在测试的系统或类别。这就是你测试的。 测试双打 - 来自特技双打。他们在电影中做危险的场面,以至于真正的演员不需要。同样在这里。测试双打替换测试中的真实对象,以便您可以在测试环境中隔离SUT/CUT。

让我们看一下这个类


public class NotTestableParty 
{ 
    public bool ShouldStartPreparing() 
    { 
     if (DateTime.Now.Date == new DateTime(2011, 12, 31)) 
     { 
      Console.WriteLine("Prepare for party!"); 
      return true; 
     } 
     Console.WriteLine("Party is not today"); 
     return false; 
    } 
} 

你将如何测试这个类做的事情应该在除夕?你要做的是在新年前夕:)

现在看看修改党的阶级 短的例子:

public class Party 
    { 
     private IClock clock; 

     public Party(IClock clock) 
     { 
      this.clock = clock; 
     } 

     public bool ShouldStartPreparing() 
     { 
      if (clock.IsNewYearsEve()) 
      { 
       Console.WriteLine("Prepare for party!"); 
       return true; 
      } 
      Console.WriteLine("Party is not today"); 
      return false; 
     } 
    } 

    public interface IClock 
    { 
     bool IsNewYearsEve(); 
    } 

    public class AlwaysNewYearsEveClock : IClock 
    { 
     public bool IsNewYearsEve() 
     { 
      return true; 
     } 
    } 

现在测试您可以将假时钟传递到党的阶级

 var party = new Party(new AlwaysNewYearsEveClock()); 
     Assert.That(party.ShouldStartPreparing(), Is.True); 

现在你知道你的派对班是否在除夕。 AlwaysNewYearsEveClock是一个存根。

现在看一下这个类:

public class UntestableCalculator 
    { 
     private Logger log = new Logger(); 

     public decimal Divide(decimal x, decimal y) 
     { 
      if (y == 0m) 
      { 
       log.Log("Don't divide by 0"); 
      } 

      return x/y; 
     } 
    } 

    public class Logger 
    { 
     public void Log(string message) 
     { 
      // .. do some logging 
     } 
    }

您将如何测试你的类记录的消息。根据你在哪里登录它你必须检查文件或数据库或其他地方。这不是单元测试,而是集成测试。为了单元测试你这样做。

public class TestableCalculator 
    { 
     private ILogger log; 
     public TestableCalculator(ILogger logger) 
     { 
      log = logger; 
     } 
     public decimal Divide(decimal x, decimal y) 
     { 
      if (y == 0m) 
      { 
       log.Log("Don't divide by 0"); 
      } 
      return x/y; 
     } 
    } 

    public interface ILogger 
    { 
     void Log(string message); 
    } 
    public class FakeLogger : ILogger 
    { 
     public string LastLoggedMessage; 
     public void Log(string message) 
     { 
      LastLoggedMessage = message; 
     } 
    }

而且在测试您可以

var logger = new FakeLogger(); 
     var calculator = new TestableCalculator(logger); 
     try 
     { 
      calculator.Divide(10, 0); 
     } 
     catch (DivideByZeroException ex) 
     { 
      Assert.That(logger.LastLoggedMessage, Is.EqualTo("Don't divide by 0")); 
     }

这里你断定假冒记录。假记录器是模拟对象。

+0

非常感谢Peri,一些概念不清楚,你能解释一下'Test doubles','stubs','mocks','SUT'是什么意思..“我真的不知道它有什么不同从第二点开始。“数据库层直接使用数据库,数据访问层由每个实体的类(映射)组成,并使用数据库层访问数据并执行CRUD操作。 – 2011-05-30 21:30:01

+1

我编辑了我的asnwer。 – 2011-05-31 19:37:07

相关问题