65.9K
CodeProject 正在变化。 阅读更多。
Home

iPhone 上的 C++: 测试驱动开发

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.50/5 (3投票s)

2009年6月2日

CPOL

4分钟阅读

viewsIcon

19872

最近我一直在学习一些开发策略,而我最近关注的一个新策略是测试驱动开发 (TDD) 或单元测试。

最近我一直在学习一些开发策略,而我最近关注的一个新策略是测试驱动开发 (TDD) 或单元测试。TDD 和单元测试背后的思想是将问题分解成小的、易于管理的问题,而不是一开始就设计所有的东西,并且在项目的剩余时间里忍受任何或所有的错误。TDD 是一个非常复杂的主题,通常需要使用各种框架进行动态单元测试,但我将专注于 TDD 的“开始”方法,静态单元测试。

我们如何开始?好吧,在我当前的引擎中,我所做的是编写一个名为“TestGame.cpp”的类,它是一个单例类,包含用于测试游戏的各种方法。在该类中,我会编写函数来测试我将要创建的特定类,或者测试整个游戏循环来测试类的逻辑,而无需为我们的对象构建一个游戏世界。在 TestGame 类中有一个名为 'startTesting()' 的函数,它将调用任何您希望测试的内容。让我们编写一个示例测试,让您了解我正在做的最基本的内容。

//This function is public, and able to be called when you obtain the instance
//of the TestGame class. We will start every test from this function, and keep
//it kind of like a list. Whenever an aspect needs to be changed, for example
//with the actor class, we can simply uncomment the 'testActorClass()' line
//to ensure it still passes all of our tests.
void TestGame startTesting()
{
	testActorClass();
}

//This function, however... is private and unable to be called by anything
//outside the "TestGame" class, and should only be called by the 'startTesting()'
//function.
void testActorClass()
{
	Actor *act = new Actor();
	string testString;
	float testFloat;

	act->setAlpha( .50f );
	testFloat = act->getAlpha();

	//	identities are unique and assigned when the object
         ///      is constructed.. Calling this function
	//	should not change the identity
	act->setIdentity( "newIdentity" );
	testString = act->getIdentity(); //should still be "Actor_#"

	act->setName( "Werewolf ");
	testString = act->getName();//should be "Werewolf"

	act->setPosition( Vector2::ZERO() );
	testString = act->getPosition();//should be 0,0

	act->setSize( Vector2(32, 32) );
	testString = act->getSize();//should be 32, 32

	act->update( .003f );
}

现在,如果我编译这段代码,它会抛出一堆错误。“设置名字?.. 获取身份?我不知道怎么做!” 这就是重点!这些函数尚未编写。基本思想是构建您希望 actor 类执行的操作,然后编写代码来执行它。下一步是编写 JUST 足够的代码来使项目能够编译,所以…我们去 actor 类!毫不夸张地说,我们在下一步将要做的就是编写像这样的骨架函数(注意:像 Vector2 这样的各种辅助类已经编写并添加到引擎中,它们已经创建并且已经使用这种方法进行了测试,并且在 C++(或据我所知 Obj-C)中不是“标准”的);

//in the Actor.h file
public:
	bool setIdentity( const string &value );
	string getIdentity() const { return identity; }

	bool setName( const string &value );
	string getName() const { return name; }

	bool setPosition( const Vector2 &value );
	Vector2* getPosition() { return position; }

	bool setSize( const Vector2 &value );
	Vector2* getSize() const { return size; }

	bool setAlpha( const float value );
	float getAlpha() const { return alpha; }

	virtual void update( const float deltaTime );
protected:
	string identity;
	string name;
	Vector2 *position;
	Vector2 *size;
	float alpha;
//in the Actor.cpp file
bool Actor::setIdentity( const string &value )
{
}

bool Actor::setName( const string &value )
{
}

bool Actor::setPosition( const Vector2 &value )
{
}

bool Actor::setSize( const Vector2 &value )
{
}

bool Actor::setAlpha( const float value )
{
}

void Actor::update( const float deltaTime )
{
}

这段代码现在应该可以编译和运行,即使它什么也不做。好吧,我们知道我们想要做什么,并且我们现在有一个骨架来做它……所以我们应该开始编写代码!

例如,我们知道我们希望 actor 的身份是唯一的,并且 setIdentity 函数应该只在当前没有身份的情况下设置字符串,所以因为这将是最难编写的函数,让我们快速完成它。

bool Actor::setIdentity( const string &value )
{
	//	if the identity has already been set, do not
	//	re-set the identity. Object must be destroyed
	//	and re-created to reset an identity.
	if ( identity.length() != 0)
	{
		return false;
	}

	//	if the identity has not been set, set it
	//	and return true
	identity = value;
	return true;
}

真的,就是这样。actor 不知道它的身份是否唯一,也不知道如何获得唯一的身份。它只是说“好的,我现在没有身份,所以我将接受这个并使其成为我自己的!” 想法是 actor 类独立存在,并作为自己的数据。为了获得唯一的身份并跟踪游戏世界中的所有 actor,我们将使用一个 ActorController(还记得那个讨厌的叫做 Model / View / Controller 的东西吗?)。Actor 类是数据(模型),而 Controller 将管理该数据并在需要时将其呈现给视图进行渲染……但这将是另一篇文章的主题。

我们应该做的最后一件事是注释注释注释!我非常喜欢注释我的代码,并记录不仅函数的作用,还要记录它为什么以这种方式实现。如果你在 3 个月后回顾你的代码,你会对自己说“我没有写这个……我在想什么?!” ……好吧,如果你注释了你的代码,你就会知道!这是一个养成的好习惯,如果你看看我之前的一些帖子中的屏幕控制器,你会注意到我注释了多少。

今天就到此为止。测试驱动开发是一个巨大的领域,这只是如何完成它的非常非常基础的内容。一旦你进入框架,它可能会非常复杂,但非常值得付出努力。

祝大家编码愉快!

在此处阅读原始博客文章 这里

© . All rights reserved.