Episodix: Integration Tests – Iteración 2

En cada test se añadirán los objetos, scripts y demás cosas necesarias de iteración_2 para su correcta realización. Para la realización de estos tests se hace uso de scripts (uno para cada test) que realizan las comprobaciones correspondientes. Al pasar dichas comprobaciones se utiliza la función IntegrationTest.Pass( ); para indicar que se pasa correctamente o IntegrationTest.Fail( ); para indicar que falla. A continuación se mostrarán los tests de integración que se implementaron en Unity para comprobar el correcto funcionamiento de la iteración 2:

Test_Solids: Test para comprobar que hay uno de los seis sólidos posibles en cada una de las posiciones de los Anchor Points. Partiendo del script Solids.cs se crea el script TestSolids.cs, que realizará las acciones de elección y activación en los Anchor Points de Solids.cs y comprobará que el resultado sea el esperado. La escena del test constará del objeto Street con TestSolids.cs asociado a Solids.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class TestSolids : MonoBehaviour
{
// Almacenará los objetos correspondientes a los sólidos y el componente Transform de los Anchor Points.
//
public GameObject cube, sphere, cylinder, capsule, prism, circle;
public Transform anchor1, anchor2, anchor3;

int select, count, i;

// Se crea una lista con los sólidos de la escena y se selecciona de manera aleatoria tres
// de ellos para asignarlos a la posición de los Anchor Points y activarlos.
//
void Awake ()
{
List<GameObject> solids = new List<GameObject> ()
{
cube,
sphere,
cylinder,
capsule,
prism,
circle,
};

for (i=1; i<4; i++)
{
select = Random.Range(0, solids.Count);
switch(i)
{
case 1:
solids[select].transform.position = anchor1.position;
break;
case 2:
solids[select].transform.position = anchor2.position;
break;
case 3:
solids[select].transform.position = anchor3.position;
break;
}
solids[select].SetActive(true);
solids.RemoveAt (select);
}

// Si hay un sólido en la posición de cada anchor el test es satisfactorio, en caso
// contrario se dará por fallido el test.
//
if (CheckSolid(anchor1) && CheckSolid(anchor2) && CheckSolid(anchor3))
{
IntegrationTest.Pass();
}
else
{
IntegrationTest.Fail();
}
}

// Comprueba que en la posición de anchor se encuentra alguno de los seis sólidos.
//
bool CheckSolid(Transform anchor)
{
if (anchor.position == cube.transform.position || anchor.position == sphere.transform.position || anchor.position == cylinder.transform.position
|| anchor.position == capsule.transform.position || anchor.position == prism.transform.position || anchor.position == circle.transform.position)
{
return true;
}
else
{
return false;
}
}
}

Test_Solids

