单元测试概括

一、单元测试的目的

验证代码与设计相符合(Code Inspection与Unit Test相结合)

跟踪需求和设计的实现

发现设计和需求中存在的错误

发现编码过程中引入的错误

对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如C语言中单元指一个函数,Java里单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。总的来说,单元就是人为规定的最小的被测功能模块。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。

二、单元测试的环境

构造最小运行调度系统,即驱动模块(Driver),用以模拟被测模块的上一级模块 模拟实现单元接口桩(Stub),即被测单元需调用的其他单元函数的接口 模拟生成数据或状态,为单元测试准备动态环境

三、单元测试的方法

孤立测试策略 单元内的全局输入/输出变量测试(Driver) 单元内调用的函数(Stub)的接口测试 覆盖测试(语句覆盖/分支覆盖/复合谓词覆盖/路径覆盖)。 Note:应该依据规格说明书、流程图并结合源程序规划测试方法和测试用例。

四、单元测试的测试用例设计

为系统运行与正向测试设计测试用例:等价类划分、决策表 为逆向测试设计测试用例:边界值法 为代码覆盖设计测试用例:代码覆盖:语句覆盖、分支覆盖、复合谓词覆盖、路径覆盖、数据定义使用测试

五、单元测试应坚持的原则

单元测试前应该执行静态检查、代码走读 对全新的代码或修改过的代码进行单元测试 被测试的对象为实现一组相关功能的代码(一个或一组函数) 单元测试根据单元测试的计划和方案进行,排除测试的随意性 项目管理者保证测试用例经过审核(集思广益) 当测试用例的测试结果与预期结果不一致时,单元测试的执行人员需如实记录实际测试结果 当测试达到计划的结束标准时,单元测试结束 对被侧单元需达到一定的代码覆盖率要求 当程序修改后,测试人员要执行回归测试,以保证修改后没有引入新的错误。

我们编写代码时,一定会反复调试保证它能够编译通过。如果是编译没有通过的代码,没有任何人会愿意交付给自己的老板。但代码通过编译,只是说明了它的语法正确;我们却无法保证它的语义也一定正确,没有任何人可以轻易承诺这段代码的行为一定是正确的。

幸运的是,单元测试会为我们的承诺做保证。编写单元测试就是用来验证这段代码的行为是否与我们期望的一致。有了单元测试,我们可以自信的交付自己的代码,而没有任何的后顾之忧。

什么时候测试?单元测试越早越好,早到什么程度?XP开发理论讲究TDD,即测试驱动开发,先编写测试代码,再进行开发。在实际的工作中,可以不必过分强调先什么后什么,重要的是高效和感觉舒适。从老纳的经验来看,先编写产品函数的框架,然后编写测试函数,针对产品函数的功能编写测试用例,然后编写产品函数的代码,每写一个功能点都运行测试,随时补充测试用例。所谓先编写产品函数的框架,是指先编写函数空的实现,有返回值的随便返回一个值,编译通过后再编写测试代码,这时,函数名、参数表、返回类型都应该确定下来了,所编写的测试代码以后需修改的可能性比较小。

由谁测试?单元测试与其他测试不同,单元测试可看作是编码工作的一部分,应该由程序员完成,也就是说,经过了单元测试的代码才是已完成的代码,提交产品代码时也要同时提交测试代码。测试部门可以作一定程度的审核。

关于桩代码,老纳认为,单元测试应避免编写桩代码。桩代码就是用来代替某些代码的代码,例如,产品函数或测试函数调用了一个未编写的函数,可以编写桩函数来代替该被调用的函数,桩代码也用于实现测试隔离。采用由底向上的方式进行开发,底层的代码先开发并先测试,可以避免编写桩代码,这样做的好处有:减少了工作量;测试上层函数时,也是对下层函数的间接测试;当下层函数修改时,通过回归测试可以确认修改是否导致上层函数产生错误。

在一种传统的结构化编程语言中,比如C,要进行测试的单元一般是函数或子过程。在象C++这样的面向对象的语言中, 要进行测试的基本单元是类。对Ada语言来说,开发人员可以选择是在独立的过程和函数,还是在Ada包的级别上进行单元测试。单元测试的原则同样被扩展到第四代语言(4GL)的开发中,在这里基本单元被典型地划分为一个菜单或显示界面。

