Cultorios Automated Unity Game Testing Tutorial



Hello again.

If you have read our previous post about Development Cultorios game and MVC in Unity:
http://doctrina-kharkov.blogspot.com/2016/08/cultorios-unity-mvc-tutorial.html
you have noticed that we made separate Controller witch give us a lot of benefits. One of them is ability to automate game testing. We know that Unity provide solution for unit-tests, but it's complicated as finding bugs :). And that's obvious because automated testing is some kind of AI which need deep understanding the problem that is still not resolved with modern computers. It's depends of architecture, AI, game mechanics and lots of things.

This gameplay demonstrate automated movement of a Hero described below.


If you ever give your unpolished game to someone who see it at first he will crash it in a minutes. And you asking yourself Why ? I did it so long, that's should not happened.

Reason is simple:
as developer you play exactly right to make everything working, but players are not! They push all the buttons at once and do some kind of random behavior. And there your game came into a case you never test it as developer.

With years we try to do same things during development but always there is a person who crash your game. Of course professional QA will do it better and even find a patters of bugs, know vulnerable parts of your code. But as indie developers we not always have resources to involve such people.

What all of this came to ? Games crash because of Input. If you start your game and do nothing in most cases it works fine, but with input it stuck or crash. And now we have a separate class that send input into a logic.

Idea is simple:
Generate random input instead of use keyboard or controller data. That's it. Most games at development will crash at that simple case. 

If we have data from devices handled like this:

protected void Controlled()
{
float h = Input.GetAxis("Horizontal");
if ( Mathf.Abs( h ) != 0f )
{
root.ForwardEvent( EEvents.Move, h);
}

if ( Input.GetButtonDown("Jump"))
{
root.ForwardEvent( EEvents.Jump, null);
}
}

where hero is moved and jump. Randomly generated input will looks like this.

  protected void Generated()
{
//Randomly select one of the available input from enum
    //Randomly generate data for such input
    //Send it to Root
 }

We not made such simple case because it bring Hero nowhere and of course it is very limited testing because of full random. We made it much complicated to make behavior of our hero more real:

  protected void Generated()
{
mMoveTimer += Time.deltaTime;

    if (mMoveTimer > mMovePeriod)
{
mMoveRightLeftTimer += Time.deltaTime;

if ( mMoveRight )
{
root.ForwardEvent( EEvents.Move, 1f );
}
else if ( mMoveLeft )
{
root.ForwardEvent( EEvents.Move, -1f );
}

if ( mMoveRightLeftTimer > mMoveLeftRightPeriod )
{
mMoveLeft = mMoveRight = false;

mMoveRightLeftTimer = 0f;

if ( Random.value > 0.5f )
{
mMoveRight = true;
}
else
{
mMoveLeft = true;
}

mMoveLeftRightPeriod = Random.Range( 1f, 3f );

}

mMoveTimer = 0f;
}

mJumpTimer += Time.deltaTime;
if (mJumpTimer > mJumpPeriod)
{
root.ForwardEvent( EEvents.Jump, 0f );
mJumpTimer = 0f;
}
 }

Conclusion:
We select direction of the Hero movement and time which he made such movement. When this time is reached we do it all over again. That's how hero will not stay at same place. Also we add jumping with some period of time. Of course you should write down code for testing, even with some kind of AI that is still not very useful.

Our next solution will be record mini patterns of input and randomly select such recordings. That's how we not need to write down any code. See such tutorial later.

Thanks for reading.



2 comments: