Test funcional con Selenium y NUnit

by Luis Roig on junio 12th, 2010

Antes de seguir tratando otros aspectos de Cuyahoga en siguientes posts, me gustaría escribir sobre la importancia de tener tests funcionales automatizados en el desarrollo de cualquier aplicación software.

Entre los varios tipos de tests que normalmente son usados en el desarrollo de software el test funcional o de aceptación ataca directamente al interfaz final de la aplicación al que accederá el usuario, y su objetivo es verificar el correcto funcionamiento de todo el sistema en conjunto.

En el ámbito de las aplicaciones web, lo tradicional es realizar este testeo de forma manual, lo que los americanos llaman “monkey testing” y nosotros denominamos simplemente “a mano”. Esto puede servirnos cuando estamos desarrollando una determinada funcionalidad, pero en una aplicación web medianamente grande no es operativo funcionar de esta forma. ¡Ese trabajo lo tendría que hacer una máquina! Es necesario que tengamos otras piezas de software que prueben automáticamente nuestra aplicación.

Afortunadamente existen muchas herramientas y frameworks de testing de código abierto que nos facilitan mucho la tarea de escribir estas pruebas automatizadas. En este post vamos a hablar un poco de dos de ellas: Selenium y NUnit.

Selenium es un conjunto de herramientas para testear aplicaciones web en varias plataformas. Primero nos ofrece Selenium IDE, un plugin para Firefox con el que podemos crear de forma muy fácil los distintos casos de test. Con él grabaremos nuestra interacción con la aplicación y podemos indicar con un menu contextual las condiciones que queremos que se verifiquen.

Aunque el plugin para Firefox nos permite grabar y ejecutar casos de test sin ningún problema, tiene varias limitaciones: no podemos reutilizar aspectos comunes de los tests ni integrarlos en el framework de test que ya estemos utilizando para el desarrollo de nuestra aplicación. Para solucionar estas carencias existe Selenium Remote Control, un servidor que permite ejecutar nuestros tests en varios navegadores y además integrarlo con diferentes frameworks de testing (como RSpec para Ruby, JUnit para Java o NUnit para C#).

Veamos un pequeño ejemplo de los pasos que tendríamos que dar para correr un test funcional con Selenium y NUnit.

Supongamos que tenemos una sencilla aplicación web: el típico ejemplo de formulario con una caja de texto y un botón. Al pulsar el botón, la aplicación nos redirigirá a otra página donde mostrará “Hola ” y el texto que hayamos escrito en el formulario anterior.

Aunque se trate de un ejemplo trivial, imaginemos que deseamos realizar un test funcional para poder verificar este comportamiento posteriormente. En principio la aplicación puede estar escrita en cualquier tecnología (php, rails, javascript, asp.NET) y nuestros tests funcionales nunca dependerán de ello, pero imaginemos también que queremos usar C# y NUnit para escribirlos.

Para grabar el caso de test de forma sencilla, primero instalamos el plugin de Selenium para Firefox y creamos un caso de test nuevo. Pulsando el botón de grabar, navegamos a nuestro formulario en firefox, escribimos ‘Nectio’ en la caja de texto y pulsamos el botón. Cuando la aplicación nos muestra el mensaje ‘Hola Nectio’, podemos seleccionar dicho texto y pulsar ‘Verify text presence’ en el menú contextual. Por último volvemos a la ventana de Selenium y paramos la grabación del test.

Si en el menú del plugin elegimos Options > Format > C# Selenium RC, obtendremos algo parecido a esto:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using NUnit.Framework;
using Selenium;
 
namespace SeleniumTests
{
	[TestFixture]
	public class HelloWorld
	{
		private ISelenium selenium;
		private StringBuilder verificationErrors;
 
		[SetUp]
		public void SetupTest()
		{
			selenium = new DefaultSelenium("localhost", 4444, "*chrome", "http://change-this-to-the-site-you-are-testing/");
			selenium.Start();
			verificationErrors = new StringBuilder();
		}
 
		[TearDown]
		public void TeardownTest()
		{
			try
			{
				selenium.Stop();
			}
			catch (Exception)
			{
				// Ignore errors if unable to close the browser
			}
			Assert.AreEqual("", verificationErrors.ToString());
		}
 
		[Test]
		public void TheHelloWorldTest()
		{
			selenium.Open("/");
			selenium.Type("nombre", "Nectio");
			selenium.Click("Enviar");
			selenium.WaitForPageToLoad("30000");
			try { 
				Assert.IsTrue(selenium.IsTextPresent("Hola Nectio!"));
			}
			catch (AssertionException e)
			{
				verificationErrors.Append(e.Message);
			}
		}
	}
}

Lo siguiente será crear un nuevo proyecto .NET del tipo librería de clases. Es preciso incluir también referencias a los siguientes ensamblados: nmock, nunit.core, nunit.framework, ThoughtWorks.Selenium.Core, ThoughtWorks.Selenium.IntegrationTests y ThoughtWorks.Selenium.UnitTests. A continuación crearemos una clase con el código que hemos copiado desde el plugin. Una vez compilado el proyecto, para poder correr este test desde NUnit primero tendremos que iniciar el servidor de Selenium RC. Basta con bajárnoslo de la web, y teniendo java instalado en nuestra máquina podemos iniciarlo desde la línea de comandos de esta manera:

1
java -jar selenium-server.jar

Ahora tan sólo nos queda abrir el ensamblado que acabamos de compilar desde el GUI de NUnit. Al ejecutar el test Selenium se encargará de abrir el navegador o navegadores que indiquemos en el test y realizar las comprobaciones sobre el funcionamiento de nuestra aplicación.

Una de las ventajas que nos presenta el tener el test escrito en C# y Nunit es la posibilidad de sofisticar un poco más su lógica. En el test anterior, podríamos por ejemplo hacer que el texto que introduce el test en el formulario sea aleatorio, ayudándonos del método Path.GetRandomFileName:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[Test]
public void TheHelloWorldTest()
{
	string randomName = Path.GetRandomFileName().Replace(".","");
	selenium.Open("/");
	selenium.Type("nombre", randomName);
	selenium.Click("Enviar");
	selenium.WaitForPageToLoad("30000");
	try { 
		Assert.IsTrue(selenium.IsTextPresent("Hola "+ randomName + "!"));
	}
	catch (AssertionException e){
		verificationErrors.Append(e.Message);
	}
}

From → Sin categoría

4 Comentarios
  1. Luis muy bueno tu tutorial, estaba precisamente tratando de hacer un test mas elaborado para testear un formulario con campos generados aleatoriamente.
    Lamentablemente no me corrió mi test en NUnit.
    Para trabajar con Path.GetRandomFileName tuviste que sentenciar using System.IO ?
    Porque cuando lo intente correr en NUnit me tiro un problema de reconocimiento del Path, entonces no se que me esta faltando.
    Ojala me puedas ayudar !

    O bien publicar el código ejemplo que pusiste pero completo para saber si me falto algo.
    (hice todo lo que sale en el tutorial)

  2. Estimado ya lo solucione …el problema era en:
    selenium = new DefaultSelenium(“localhost”, 4444, “*googlechrome”, “http://…”);

    en la parte del navegador

  3. Luis Roig permalink

    Hola Ricardo! Sí, en efecto, hay que poner el hostname del site que testeas!!

    Un saludo!!

  4. Gracias por compartir con todos nosotros toda esta practica informacin. Con estos granitos de arena hacemos ms grande la montaa Internet. Enhorabuena por esta web.

    Saludos

Escribe un comentario!

Nota: Se permite XHTML. Tu email nunca se publicará.

Suscríbete a este feed de comentarios via RSS