0% encontró este documento útil (0 votos)
7 vistas17 páginas

Pruebas Unitarias y Funciones en Python

El documento aborda la importancia de las pruebas unitarias en el desarrollo de software, destacando su papel en la detección temprana de errores y la mejora de la calidad del código. Se explican conceptos clave sobre funciones en Python, incluyendo su declaración, parámetros y el uso de la instrucción 'return'. Además, se presentan los principios F.I.R.S.T. y el ciclo de vida de una prueba unitaria, enfatizando los beneficios de su implementación en el proceso de desarrollo.

Cargado por

luis.orive15
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
7 vistas17 páginas

Pruebas Unitarias y Funciones en Python

El documento aborda la importancia de las pruebas unitarias en el desarrollo de software, destacando su papel en la detección temprana de errores y la mejora de la calidad del código. Se explican conceptos clave sobre funciones en Python, incluyendo su declaración, parámetros y el uso de la instrucción 'return'. Además, se presentan los principios F.I.R.S.T. y el ciclo de vida de una prueba unitaria, enfatizando los beneficios de su implementación en el proceso de desarrollo.

Cargado por

luis.orive15
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd

UNIVERSIDAD DE SAN CARLOS DE GUATEMALA

FACULTAD DE INGENIERÍA
ESCUELA DE CIENCIAS Y SISTEMAS
SEGUNDO SEMESTRE 2025
PRACTICAS INICIALES
SECCIÓN F+

PRUEBAS UNITARIAS EN PYTHON

CARNET NOMBRE

202100262 LUIS FERNANDO ORIVE PEREZ

202200166 JOSÉ EDUARDO OCHOA SANDOVAL

202201502 DOUGLAS XAVIER SANTIAGO SOTO MEJIA

202405038 CHRISTOPHER ANDRÉS VALENCIA MONTENEGRO

202405532 MARCOS MANUEL CHIP CASTILLO


Todas las personas que nos vemos envueltos por el mundo del desarrollo de
software, tenemos la capacidad de crear nuevo software, pero muchas veces en el
tiempo en el cual estamos desarrollando las distintas aplicaciones, se suele dar el
caso de querer probar las nuevas funcionalidades que tendrá la misma aplicación.
Con ello, como desarrolladores, usualmente, ejecutamos la aplicación completa, lo
que genera pérdida de tiempo en cuestión de entrega o producción del código.

Para ello, las pruebas unitarias fungen como una herramienta valiosa para probar
las unidades mínimas de nuestras aplicaciones, estas unidades dependiendo del
entorno pueden ser instancias de objetos, clases, funciones, etc. Con ello se logra
minimizar los errores y el tiempo de entrega de las aplicaciones.

Python, al ser un lenguaje de programación bastante común en la actualidad, se ha