六、单元测试工具

代码静态分析工具:Logiscope、McCabe QA、CodeTest 代码检查工具:PC-LINT、CodeChk、Logiscope 测试脚本工具:TCL、Python、Perl 覆盖率检测工具: Visual studio ,Logiscope、Purecoverage 内存检测工具:Purify、CodeTest 单元测试工具:Visual studio 2005-2013,xUnit

七、实验内容

创建解决方案和单元测试项目

在“文件”菜单上选择“新建”,然后选择“新建项目”。

在“新建项目”对话框中,展开“已安装”、“Visual C#”,选择“Windows Store”。  然后从项目模板列表中选择“空白应用程序”。

将项目命名为 Maths,并确保选中“创建解决方案的目录”。

在解决方案资源管理器中,选择解决方案名称,从快捷菜单中选择“添加”,然后选择“新建项目”。

在“新建项目”对话框中,展开“已安装”、“Visual C#”,然后选择“Windows 应用商店”。  然后从项目模板列表中选择“单元测试库(Windows Store 应用程序)”。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;

namespace UnitTestLibrary1

{

[TestClass]

public class UnitTest1

{

[TestMethod]

public void TestMethod1()

{

Assert.AreEqual(0, 0);

}

}

}

以下是测试源码

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

namespace App1

{

public class Class1

{

public Class1()

{

}

public double SquareRoot(double x)

{

double estimate = x;

double diff = x;

if (x < 0.0)

{

throw new ArgumentOutOfRangeException();

}

while (diff > estimate / 1000)

{

double previousEstimate = estimate;

estimate = estimate - (estimate * estimate - x) / (2 * estimate);

diff = Math.Abs(previousEstimate - estimate);

}

return estimate;

}

}

}

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;

using App1;

namespace UnitTestLibrary1

{

[TestClass]

public class UnitTest1

{

[TestMethod]

public void TestMethod1()

{

Assert.AreEqual(0, 0);

}

[TestMethod]

public void BasicTest()

{

App1.Class1 rooter = new Class1();

double expected = 0.0;

double actual = rooter.SquareRoot(expected * expected);

double tolerance = .001;

Assert.AreEqual(expected, actual, tolerance);

}

[TestMethod]

public void RangeTest()

{

Class1 rooter = new Class1();

for (double v = 1e-6; v < 1e6; v = v * 3.2)

{

double expected = v;

double actual = rooter.SquareRoot(v * v);

double tolerance = expected;

Assert.AreEqual(expected, actual, tolerance);

}

}

[TestMethod]

public void NegativeRangeTest()

{

string message;

Class1 rooter = new Class1();

for (double v = -0.1; v > -3.0; v = v - 0.5)

{

try

{

// Should raise an exception:

double actual = rooter.SquareRoot(v);

message = String.Format("No exception for input {0}", v);

Assert.Fail(message);

}

catch (ArgumentOutOfRangeException ex)

{

continue; // Correct exception.

}

catch (Exception e)

{

message = String.Format("Incorrect exception for {0}", v);

Assert.Fail(message);

}

}

}

}

}

以下是app源码

using System;

using System.Collections.Generic;

using System.IO;

using System.Linq;

using System.Runtime.InteropServices.WindowsRuntime;

using Windows.ApplicationModel;

using Windows.ApplicationModel.Activation;

using Windows.Foundation;

using Windows.Foundation.Collections;

using Windows.UI.Xaml;

using Windows.UI.Xaml.Controls;

using Windows.UI.Xaml.Controls.Primitives;

using Windows.UI.Xaml.Data;

using Windows.UI.Xaml.Input;

using Windows.UI.Xaml.Media;

using Windows.UI.Xaml.Navigation;

// “空白应用程序”模板在 http://go.microsoft.com/fwlink/?LinkId=234227 上有介绍

namespace App1