Test_QuestionAnchorPoints: Test para comprobar que la primera pregunta se corresponde con el sólido del primer Anchor Point, la segunda pregunta con el sólido del segundo Anchor Point y la tercera pregunta se corresponde con el sólido del tercer Anchor Point. Partiendo del script StartRecallPhase.cs se crea el script TestStartRecallPhase.cs, que realizará las acciones de elección de las preguntas del modo que se hace en StartRecallPhase.cs y comprobará que el resultado de las tres primeras preguntas se correspondan con los objetos en los Anchor Points y manteniendo el mismo orden. La escena del test constará de los objetos Street, RecallPhase (donde se encuentran las preguntas) y CheckEnd, con TestStartRecallPhase.cs asociado.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class TestStartRecallPhase : MonoBehaviour
{
public GameObject q1, q2, q3, q4, q5, q6; // Almacenará los objetos de las posibles preguntas del test.
public GameObject cube, sphere, cylinder, capsule, prism, circle; // Almacenará todos los posibles sólidos.
public GameObject scores;
public GameObject recallPhase; // Almacenará el objeto Recall Phase;

public Transform anchor1, anchor2, anchor3;

GameObject aux;

int select;
int count = 3;

List<GameObject> allSolidsQuestions = new List<GameObject>(); // Lista con las preguntas de todos los sólidos.
List<GameObject> streetSolidsQuestions = new List<GameObject>(); // Lista con las preguntas de los sólidos de la calle.
List<GameObject> allSolids = new List<GameObject>(); // Lista con todos los sólidos posibles.

// Esta función añadirá a la lista streetSolidsQuestions la pregunta correspondiente al sólido
// que se encuentre en la posición del Anchor Point pasado como argumento.
//
void AddStreetSolidsQuestions(Transform anchorPoint)
{
for (int i = 0; i < allSolids.Count; i++)
{
if (allSolids[i].transform.position == anchorPoint.position)
{
switch (allSolids[i].name)
{
case "Cube":
streetSolidsQuestions.Add(q1);
break;
case "Sphere":
streetSolidsQuestions.Add(q2);
break;
case "Cylinder":
streetSolidsQuestions.Add(q3);
break;
case "Capsule":
streetSolidsQuestions.Add(q4);
break;
case "Prism":
streetSolidsQuestions.Add(q5);
break;
case "Circle":
streetSolidsQuestions.Add(q6);
break;
}
}
}
}

// Al inicio se añaden los objetos de las listas declaradas anteriormente.
//
void Start()
{
allSolids.Add(cube);
allSolids.Add(sphere);
allSolids.Add(cylinder);
allSolids.Add(capsule);
allSolids.Add(prism);
allSolids.Add(circle);

AddStreetSolidsQuestions(anchor1);
AddStreetSolidsQuestions(anchor2);
AddStreetSolidsQuestions(anchor3);

allSolidsQuestions.Add(q1);
allSolidsQuestions.Add(q2);
allSolidsQuestions.Add(q3);
allSolidsQuestions.Add(q4);
allSolidsQuestions.Add(q5);
allSolidsQuestions.Add(q6);

if (CheckSolidsQuestions(anchor1, nextQuestion()) && CheckSolidsQuestions(anchor2, nextQuestion()) && CheckSolidsQuestions(anchor3, nextQuestion()))
{
IntegrationTest.Pass();
}
else
{
IntegrationTest.Fail();
}
}


// Devolverá la siguiente pregunta de la Recall Phase. Empezará
// devolviendo las correspondientes a los objetos situados en la calle.
// En caso de que ya no haya más preguntas devolverá los resultados.
//
GameObject nextQuestion()
{
if (streetSolidsQuestions.Count != 0)
{
aux = streetSolidsQuestions[0];
streetSolidsQuestions.RemoveAt(0);
return aux;
}
else
{
if (allSolidsQuestions.Count != 0 && count != 0)
{
select = Random.Range(0, allSolidsQuestions.Count);
aux = allSolidsQuestions[select];
allSolidsQuestions.RemoveAt(select);
count--;
return aux;
}
else
{
aux = scores;
return aux;
}
}
}


// Comprueba si se corresponde la pregunta con el sólido de la posición
// del anchorPoint.
bool CheckSolidsQuestions(Transform anchorPoint, GameObject Qsolid)
{
switch (Qsolid.name)
{
case "Q1cube":
return CheckPosition(cube, anchorPoint);
case "Q2sphere":
return CheckPosition(sphere, anchorPoint);
case "Q3cylinder":
return CheckPosition(cylinder, anchorPoint);
case "Q4capsule":
return CheckPosition(capsule, anchorPoint);
case "Q5prism":
return CheckPosition(prism, anchorPoint);
case "Q6circle":
return CheckPosition(circle, anchorPoint);
default:
return false;
}
}

// Comprueba si la posición de sol y anch es la misma.
//
bool CheckPosition(GameObject sol, Transform anch)
{
if (sol.transform.position == anch.position)
{
return true;
}
else
{
return false;
}
}
}

Test_QuestionAnchorPoints

– Test_CheckScores: Test para comprobar que se actualiza correctamente la puntuación. Partiendo del script Scores.cs se crea el script TestScores.cs, que realizará las acciones para determinar si la respuesta dada es correcta comparándola con los sólidos de la escena que se hace en Scores.cs y comprobará que el resultado es el esperado: respuesta true si el objeto está presente en la calle añade respuesta correcta e incorrecta si no está presente; respuesta flase si el objeto no está presente en la calle añade respuesta correcta e incorrecta si está presente. La escena del test constará de los objetos Street, en el cual siempre estarán activos el cubo, la esfera y el cilindro e inactivos el resto, y Scores, con TestScores.cs asociado.

using UnityEngine;
using System.Collections;

public class TestScores : MonoBehaviour
{
public GameObject cube; // Sólido activo en la escena de testeo.
public GameObject capsule; // Sólido inactivo en la escena de testeo.
bool answer; // Almacenará la respuesta a una pregunta (Si o No)

// Recogerá la respuesta a una pregunta.
//
void CollectAnswer(bool ans)
{
answer = ans;
}

// Comprobará si la respuesta a la pregunta es correcta.
//
bool AddScore (GameObject solid)
{
if (solid.activeInHierarchy==answer) // Comprueba que la respuesta coincida con el estado del sólido en la escena.
{
return true; // Respuesta correcta.
} else
{
return false; // Respuesta incorrecta.
}
}


void Start()
{
// Se recogerá como respuesta true para el caso de que se preguntase por el cubo, que sabemos que está
// activo en la escena de testeo.
CollectAnswer(true);
// AddScore(cube) debería devolver true, en caso contrario se considera el test fallido.
if (!AddScore(cube))
{
IntegrationTest.Fail();
}
// Se recogerá como respuesta false para el caso de que se preguntase por el cubo, que sabemos que está
// activo en la escena de testeo.
CollectAnswer(false);
// AddScore(cube) debería devolver false, en caso contrario se considera el test fallido.
if (AddScore(cube))
{
IntegrationTest.Fail();
}
// Se recogerá como respuesta true para el caso de que se preguntase por la cápsula, que sabemos que no
// está activa en la escena de testeo.
CollectAnswer(true);
// AddScore(capsule) debería devolver false, en caso contrario se considera el test fallido.
if (AddScore(capsule))
{
IntegrationTest.Fail();
}
// Se recogerá como respuesta true para el caso de que se preguntase por la cápsula, que sabemos que no
// está activa en la escena de testeo.
CollectAnswer(false);
// AddScore(capsule) debería devolver true, en caso contrario se considera el test fallido.
if (!AddScore(capsule))
{
IntegrationTest.Fail();
}
IntegrationTest.Pass();
}

}

Test_CheckScores

– Test_Menu: Test para comprobar que al pulsar la tecla escape, el objeto de la interfaz del menú del juego (continuar, reiniciar, salir), así como su cámara, se activa/desactiva. Del mismo modo se comprobará que FPSController se desactiva/activa simultáneamente. Partiendo del script Menu.cs se crea el script TestMenu.cs, que realizará las acciones para activar/desactivar el objeto Menu correspondiente al menú del juego que se hace en Menu.cs y comprobará que el comportamiento sea el adecuado. Para simular la pulsación de la tecla «escape» se llamará a una función, ActivateMenu( ), que realizará las acciones que se corresponderían con la pulsación de dicha tecla. La escena del test constará de los objetos Menu (que incluye la interfaz del menú), Recall Phase Camera (la cámara correspondiente al menú), FPSController (el personaje controlado por el usuario) y Street, con TestMenu.cs asociado.

using UnityEngine;
using System.Collections;

