单元测试意识与软件质量
作者:网络转载 发布时间:[ 2011/9/14 13:45:18 ] 推荐标签:
3. 抛出异常或捕捉异常,任何函数如果存在内部断点或跳出点,一定要做单元测试模拟程序内部跳转和停止的情况;
4. 越底层函数越需要单元测试,指的是系统越底层的函数、越核心的函数,越需要单元测试,反之,越高层的,比如UI层,越不要单元测试。
记住,不要去测试类中的每个方法。挑选以上几种函数进行测试,而且要根据需求来测试这个类对外所能提供的功能, 这些功能可能是其中的几个重要方法, 可能需要类中的几个方法协作,可以对这几个方法进行测试,无需测试类中的所有方法。将来做自动化回归测试的时候,这些重要函数的单元测试都有覆盖跑到,能大大增强软件的质量保证。(额外好处:你可以通过你的测试代码告诉别人如何使用这个类)
到底是先写测试函数,后写函数,还是反之,这个问题TDD主张先写测试函数确定接口,然后写具体函数实现。个人觉得看项目需要。
有关回归测试:
写单元测试的一大好处是可以自动进行回归测试,也是说,将来代码修改了,可以自动跑一些所有测试案例,知道这次修改有没有伤及其他函数。回归测试的功能非常重要,对软件后期的维护和升级节省相当的成本。甚至有人说,如果没有回归测试,没必要写单元测试。
当然,单元测试另一个问题是覆盖率,不完全的测试覆盖率意味着缺陷的存在,但不能因为覆盖率不能覆盖不做单元测试,所谓“高效的单元测试”是取得项目测试时间、项目的输出和质量、Schedule和成本的三者的平衡。
分层架构下的单元测试:
Web层,界面层,或称为表现层(Presentation):主要测试Controller的数据结构化逻辑。
业务逻辑层(Business Logic):主要测试业务规则,独立的业务规则或者叠加的业务规则;以来外部对象的可以用MOCK来模拟环境测试。当然繁杂的业务流程可以不测试,要视具体情况而定。
数据访问层(Data Access Logic): 需要测试。
面向方面(AOP)和其他基类库:需要重点测试。
单元测试的自动化工具:
CppUnit,这是C++单元测试工具的鼻祖,免费的开源的单元测试框架.
C++Test,这是Parasoft公司的产品。[C++Test是一个功能强大的自动化C/C++单元级测试工具,可以自动测试任何C/C++函数、类,自动生成测试用例、测试驱动函数或桩函数,在自动化的环境下极其容易快速的将单元级的测试覆盖率达到]。Visual Unit,简称VU,这是国产的单元测试工具,据说申请了多项专利,拥有一批创新的技术,不过老纳只关心是不是有用和好用。
NUnit,这是一个单元测试框架,专门针对于.NET来写的
JUnit,针对Java的单元测试框架。目前java下的team 开发采用cvs(版本控制) + ant(项目管理) + junit(集成测试) 的模式时,通过对ant的配置,可以很简单地实现测试自动化。
单元测试的例子:
1. NUnit单元测试,测试单个函数的逻辑分支和抛出的异常:
实现类:(ConnectionFactory.cs)主要实现了CreateConnection这个方法。
using System;
using Microsoft.Practices.SmartClient.ConnectionMonitor.Implementations;
namespace Microsoft.Practices.SmartClient.ConnectionMonitor
{
/// <summary>
/// A simple factory that can create <see cref="Connection"/> objects.
/// </summary>
public class ConnectionFactory
{
/// <summary>
/// DesktopConnection
/// </summary>
public const string DesktopConnection = "DesktopConnection";
/// <summary>
/// NicConnection
/// </summary>
public const string NicConnection = "NicConnection";
/// <summary>
/// WirelessConnection
/// </summary>
public const string WirelessConnection = "WirelessConnection";
/// <summary>
/// WiredConnection
/// </summary>
public const string WiredConnection = "WiredConnection";
/// <summary>
/// Creates a <see cref="Connection"/> object.
/// </summary>
/// <param name="connectionType">The type of the connection to create.</param>
/// <param name="price">The price of the <see cref="Connection"/>.</param>
/// <returns>A <see cref="Connection"/> object.</returns>
/// <exception cref="ConnectionMonitorException">Thrown when an invalid type is requested.</exception>
/// <remarks>
/// For the built-in <see cref="Connection"/> types
/// (i.e. DesktopConnection, NicConnection, WirelessConnection, WiredConnection),
/// only the class name is required. For user created types, the fully qualified
/// class name is required.
/// </remarks>
public static Connection CreateConnection(string connectionType, int price)
{
Guard.StringNotNullOrEmpty(connectionType, "connectionType");
if (price < 0)
{
throw new ArgumentOutOfRangeException("price");
}
Connection connection;
switch (connectionType)
{
case DesktopConnection:
connection = new DesktopConnection(DesktopConnection, price);
break;
case NicConnection:
connection = new NicConnection(NicConnection, price);
break;
case WirelessConnection:
connection = new WirelessConnection(WirelessConnection, price);
break;
case WiredConnection:
connection = new WiredConnection(WiredConnection, price);
break;
default:
try
{
Type connectionTypeToCreate = Type.GetType(connectionType, true);
Object createdObject = Activator.CreateInstance(connectionTypeToCreate, connectionTypeToCreate.Name, price);
connection = createdObject as Connection;
}
catch(TypeLoadException ex)
{
throw new ConnectionMonitorException("Unsupported connection type.", ex);
}
if (connection == null)
{
throw new ConnectionMonitorException("Unsupported connection type.");
}
break;
}
return connection;
}
}
}
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11