10.单元测试
随着类的不断增多,如何在编写完一个类后测试它的正确性就变得越来越重要,不要等到写了很多类之后再想到除错,那已经为时已晚,你根本就找不到到底是哪个类有问题。比如说编写完UIImage后,想知道它是否工作正常,一个方法就是新建一个项目,从引擎类继承,再添加一个Scene,将UIImage类放在这个Scene中,运行项目看看是否正常,调试一个类时这种方法挺管用,如果以后还有大量的类呢?每个类都要创建一个项目吗?其实发现测试的过程都是类似的,自然想到需要将测试过程封装成一个类。具体的实现原理可参见《ProfessionalXNA》中的§2.3让我们编写Pong和§3.3XNA 中的单元测试。
先在引擎类StunEngine.cs中添加一个委托:
/// <summary>
/// 用于单元测试的委托。
/// </summary>
public delegate void RenderDelegate();
然后创建一个入口点类:
namespace StunEngine
{
static class Program
{
static void Main(string[] args)
{
![]()
}
}
}
接着还要新建一个类TestGame从引擎继承:
namespace StunEngine
{
class TestGame:StunXnaGE
{
成员变量
![]()
/// <summary>
/// 创建单元测试
/// </summary>
/// <param name="setWindowsTitle">设置窗口标题</param>
/// <param name="setInitCode">设置初始化代码</param>
/// <param name="setUpdateCode">设置更新代码</param>
/// <param name="setDrawCode">设置绘制代码</param>
protected TestGame(string setWindowsTitle,RenderDelegate setInitCode,RenderDelegate setUpdateCode,RenderDelegate setDrawCode)
{
this.Window.Title = setWindowsTitle;
![]()
initCode = setInitCode;
updateCode = setUpdateCode;
drawCode = setDrawCode;
}
![]()
/// <summary>
/// 初始化代码
/// </summary>
protected override void Initialize()
{
base.Initialize();
![]()
//添加默认屏幕
scene = new defaultScene(this);
SceneManager.AddScene(scene);
![]()
// 调用自定义的初始化代码
if (initCode != null)
initCode();
}
![]()
/// <summary>
/// 更新代码
/// </summary>
protected override void Update(GameTime time)
{
base.Update(time);
![]()
// 按ESC键或手柄Back退出测试
if (Input.KeyboardEscapeJustPressed ||
Input.GamePadBackJustPressed)
this.Exit();
![]()
// 调用自定义的更新代码
if (updateCode != null)
updateCode();
}
![]()
/// <summary>
/// 绘制代码
/// </summary>
protected override void Draw(GameTime gameTime)
{
base.Draw(gameTime);
![]()
// 调用自定义的绘制代码
if (drawCode != null)
drawCode();
![]()
}
![]()
开始测试
![]()
单元测试
}
}
在TestGame类中有一个静态的Scene,我命名为defaultScene,所以还需要在项目中添加一个defaultScene类,这个类中添加了一个相机,一个相机控制器和一个默认单向光源。代码如下:
class defaultScene:Scene
{
public FpsCameraController fpsCamCtrl;
/// <summary>
/// 构造函数
/// </summary>
public defaultScene(StunXnaGE engine)
: base(engine, "default")
{
![]()
}
![]()
public override void LoadContent()
{
base.LoadContent();
![]()
//-----------------------------------
// 添加一个指向左后方的默认单向光源,颜色为白色
//-----------------------------------
Light sun = new Light(new Vector3(1.0f, 1.0f, 1.0f),new Vector3(-1f, 0, -1f));
AddLight(sun);
![]()
//-----------------------------------
// 创建相机
//-----------------------------------
Vector3 cameraPosition = new Vector3(0, 0, 20);
CameraSceneNode Camera = new CameraSceneNode(engine, this, cameraPosition, cameraPosition + Vector3.Forward);
Camera.Initialize();
Camera.FOV = MathHelper.PiOver4;
this.Camera = Camera;
![]()
//-----------------------------------
// 创建fps相机控制器
//-----------------------------------
fpsCamCtrl = new FpsCameraController(engine);
fpsCamCtrl.Elevation = 90;
Camera.AttachController(fpsCamCtrl);
}
}
}
编写好上述几个类后,要实现单元测试,首先需要StunEngine项目的属性中将“输出类型”从“类库”改为“Windows应用程序”,并将右击StunEngine项目将它“设为启动项目”。比如我要测试UIImage类是否工作正常,只需在UIImage类的最后添加以下代码:
单元测试
最后别忘了在Program.cs类中调用这个单元测试:
namespace StunEngine
{
static class Program
{
static void Main(string[] args)
{
UIImage.TestUIImage();
}
}
}
运行代码后,程序截图如下:
以后我每编写一个类都会实现单元测试,这样可以将错误限定在一个类中,给程序除错带来极大的方便,而且你也可以从单元测试中看到类的使用方法。
发布时间:2010/1/15 13:55:51 阅读次数:5408