{

/// <summary>

/// 提供特定于应用程序的行为,以补充默认的应用程序类。

/// </summary>

sealed partial class App : Application

{

/// <summary>

/// 初始化单一实例应用程序对象。    这是执行的创作代码的第一行,

/// 逻辑上等同于 main() 或 WinMain()。

/// </summary>

public App()

{

this.InitializeComponent();

this.Suspending += OnSuspending;

}

/// <summary>

/// 在应用程序由最终用户正常启动时进行调用。

/// 以打开特定文件等情况下使用其他入口点。

/// </summary>

/// <param name="e">有关启动请求和过程的详细信息。</param>

protected override void OnLaunched(LaunchActivatedEventArgs e)

{

#if DEBUG

if (System.Diagnostics.Debugger.IsAttached)

{

this.DebugSettings.EnableFrameRateCounter = true;

}

#endif

Frame rootFrame = Window.Current.Content as Frame;

// 不要在窗口已包含内容时重复应用程序初始化,

// 只需确保窗口处于活动状态

if (rootFrame == null)

{

// 创建要充当导航上下文的框架,并导航到第一页

rootFrame = new Frame();

//设置默认语言

rootFrame.Language = Windows.Globalization.ApplicationLanguages.Languages[0];

rootFrame.NavigationFailed += OnNavigationFailed;

if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)

{

//TODO:  从之前挂起的应用程序加载状态

}

// 将框架放在当前窗口中

Window.Current.Content = rootFrame;

}

if (rootFrame.Content == null)

{

// 当未还原导航堆栈时,导航到第一页,

// 并通过将所需信息作为导航参数传入来配置

// 参数

rootFrame.Navigate(typeof(MainPage), e.Arguments);

}

// 确保当前窗口处于活动状态

Window.Current.Activate();

}

/// <summary>

///导航到特定页失败时调用

/// </summary>

///<param name="sender">导航失败的框架</param>

///<param name="e">有关导航失败的详细信息</param>

void OnNavigationFailed(object sender, NavigationFailedEventArgs e)

{

throw new Exception("Failed to load Page " + e.SourcePageType.FullName);

}

/// <summary>

/// 在将要挂起应用程序执行时调用。    在不知道应用程序

/// 将被终止还是恢复的情况下保存应用程序状态,

/// 并让内存内容保持不变。

/// </summary>

/// <param name="sender">挂起的请求的源。</param>

/// <param name="e">有关挂起的请求的详细信息。</param>

private void OnSuspending(object sender, SuspendingEventArgs e)

{

var deferral = e.SuspendingOperation.GetDeferral();

//TODO:  保存应用程序状态并停止任何后台活动

deferral.Complete();

}

}

}

时间: 2024-10-20 06:49:29

单元测试概括的相关文章

ng2响应式表单-翻译与概括官网REACTIVE FORMS页面

本文将半翻译半总结的讲讲ng2官网的另一个未翻译高级教程页面. 原文地址. 文章目的是使用ng2提供的响应式表单技术快速搭出功能完善丰富的界面表单组件. 响应式表单是一项响应式风格的ng2技术,本文将解释响应式表单并用来创建一个英雄详情编辑器. 包含内容: 响应式表单介绍 开始搭建 创建数据模型 创建响应式的表单组件 创建组建的模板文件 引入ReactiveFormsModule 显示HeroDetailComponent 添加一个FormGroup 看看表单模型 介绍FormBuilder 验

单元测试和集成测试业务应用程序

20160509单元测试和集成测试业务应用程序--翻译 单元测试,集成测试,测试驱动开发等介绍 1.单元测试是写代码来测试代码的一个小单位的方式.  在一个单元测试中,一次只能测试一个类. 例如,如果您正在测试一个使用类File ,而另一个测试类DummyFile是用来消除对物理文件系统的需要. 单元测试的测试类逻辑应该被测试. 为了使类从真正落实给虚/存根实现切换,接口代替真正的类的使用. 所以,你的类应使用IFile或IDatabase而不是直接使用File和Database. 2.集成测试

VS2013安装和单元测试

