#Python #Unittest #Selenium #Automation
En este post, vamos a ver cómo probar unitariamente una aplicación web en Python para verificar la corrección de la funcionalidad. Whoa! Esa frase tiene un puñado de jerga: prueba de unidad, aplicación web y pruebas de funcionalidad.
Vimos pruebas unitarias de un programa Python en un post anterior. Le recomendamos que lo haga, si no está familiarizado con las pruebas unitarias.
¿Qué es una prueba unitaria?La unidad
es una parte comprobable más pequeña de un programa o una aplicación.
Por lo tanto, las pruebas unitarias se utilizan para probar programáticamente cada componente comprobable.
Puede probar un programa de backend o un programa de frontend, como una aplicación web.
Para un programa de backend, escribiría una prueba de unidad para cada función o método en el código, ya que son unidades lógicas más pequeñas.
Sin embargo, para un frontend, identificará diferentes funciones que desea verificar y escribirá pruebas unitarias en consecuencia.
En este post, vamos a probar un programa de frontend, es decir, una aplicación web.
¿Qué es una aplicación web?
Cualquier aplicación que se renderice en un navegador web como Chrome, Firefox o Safari.
Todas las aplicaciones web tienen una cosa en común: son visibles para los usuarios finales una página HTML (Lenguaje de marcado de hipertexto). HTML es simplemente un lenguaje de formato para describir cómo se deben organizar las cosas. Es simplemente un archivo de texto.
Los navegadores obtienen esta página HTML e interpretan las etiquetas (por ejemplo, HEAD, BODY, HREF, TABLE, etc.).) para mostrarte una página bonita.
Las aplicaciones web funcionan en la arquitectura cliente-servidor, donde el servidor web aloja el contenido al que desea acceder y el navegador web actúa como cliente.
¿Qué es la prueba de funcionalidad?
Como su nombre indica, cuando escribe código de prueba funcional, su objetivo es probar la funcionalidad de la aplicación. En otras palabras, debe asegurarse de que la aplicación siga la especificación funcional.
Hay otros tipos de pruebas, como pruebas de rendimiento, pruebas de seguridad (penetración) y pruebas de aceptabilidad del usuario.
El código de prueba funcional que escriba puede incluirse en lo que se llama una prueba de regresión que se ejecuta periódicamente para asegurarse de que la funcionalidad antigua no se rompa debido a un nuevo desarrollo.
Al final de esta publicación, comprenderá el código completo mencionado a continuación.
No te desanimes si sientes que esto es demasiado. El objetivo de este post es diseccionar esto y mostrarte cómo puedes entender este código y luego escribir el tuyo propio.
El siguiente diagrama muestra el enfoque de alto nivel para probar automáticamente una aplicación web (página).
para escribir nuestras pruebas, utilizamos un framework de pruebas llamado unittest. Es muy similar a junit en Java o nunit en. Net.
unittest le permite agrupar su código de inicialización en una función de configuración y limpiar el código en una función de desmontaje.
El siguiente diagrama muestra el enfoque general detrás de las pruebas unitarias.
Como se puede ver en el diagrama anterior, un conjunto de pruebas se compone de uno o más casos de prueba.
Un caso de prueba puede tener una o más pruebas. En este post, nos vamos a centrar en un caso de prueba con una prueba. Mostraremos al final cómo agregar más pruebas al mismo caso de prueba, así como crear un conjunto de pruebas.
Como se mencionó anteriormente, cada caso de prueba tiene un método de configuración (ejecutar al principio) y desmontaje (ejecutar al final) para inicializar y limpiar respectivamente.
El fragmento de código anterior muestra la estructura de un caso de prueba unitario.
Línea 1: Importe las bibliotecas necesarias. En nuestro caso, estamos utilizando las bibliotecas selenium y unittest.
Línea 3: Crea una clase llamada MyTestCase que extiende unittest.Clase TestCase. Decimos que unittest.TestCase es la clase principal y MyTestCase es la clase secundaria.
Línea 4: Agregamos nuestro código de inicialización en el método de configuración. Necesita usar el nombre exacto del método para que unittest sepa que está agregando su código de inicialización aquí. Cuando ejecuta este caso de prueba, este método se ejecuta primero.
Línea 7: Una prueba de muestra que queremos incluir en el caso de prueba.
Línea 10: Otra prueba de muestra que tenemos en nuestro caso de prueba.
Línea 16: Agregamos nuestro código de limpieza dentro de este método de desmontaje. Lo opuesto al método de configuración, el método de desmontaje se ejecuta el último.
Entonces, el orden de invocación del método es:
setUp > test1 > test2 >
Línea 20: Esto dice que el programa principal comienza desde este lugar.
Línea 21: Así es como se ejecuta el caso de prueba.
Ahora es el momento de que tengamos en nuestras manos la prueba real que queríamos hacer. Recuerde, que queremos probar si el cuadro de búsqueda de Google devuelve al menos 5 resultados para una palabra clave de búsqueda dada.
Veamos primero el método de configuración:
En este fragmento de código, creamos el controlador del navegador Chrome.
Debe descargar el controlador selenium Chrome desde aquí si aún no lo tiene. Al momento de escribir este artículo, Chrome también tiene la versión 74. Desde mi navegador Chrome es la versión 73, he descargado la versión 73 para este ejercicio.
Línea 2 y 3 crea la opción Chrome y haz saber a selenium webdriver que no queremos que el navegador sea visible cuando ejecutemos la prueba.
Si no agrega esta opción, su prueba se atasca en el punto donde se abre el navegador.
Ahora veamos método de desmontaje:
simplemente limpiar el conductor llamando al método quit ().
Finalmente, es hora de echar un vistazo a la prueba que queremos incluir en este caso de prueba. Recordemos que podemos probar (assert) si el número de resultados de búsqueda devueltos es mayor o igual a 5.
Línea 1: El método de prueba comienza con la palabra «prueba».
Línea 3: Cargar www.google.com página web en el controlador (Tenga en cuenta que sí mismo.el controlador se crea durante el tiempo de configuración).
Línea 6: Localice el cuadro de búsqueda por el nombre del elemento HTML «q». Es necesario inspeccionar la página HTML para identificar esto.
Línea 7: Vacía el cuadro de búsqueda en caso de que haya algún valor predeterminado.
Línea 10: Rellene el cuadro de búsqueda con la cadena de búsqueda «Pruebas automatizadas».
Línea 11: Envía la consulta de búsqueda a Google.
Línea 14: Identificación de encabezados de resultados de búsqueda XPath.
Línea 17: Espere 10 segundos hasta que se cargue la página de resultados de Google.
Línea 20: Obtenga todos los encabezados de resultados de búsqueda utilizando el XPath definido en la línea 14.
Líneas 25 y 26: Los encabezados de los resultados de búsqueda son en realidad una lista y los repasamos para que aparezcan en la pantalla. Agregamos estas dos líneas solo con fines de demostración. Por lo general, los scripts de prueba no tienen pantallas de impresión, ya que no hay nadie disponible para mirar la pantalla y ver dicha salida cuando se automatiza.
Línea 30: Esta es la afirmación real que estamos haciendo. assertGreater es un método definido en unittest.Clase TestCase que nos permite comprobar si alguna salida es mayor que el valor some.
unittest.TestCase, de hecho, nos proporciona un conjunto de dicho método para verificar la igualdad, mayor que, menor que, etc. dependiendo de lo que quieras afirmar. La siguiente tabla muestra algunos de los métodos de afirmación comunes disponibles.
Como se muestra al principio, puede escribir el caso de prueba invocando lo siguiente en su código:
unittest.main()
En la línea de comandos, simplemente puede escribir el nombre de archivo que utilizó para guardar el caso de prueba.
python google_search_test.py
Ejecuta setUp (), luego test_result_count () y finalmente tearDown ().
Debería ver una salida similar a la siguiente:
Si alguna prueba falla, verá el mensaje de error junto con el método de prueba que falló.
Ese es su primer caso de prueba de Selenio/unidad exitoso. ¡Felicitaciones! Es un hito importante.
Bonus
Si tienes el steam, te animaría a seguir el resto para profundizar aún más en las pruebas automatizadas de la aplicación web base Selenium/unittest.
Supongamos que desea probar si el encabezado es igual a «Google».
El código de prueba se ve de la siguiente manera:
def test_header(self):
self.driver.get("http://www.google.com")
self.assertEqual("Google", self.driver.title)
Ahora todo nuestro caso de prueba se ve de la siguiente manera:
class GoogleSearchTest(unittest.TestCase):
def setUp(self): def test_header(self): def test_result_count(self): def tearDown(self):
if __name__ == "__main__":
unittest.main()
Supongamos que las pantallas de impresión anteriores están comentadas. Cuando ejecute el caso de prueba actualizado, debería obtener una salida de la siguiente manera:
test_header (__main__.GoogleSearchTest) ... ok
test_result_count (__main__.GoogleSearchTest) ... ok----------------------------------------------------------------------
Ran 2 tests in 13.799s
OK
Dice que realizó dos pruebas y ambas tuvieron éxito.
Digamos que cambio la condición assertEqual en la primera prueba a lo siguiente:
self.assertEqual("Microsoft", self.driver.title)
¿Qué crees que pasaría aquí?
Sí, lo adivinaste bien. El primer caso de prueba fallará como uno mismo.controlador.el título es igual a Google, no a Microsoft.
Obtendrá una salida similar a la siguiente:
test_header (__main__.GoogleSearchTest) ... FAIL
test_result_count (__main__.GoogleSearchTest) ... ok
====================================================================
FAIL: test_header (__main__.GoogleSearchTest)
--------------------------------------------------------------------
Traceback (most recent call last):
File "google_search_test.py", line 19, in test_header
self.assertEqual("Microsoft", self.driver.title)
AssertionError: 'Microsoft' != 'Google'
- Microsoft
--------------------------------------------------------------------
Ran 2 tests in 14.011s
FAILED (failures=1)
La salida anterior dice que solo una prueba tuvo éxito y la falló.
Cuando escribes tus casos de prueba por primera vez, es posible que te encuentres con situaciones como esta.
Asumiendo que su caso de prueba es correcto, identificará errores en el código y obtendrá que los desarrolladores respectivos corrijan el problema y vuelvan a probar.
Si este error ocurre en una prueba de regresión, este error se introduce debido al nuevo desarrollo de software realizado sobre la base de código existente.
Esto muestra que hay algo mal con la nueva base de código que necesita arreglarse para asegurarse de que la funcionalidad antigua funcione. Una vez más, los desarrolladores deben encargarse de ello.
¿Qué tal tener muchos casos de prueba? Digamos que tenemos TestCase1 y TestCase2, cada uno con varias pruebas.
Puede crear lo que se llama un conjunto de pruebas y ejecutarlo utilizando un ejecutor de pruebas de la siguiente manera:
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestCase1))
suite.addTest(unittest.makeSuite(TestCase2))
runner = unittest.TextTestRunner()
runner.run(suite)
El código anterior ejecutará todas las pruebas en TestCase1 y luego en TestCase2.
Eso es todo por hoy. Espero que eso ayude.