public class TestMenu : MonoBehaviour
{
// Se almacenarán los objetos que necesitaremos activar/desactivar
// a la hora de activar/desactivar el menú.
//
public GameObject men;
public GameObject character;
public GameObject cam;

// menu indicará el estado del menú actualmente.
bool menu;

void Start()
{
menu = men.activeInHierarchy;

// Al pulsar la tecla "escape" se activará/desactivará el menú. Se simulará el caso en que se
// pulsase "escape" (Input.GetKeyDown("escape")) llamando a la función ActivateMenu().
// La primera llamada a ActiveMenu() debería activar el menú y la cámara y desactivar el FPSController...
//
ActivateMenu();
if (!men.activeInHierarchy && !cam.activeInHierarchy && character.activeInHierarchy)
{
IntegrationTest.Fail();
}

// ...mientras que la segunda llamada debería activar el FPSController y desactivar el menú y la cámara.
//
ActivateMenu();
if (men.activeInHierarchy && cam.activeInHierarchy && !character.activeInHierarchy)
{
IntegrationTest.Fail();
}
else
{
IntegrationTest.Pass();
}
}


// Activa el menú si está desactivado y lo desactiva si está activado.
//
void ActivateMenu()
{
if (!menu)
{
menu = true;
men.SetActive(true);
character.SetActive(false);
cam.SetActive(true);
}
else
{
menu = false;
men.SetActive(false);
cam.SetActive(false);
character.SetActive(true);
}
}
}

Test_Menu

– Test_AllSolids: Test para comprobar que mientras se mantiene pulsada la tecla tab el objeto de la interfaz que muestra el conjunto de todos los posibles sólidos se mantiene activado y si no se mantiene la tecla tab se mantendrá desactivado. Partiendo del script Menu.cs se crea el script TestAllSolids.cs, que realizará las acciones para activar/desactivar el objeto All Solids correspondiente a la interfaz del juego que muestra por pantalla todos los posibles sólidos del juego que se hace en Menu.cs y comprobará que el comportamiento sea el adecuado. Para simular la pulsación de la tecla «tab» se llamará a una función, ActivateAllSolids( ), que realizará las acciones que se corresponderían con la pulsación de dicha tecla. Se considerará que la tecla «tab» se mantiene pulsada hasta que se llame otra vez a la función ActivateAllSolids( ). La escena del test constará de los objetos All Solids (que incluye la interfaz con los posibles sólidos) y Street, con TestAllSolids.cs asociado.

using UnityEngine;
using System.Collections;

public class TestAllSolids : MonoBehaviour
{
// Se almacenarán los objetos que necesitaremos activar/desactivar
// a la hora de activar/desactivar AllSolids.
//


public GameObject allSolids;

// aS indicará el estado de AllSolids actualmente.
bool aS;

void Start()
{
aS = allSolids.activeInHierarchy;
// Inicialmente AllSolids debe estar desactivado.
if (allSolids.activeInHierarchy)
{
IntegrationTest.Fail();
}
// Al mantener pulsada la tecla "tab" se mantendrá activado AllSolids. Se simulará el caso en que se
// pulsase "tab" (Input.GetKey("tab")) llamando a la función ActivateAllSolids().
// La primera llamada a ActiveAllSolids() simulará que se mantiene pulsada la tecla "tab", lo que
// resultaría en mantener AllSolids activado...
//
ActivateAllSolids();
if (!allSolids.activeInHierarchy)
{
IntegrationTest.Fail();
}


// ...mientras que la segunda llamada se simulará que se deja de pulsar la tecla "tab", lo que debería
// desactivar AllSolids.
//
ActivateAllSolids();
if (allSolids.activeInHierarchy)
{
IntegrationTest.Fail();
}
else
{
IntegrationTest.Pass();
}
}


// Activa AllSolids
//
void ActivateAllSolids()
{
aS = !aS;
allSolids.SetActive(aS);
}
}

Test_AllSolids

A mayores también se mantendrán los tests realizados previamente para la iteración 1. No sería necesario añadir ningún test unitario más.

*Para más información acerca de Unity Test Tools pulse aquí.

Deja un comentario