1. VC2013安装过程及使用感受 刚上大一的时候老师推荐我们用VC++6.0.当时也就听了老师的话用VC++6.0编程了一段时间.后来上了大二买了电脑VC++6.0支持不了WIN8.1所以我就开始接触VC2013了.VS2013这个软件我已经都用了一年了.所以,老师要求的要把安装过程图文并茂的表现出来....额~ 我不可能卸了再重下吧..毕竟要花费我一上午的时间还有我有些代码都在那所以我不敢动~~~希望老师谅解.我把我用VC2013的感受说一下.比如打一个scanf.如果是VC++6.0的话

java 字符串拼接的单元测试

整体内容介绍 本文分为几个部分: * String.StringBuffer.StringBuilder的对比 * 字符串拼接方式的对比 使用到的内容: * Junit4单元测试 * slf4j的日志框架 String.StringBuffer.StringBuilder的对比 对于这三者使用的场景做如下概括(参考:<编写搞质量代码:改善java程序的151个建议>): String:在字符串不经常变化的场景中可以使用String类,如:常量的声明.少量的变量运算等. StringBuffer

初识单元测试框架

认识单元测试 对于单元测试框架,它主要完成以下三件事: 1.提供用例组织与执行 为什么要考虑到测试用例的组织问题呢?这是因为当我们的测试用例多达成百上千条时,这就产生了一些很严重的问题--测试用例的维护性问题以及扩展管理性问题等,而单元测试框架就是用来解决用例的规范与组织问题. 2.提供丰富的比较方法 说到比较方法,先简单描述一下什么是软件Bug--通俗讲Bug就是实际结果与预期结果之间的差异,而预期结果来源于需求,因此可以概括成与需求不符即Bug.因此无论是功能测试还是单元测试,都需要将实际结

单元测试Junit

###<center> 单元测试Junit </center>###- - -1.**单元测试**:> ==单元测试==是软件之中对于最小的功能模块的的测试,其可以对最基本的软件构成单元来测试.> 需要注意的是:> >**测试用例是用来达到测试想要的预期结果,而不能测试出程序的逻辑错误**. 2.**JUnit**:>1.**Junit是基于断言机制的**.是用于编写可复用测试集的简单框架,是xUnit的一个子集.xUnit是一套基于测试驱动开发的测试

MVC与单元测试实践之健身网站(四)-动作管理

网站后台负责进行动作的管理,包括动作名称.介绍.训练要点.配图等内容,以便前台能够使用这些内容.在上一篇< Fit项目图片上传和云存储的调通>中已经准备好了这里涉及到的主要技术难点,现在就开始完成该模块了. 一 列表介绍 健身管理模块包括肌群.肌肉的显示以及动作的管理.这儿也算是开始涉及"业务内容"了,还好我之前有储备了一些关于健身的资料,现在是时候派上另一种用场了. a) 肌群和肌肉因为内容相对固定,所以为了减少业务逻辑以及单元测试的代码量,当然最主要是为了偷懒,就只提供

MVC与单元测试实践之健身网站(二)-管理员模块

开始动手做这个项目时,发现无法做到完全的先设计.再编码,于是决定分模块进行,从管理员模块开始设计.编码,而且接口就已经改了好几次了. 管理员模块涉及的功能有登录和后台对管理员的维护,其中也涉及前端的开发.UI模板使用Inspinia,感觉这套模板功能丰富.界面美观,而且基于HTML5和BootStrap,对这两方面的知识也可以多些了解. 在上一篇<如何在单元测试时隔离ORM>中,解决了对Service层进行测试怎样构建伪对象的问题,随后管理员模块的Service层和单元测试在齐头并进中完成了:

单元测试(一)-NUnit基础

单元测试作为提高代码和软件质量的有效途径,其重要性和益处自不必多说,虽然我没有实践过TDD之类,但坚信单元测试的积极作用.作为一种开发方法,单元测试早在上世纪70年代就已经在Smalltalk语言被运用了,这么多年来,单元测试一次又一次证明了自身的价值,在各种开发方式此起彼伏的浪潮中,经受住了时间的考验. 现在,俺也开始学习了,并在以后好好实践.这个系列的学习素材为Roy Osherove所著The Art of Unit Testing with examples in C#, 2nd Edi