dado a lugar a la creación de frameworks, los cuales, ayudan en distintos ámbitos
del desarrollo, y las pruebas unitarias no se quedan fuera de ello.
Funciones formato def Python
Las funciones en Python son bloques de código que podemos reutilizar para llevar a cabo
tareas específicas. Esta característica permite una programación más estructurada y
modular que utiliza el principio de desarrollo de software DRY (“Don't repeat yourself”),
fundamental para desarrollar aplicaciones de cualquier tamaño.

Si bien Python ya proporciona muchas funciones integradas como print() y len(), también
podemos definir funciones propias para usar en proyectos. Una de las grandes ventajas que
ofrecen las funciones es que reduce de gran manera las líneas de código del programa.

Pensar en las funciones como "cajas negras" o "recetas" que toman ingredientes (entradas)
y producen un resultado (salida).

¿Que es una función en Python?


Una función en Python es, en esencia, un bloque de código diseñado para ejecutar una
tarea particular. Las funciones se pueden invocar en cualquier momento del programa,
permitiendo que ese código se ejecute cada vez que sea necesario sin necesidad de
duplicarlo.

Cuando hablamos de función, nos referimos a una porción de código que realiza una
operación específica y que puede tornarnos un valor. Las funciones nos ayudan a organizar
y dividir el código en unidades lógicas, lo cual es crucial para el mantenimiento y la
escalabilidad de un proyecto. Una función puede hacer tareas simples o complejas, desde
sumar dos números hasta procesar grandes cantidades de datos.

¿Cómo se declaran funciones def en Python?


Para declarar una función en Python, se utiliza una estructura específica. Comenzamos
empleando la palabra clave def, que es una abreviatura de 'define', seguida por el nombre
de la función que se desea crear. Este nombre debe ser descriptivo y reflejar lo que la
función hace, manteniendo siempre las convenciones de nomenclatura en Python, como el
uso de letra minúscula y guiones bajos para separar palabras.

Después del nombre, se colocan paréntesis que pueden contener parámetros si es


necesario. Tras los paréntesis, se coloca un dos puntos (:), señalando el inicio del bloque de
código correspondiente a la función. La parte del cuerpo de la función estará siempre
indentada, lo cual es vital en Python para definir el alcance de cada bloque de código.

Es crucial recordar que las funciones pueden, además, devolver valores utilizando el
comando return, lo que permite que la función no solo ejecute acciones sino que también
entregue un resultado concreto al invocar la misma.
Es esencial prestar atención a la indentación, ya que toda la lógica dentro de la función
debe estar perfectamente alineada. Esto garantiza que Python interprete correctamente el
inicio y el fin del bloque de código de una función.
Cuando la primera instrucción de una función es un string encerrado entre tres comillas
simples ' ' ' o dobles " " ", a dicha instrucción se le conoce como docstring. El docstring es
una cadena que se utiliza para documentar la función, es decir, indicar qué hace dicha
función.

Características y Sintaxis

1. La palabra clave def


2. Un nombre de función
3. Paréntesis ’()’, y dentro de los paréntesis los parámetros de entrada, aunque los
parámetros de entrada sean opcionales.
4. Dos puntos “:”
5. Algún bloque de código para ejecutar
6. Una sentencia de retorno (opcional)

Imagen obtenida de j2logo

Parámetros y Argumentos
Hay una sutil distinción entre los términos parametro y argumento. Los parámetros son los
nombres utilizados en la definición de la función, mientras que los argumentos son los
valores concretos que se proporcionan para cada parámetro en la llamada a la función. En
Python, el término argumento se usa a menudo informalmente para referirse a ambos.

Los argumentos son opcionales, lo que significa que puede tener funciones sin argumentos.
Sin embargo, los paréntesis son necesarios cuando se tiene la intención de llamar a la
función, incluso si la función no toma argumentos. Tanto las definiciones de función como
las llamadas siempre deben incluir paréntesis, incluso cuando están vacías.
Se obtendrá un error de sintaxis si se olvidan los paréntesis en una definición de función. Si
se olvidan los paréntesis en una llamada a una función, obtendrá un objeto de función en
lugar del resultado esperado que debería producir la función.

Argumentos Posicionales

La forma más rápida de llamar a una función con argumentos es confiar en la posición
específica de cada argumento. En este caso, usarás lo que se conoce como argumentos
posicionales.

En la definición de función, se especifica una serie de parámetros separados por comas


dentro de los paréntesis.

Aunque los argumentos posicionales son una forma común de pasar datos a una función,
podrían causar algunos problemas. El orden de los argumentos de la llamada debe coincidir
con el orden de los parámetros de la definición. Si cambias el orden, es posible que
obtengas un comportamiento inesperado o un error.

Posicionales *args

Python proporciona una sintaxis para pasar un número arbitrario de argumentos


posicionales a una función. La sintaxis consiste en añadir un asterisco inicial al nombre del
argumento. En la mayoría de los escenarios, verá esta sintaxis como , pero puede usar
cualquier nombre de argumento que se adapte a sus necesidades.*args

Posicionales **kwargs

Colocar un doble asterisco () antes de un nombre de parámetro en una definición de función


le dice a Python que empaquete los argumentos de palabras clave proporcionados en un
diccionario.

En este caso, Python empaqueta los argumentos de palabras clave , y en un diccionario. A


continuación, puede utilizar el diccionario en el cuerpo de la función como un diccionario
normal.

Argumentos Keyword

Al llamar a una función, puede especificar argumentos con el formato . Esta forma de pasar
argumentos a una función de Python se conoce como uso de argumentos de palabras
clave. Por ejemplo, puede llamar a la función como se muestra a
continuación:argument=valuecalculate_cost()

El uso de argumentos keyword elimina la restricción de el orden de los argumentos porque


cada argumento de palabra clave designa explícitamente un parámetro específico por
nombre, por lo que se puede especificar en cualquier orden, y Python sabrá qué argumento
va con qué parámetro.
Por lo tanto, los argumentos de palabras clave permiten flexibilidad en el orden en que se
especifican los argumentos de función, pero el número de argumentos sigue siendo rígido.

El “return” en las funciones


La instrucción return en Python se utiliza para salir de una función y enviar un valor de
vuelta al llamador. Puede devolver cualquier tipo de datos y, si varios valores están
separados por comas, se empaquetan automáticamente en una tupla. Si no se especifica
ningún valor, la función devuelve None de forma predeterminada.

Ámbito (Scope) de las variables


En cualquier lenguaje de programación de alto nivel, toda variable está definida dentro de
un ámbito. Esto es, los sitios en los que la variable tiene sentido y dónde se puede utilizar.
Los parámetros y variables definidos dentro de una función tienen un ámbito local, local a la
propia función. Por tanto, estos parámetros y variables no pueden ser utilizados fuera de la
función porque no serían reconocidos.

El ciclo de vida de una variable determina el tiempo en que una variable permanece en
memoria. Una variable dentro de una función existe en memoria durante el tiempo en que
está ejecutándose dicha función. Una vez que termina su ejecución, sus variables y
parámetros desaparecen de la memoria y, por tanto, no pueden ser referenciados.

Pruebas Unitarias
Las pruebas de software son un conjunto de actividades diseñadas para verificar si el
sistema, o parte de él, cumple con los requisitos definidos y si no tiene defectos. Su objetivo
principal es identificar errores, brechas, requisitos faltantes o discrepancias con los
requisitos reales.

Dentro del amplio espectro de las pruebas de software, existen diferentes niveles de
prueba, cada uno con un alcance y propósito específicos:

● Pruebas Unitarias: Enfocadas en los componentes más pequeños y aislados del


código.
● Pruebas de Integración: Verifican cómo interactúan los diferentes módulos o
unidades cuando se combinan.
● Pruebas de Sistema: Evalúan el sistema completo para asegurar que cumple con los
requisitos funcionales y no funcionales.
● Pruebas de Aceptación: Realizadas por los usuarios finales o stakeholders para
validar que el sistema cumple con sus expectativas de negocio.

La importancia de las pruebas radica en su capacidad para:


● Detectar errores tempranamente: Cuanto antes se encuentra un defecto, más
económico y fácil es corregirlo.
● Mejorar la calidad del software: Asegurando que el producto final sea más fiable y
robusto.
● Reducir riesgos: Minimizando la probabilidad de fallos en producción.
● Generar confianza: Tanto para los desarrolladores como para los usuarios, al saber
que el software funciona como se espera.

¿Qué son las Pruebas Unitarias?


Las pruebas unitarias son el nivel más granular de pruebas de software. Consisten en
verificar pequeñas y aisladas unidades de código para asegurar que cada una de ellas se
comporta correctamente según su diseño. Una "unidad" puede ser una función, un método,
una clase, o cualquier componente lógico lo suficientemente pequeño como para ser
probado de forma independiente.

El objetivo fundamental de una prueba unitaria es responder a la pregunta: "¿Hace esta


parte específica del código exactamente lo que se supone que debe hacer, bajo todas las
condiciones relevantes?"

Características clave:

● Aislamiento: Cada unidad se prueba de forma independiente del resto del sistema.
Si una unidad depende de otra, se utilizan técnicas para "simular" o "sustituir" esas
dependencias (más sobre esto en la sección de conceptos avanzados).
● Automatización: Idealmente, las pruebas unitarias son automatizadas, lo que permite
ejecutarlas rápidamente y de forma repetida.
● Pequeño alcance: Se enfocan en un único punto de lógica.

Principios Clave de las Pruebas Unitarias (F.I.R.S.T.)

Para que las pruebas unitarias sean efectivas y valiosas, deben adherirse a ciertos
principios, a menudo resumidos con el acrónimo F.I.R.S.T.:

● Fast (Rápidas): Deben ejecutarse muy rápidamente. Un conjunto de miles de


pruebas unitarias debería completarse en segundos o, a lo sumo, en unos pocos
minutos. La lentitud desalienta su ejecución frecuente.
● Isolated/Independent (Aisladas/Independientes): Cada prueba debe poder ejecutarse
de forma independiente de las demás. El orden de ejecución de las pruebas no debe
afectar el resultado, y cada prueba debe configurar su propio entorno.
● Repeatable (Repetibles): Una prueba debe producir el mismo resultado cada vez
que se ejecuta, asumiendo que el código bajo prueba no ha cambiado. Esto significa
que no deben depender de factores externos como la hora del día, el entorno de red
o el estado de una base de datos externa.
● Self-Validating (Auto-validables): El resultado de la prueba debe ser binario: pasa o
falla, sin requerir intervención humana para interpretar los resultados. La prueba
debe indicar claramente si el comportamiento es el esperado o no.
● Timely (Oportunas): Las pruebas unitarias deben escribirse antes o al mismo tiempo
que el código que prueban. Esto es un pilar fundamental del Desarrollo Guiado por
Pruebas (TDD).

El Ciclo de Vida de una Prueba Unitaria (AAA)

Una prueba unitaria típica sigue un patrón de tres fases, a menudo conocido como AAA
(Arrange, Act, Assert):

● Arrange (Configurar/Preparar): En esta fase, se inicializa el estado necesario y los


objetos requeridos para la prueba. Esto puede incluir la creación de datos de
entrada, la configuración de variables o la instanciación de objetos. El objetivo es
tener todo listo para invocar la unidad bajo prueba.
● Act (Actuar/Ejecutar): Se ejecuta la unidad de código que se está probando,
utilizando los datos y el estado configurados en la fase de "Arrange". Aquí es donde
la función o el método que queremos validar es invocado.
● Assert (Verificar/Afirmar): Se verifica que el comportamiento de la unidad bajo
prueba es el esperado. Esto se hace comparando el resultado real de la ejecución
con el resultado esperado, o verificando que el estado del sistema ha cambiado de
la manera correcta. Si la condición de verificación no se cumple, la prueba falla.

Ejemplo Conceptual:
Imaginemos una función para sumar dos números.

// Arrange:
// Define los números que vamos a sumar.
// num1 = 5
// num2 = 3
// resultado_esperado = 8

// Act:
// Llama a la función de suma con los números definidos.
// resultado_actual = funcion_sumar(num1, num2)

// Assert:
// Verifica si el resultado actual es igual al resultado esperado.
// Afirma que resultado_actual == resultado_esperado

Beneficios Fundamentales de las Pruebas Unitarias

La adopción de pruebas unitarias trae consigo una multitud de beneficios que impactan
positivamente el ciclo de vida del desarrollo de software y la calidad del producto final:

● Detección Temprana de Defectos: Al probar pequeñas unidades de forma aislada,


los errores se encuentran y se corrigen en las etapas más tempranas del desarrollo.
Corregir un error en la fase de codificación es significativamente más barato que
hacerlo en producción.
● Mejora de la Calidad del Código: Fomenta la escritura de código modular, limpio y
bien diseñado, ya que el código difícil de probar suele ser un código mal diseñado.
Promueve la separación de responsabilidades.
● Documentación Implícita: Las pruebas unitarias sirven como una forma de
documentación "viva". Muestran cómo se espera que se use un componente y cuál
es su comportamiento para diferentes entradas.
● Facilita la Refactorización: Con un conjunto robusto de pruebas unitarias, los
desarrolladores pueden refactorizar el código (mejorar su estructura sin cambiar su
comportamiento externo) con la confianza de que si introducen un error, las pruebas
lo detectarán inmediatamente.
● Acelera el Desarrollo a Largo Plazo: Aunque inicialmente puede parecer que
ralentizan el desarrollo, a largo plazo, reducen el tiempo dedicado a la depuración y
a corregir errores en etapas posteriores, lo que resulta en un ciclo de desarrollo más
rápido y eficiente.
● Mayor Confianza en el Código: Los equipos tienen más confianza en los cambios
realizados en el código base, sabiendo que las pruebas capturarán cualquier
regresión inesperada.
● Depuración Simplificada: Cuando una prueba unitaria falla, el problema se localiza a
una pequeña sección de código, lo que facilita enormemente la depuración.

Cómo se Aplican las Pruebas Unitarias: Metodología y Ejemplos


Conceptuales

La aplicación de las pruebas unitarias implica escribir código específico para probar el
código de producción.
Metodología General:
1. Identificar la Unidad a Probar: Seleccionar la función, método o clase más pequeña
que realizará una tarea específica.
2. Definir Casos de Prueba: Para cada unidad, identificar diferentes escenarios:
○ Casos de Éxito: Entradas válidas que deberían producir el resultado
esperado.
○ Casos de Borde (Edge Cases): Valores mínimos/máximos, límites, cadenas
vacías, ceros, etc.
○ Casos de Error/Excepción: Entradas inválidas que deberían provocar errores
o excepciones predefinidas.
3. Escribir la Prueba:
○ Crear una función o método de prueba.
○ Dentro de esta función, seguir el patrón AAA (Arrange, Act, Assert).
○ Utilizar sentencias de afirmación (assertions) que verifican las condiciones
(ej: assert_equal(resultado_actual, resultado_esperado),
assert_true(condicion), assert_raises(TipoDeError, funcion_a_llamar)).
4. Ejecutar las Pruebas: Utilizar un test runner o una herramienta integrada que ejecute
todas las pruebas automáticamente e informe sobre cuáles pasaron y cuáles
fallaron.
5. Corregir Errores: Si una prueba falla, significa que la unidad de código bajo prueba
tiene un defecto. Se corrige el código de producción hasta que todas las pruebas
pasen.

Ejemplo Conceptual Detallado:


Imaginemos que tenemos una "unidad" de código que es una función para determinar si un
año es bisiesto.

// Función de producción (conceptual):


// funcion_es_bisiesto(año):
// Si año es divisible por 400, es bisiesto.
// Sino, si año es divisible por 100, NO es bisiesto.
// Sino, si año es divisible por 4, es bisiesto.
// Sino, NO es bisiesto.

// Prueba Unitaria 1: Año bisiesto divisible por 4 pero no por 100


// Arrange:
// año = 2024
// esperado = Verdadero (True)
// Act:
// resultado = funcion_es_bisiesto(año)
// Assert:
// Afirmar que resultado == esperado

// Prueba Unitaria 2: Año NO bisiesto divisible por 100 pero no por 400
// Arrange:
// año = 1900
// esperado = Falso (False)
// Act:
// resultado = funcion_es_bisiesto(año)
// Assert:
// Afirmar que resultado == esperado

// Prueba Unitaria 3: Año bisiesto divisible por 400


// Arrange:
// año = 2000
// esperado = Verdadero (True)
// Act:
// resultado = funcion_es_bisiesto(año)
// Assert:
// Afirmar que resultado == esperado

// Prueba Unitaria 4: Año NO bisiesto normal


// Arrange:
// año = 2023
// esperado = Falso (False)
// Act:
// resultado = funcion_es_bisiesto(año)
// Assert:
// Afirmar que resultado == esperado

Conceptos Relacionados y Avanzados


Aunque evitamos frameworks, es vital comprender conceptos que las pruebas unitarias a
menudo emplean:
● Desarrollo Guiado por Pruebas (TDD - Test-Driven Development):
○ Una metodología de desarrollo donde las pruebas unitarias se escriben antes
del código de producción.
○ Ciclo "Rojo-Verde-Refactorización":
1. Rojo: Escribir una prueba que falla (porque la funcionalidad aún no
existe).
2. Verde: Escribir el código de producción mínimo necesario para que
esa prueba pase.
3. Refactorizar: Mejorar el código (sin cambiar el comportamiento)
mientras todas las pruebas siguen pasando.
○ Promueve un diseño de código más limpio y modular.
● Mocks, Stubs y Fakes (Objetos de Prueba):
○ Cuando una unidad bajo prueba tiene dependencias (por ejemplo, una base
de datos, un servicio externo, una API compleja), no queremos que la prueba
unitaria dependa de que esas dependencias estén disponibles o de su
comportamiento real.
○ Los objetos de prueba (mocks, stubs, fakes) son objetos simulados que
imitan el comportamiento de las dependencias. Esto permite que la unidad se
pruebe de forma aislada y las pruebas sean rápidas y repetibles.
○ Mock: Un objeto que registra las interacciones y nos permite verificar que se
le llamó de una manera específica.
○ Stub: Un objeto que proporciona respuestas predefinidas a las llamadas
durante una prueba.
○ Fake: Una implementación ligera y simplificada de una dependencia real, útil
para pruebas.
● Cobertura de Código (Code Coverage):
○ Métrica que indica qué porcentaje del código de producción ha sido
ejecutado por las pruebas.
○ No garantiza la ausencia de errores, pero ayuda a identificar áreas del código
sin probar.
○ Existen herramientas que generan informes visuales de cobertura.

Desafíos Comunes y Consideraciones


A pesar de sus beneficios, la implementación de pruebas unitarias puede presentar
desafíos:
● Código Mal Diseñado: El código altamente acoplado y con muchas
responsabilidades mezcladas es muy difícil de probar unitariamente. Esto a menudo
lleva a la necesidad de refactorizar antes de probar.
● Dependencias Externas: Manejar bases de datos, APIs externas, sistemas de
archivos, etc., requiere el uso efectivo de mocks y stubs para mantener las pruebas
unitarias aisladas.
● Costo Inicial Percibido: Al principio, escribir pruebas puede parecer que ralentiza el
desarrollo. Sin embargo, este costo se recupera rápidamente al reducir los errores y
el tiempo de depuración.
● Mantenimiento de las Pruebas: Las pruebas deben evolucionar junto con el código
de producción. Pruebas desactualizadas o incorrectas pueden generar falsos
positivos o falsos negativos.
● Qué Probar y Qué No: No todo necesita una prueba unitaria. Enfoque en la lógica de
negocio compleja, los algoritmos críticos y las áreas propensas a errores. Las
pruebas deben tener un propósito claro.
Pruebas unitarias Frameworks
Un framework de pruebas unitarias es un conjunto de herramientas y bibliotecas que
facilitan la escritura y ejecución de pruebas unitarias para aplicaciones de software. Estas
pruebas se centran en verificar el correcto funcionamiento de unidades individuales de
código, como funciones o métodos, asegurando que cada parte de la aplicación opere
según lo esperado. Los frameworks de pruebas unitarias ofrecen una estructura y
funcionalidades predefinidas para organizar las pruebas, definir casos de prueba, ejecutar
las pruebas y generar informes

Beneficios:
Los Frameworks proporcionan una estructura clara para escribir y organizar pruebas, lo cual
nos ayuda a tener un mejor mantenimiento y desarrollo a largo plazo.

Permiten automatizar la ejecución de las pruebas, por lo que se ahorra tiempo y recursos en
comparacion de hacer la ejecución manual.

Deteccion temprana de errores, ya que se pueden identificar errores en etapas tempranas


del desarrollo, lo que reduce el riego de que los errores se propaguen a etapas posteriores,
es en esta parte en la que entran las pruebas de integración.

Las pruebas unitarias actuan como documentacion viva del codigo, mostrando como se
espera que funcione cada parte del codigo.

Mejoran la calidad del codigo, al probar cada unidad de codigo de forma aislada, se fomenta
una mayor calidad y robustez del código en general.

Ejemplo de frameworks de pruebas unitarias populares:

● JavaScript: Jest, Mocha, Jasmine.


● Java: JUnit, TextNG, Mockito.
● Python: Pytest, unittest.
● .NET: NUnit, [Link].
Pruebas unitarias de Python
El módulo unittest de Python está inspirado en JUnit, una popular herramienta de pruebas
en Java, y comparte muchas de sus características con los frameworks de testing más
conocidos en otros lenguajes. Permite automatizar pruebas, reutilizar configuraciones de
prueba, ejecutar código de limpieza tras cada test, agrupar pruebas en colecciones y
mantener la independencia de los tests respecto al sistema que muestra los resultados.

Para lograr esto, unittest se basa en algunos conceptos clave, organizados con un enfoque
orientado a objetos:

● Fixture o configuración de prueba:


Son los preparativos necesarios antes de ejecutar una o varias pruebas, como crear
bases de datos temporales, carpetas de trabajo o iniciar procesos que necesita la
prueba. También incluye la limpieza posterior.

● Caso de prueba (Test Case):


Es la unidad básica dentro de las pruebas. Evalúa si una función o parte del código
responde correctamente a entradas específicas. En unittest, se hereda de la clase
TestCase para crear estos casos.

● Conjunto de pruebas (Test Suite):


Es una colección que agrupa múltiples casos de prueba o incluso otros conjuntos de
pruebas. Se utiliza cuando se desea ejecutar varias pruebas de forma conjunta.

● Ejecutor de pruebas (Test Runner):


Es quien se encarga de ejecutar las pruebas y mostrar los resultados. Puede ser
una interfaz de línea de comandos, una interfaz gráfica o simplemente un valor que
indique si las pruebas pasaron o fallaron.

Ejemplo de prueba unitaria en Python:

tenemos una funcion de suma en una clase que se llama [Link]:

def sumar(a, b):

return a + b
Luego hacemos otro archivo que se llame test_calculadora.py:

import unittest

from calculadora import sumar

class TestCalculadora([Link]):

def test_sumar(self):

[Link](sumar(2, 3), 5)

if __name__ == '__main__':

[Link]()

Cuando ejecutamos esto:

----------------------------------------------------------------------

Ran 1 test in 0.000s

OK

Pero si modificamos la suma y que el resultado sea 6, nos sale este error:

F
======================================================================
FAIL: test_sumar (__main__.TestCalculadora)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_calculadora.py", line 6, in test_sumar
[Link](sumar(2, 3), 6)
AssertionError: 5 != 6

----------------------------------------------------------------------
Ran 1 test in 0.000s

FAILED (failures=1)
Conclusiones
1. Las pruebas unitarias optimizan el desarrollo de software al permitir probar
componentes individuales de forma aislada, reduciendo significativamente el tiempo
de ejecución comparado con probar la aplicación completa repetidamente, lo que
agiliza la entrega y producción del código.
2. Python ofrece frameworks robustos para testing como unittest y Pytest, que
proporcionan estructuras organizadas para crear, ejecutar y automatizar pruebas,
facilitando la implementación de metodologías como el patrón AAA (Arrange-Act-
Assert) y principios FIRST.
3. La calidad del código mejora sustancialmente con las pruebas unitarias, ya que
fomentan un diseño modular, detectan errores tempranamente, sirven como
documentación viva del código y permiten refactorizar con confianza, asegurando
que los cambios no introduzcan regresiones.
4. El aislamiento es fundamental en las pruebas unitarias, logrado mediante el uso de
mocks, stubs y fakes para simular dependencias externas, garantizando que las
pruebas sean rápidas, repetibles y auto-validables independientemente del entorno.
5. La inversión inicial en pruebas se recupera ampliamente a largo plazo, pues aunque
inicialmente puede parecer que ralentiza el desarrollo, reduce drásticamente el
tiempo dedicado a depuración y corrección de errores en etapas posteriores,
mejorando la mantenibilidad y confianza en el código.
Bibliografía
[Link]

[Link]

[Link]

También podría gustarte