No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Cómo usar el método setup en tests de Python

5/20
Recursos

El uso del método setup en los tests permite simplificar y evitar la duplicación de código en las pruebas. Al iniciar un test, setup se ejecuta automáticamente, preparando el entorno para cada prueba de forma eficiente. En este caso, pasamos de un proyecto de calculadora a uno de una cuenta bancaria, y veremos cómo implementar pruebas unitarias para depósitos, retiros y consultas de saldo utilizando setup para optimizar el código.

¿Cómo implementar pruebas para depósitos en una cuenta bancaria?

Primero, se crea la clase de test donde se probarán los métodos de una cuenta bancaria. Para hacer un depósito, se debe instanciar una cuenta con un saldo inicial, realizar el depósito y luego validar que el saldo ha cambiado correctamente.

Pasos:

  • Crear el archivo test_bank_account.py.
  • Instanciar una cuenta con saldo inicial.
  • Probar que el método de depósito ajusta el saldo correctamente.

¿Cómo optimizar las pruebas con el método setup?

El método setup evita la creación repetitiva de instancias en cada test. Para lograr esto:

  • Se crea una instancia de cuenta en setup.
  • La cuenta creada se comparte entre todas las pruebas usando self.

Esto simplifica las pruebas al evitar duplicar el código de instanciación en cada método de test.

¿Cómo ejecutar las pruebas de retiro y consulta de saldo?

Para las pruebas de retiro y consulta de saldo:

  • El método withdraw debe restar la cantidad del saldo y validar que el resultado sea correcto.
  • El método get_balance simplemente valida que el saldo actual coincida con lo esperado.

Estas pruebas se benefician del uso de setup, ya que reutilizan la misma instancia de cuenta creada para cada prueba.

¿Cómo ejecutar pruebas con salida más detallada?

Al ejecutar las pruebas, es útil utilizar el comando con la opción -b para obtener una salida más detallada y visualizar exactamente qué pruebas se están ejecutando y dónde están ubicadas en el código. Esto ayuda a depurar y tener un mejor control sobre el flujo de las pruebas.

¿Cómo crear pruebas para una nueva funcionalidad de transferencia?

La tarea final consiste en agregar un método de transferencia a la clase BankAccount, el cual debe:

  • Permitir transferir saldo entre cuentas.
  • Levantar una excepción si el saldo no es suficiente para realizar la transferencia.

Luego, se deben crear dos pruebas unitarias:

  1. Validar que la transferencia se realiza correctamente.
  2. Validar que se lanza una excepción cuando no hay saldo suficiente para completar la transferencia.

Aportes 18

Preguntas 1

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

“El código se lee más de lo que se escribe” es uno de los mejores consejos que se pueden dar cuando estás aprendiendo a programar y por eso lo rescato de esta clase.
```js def test_transfer(self): target_account = BankAccount(balance=500) new_balance = self.account.transfer(500, target_account) assert new_balance == 500 assert target_account.balance == 1000 def test_transfer_not_enough_balance(self): target_account = BankAccount(balance=500) with self.assertRaises(ValueError): self.account.transfer(1500, target_account) ```
Para ir a la documentación o archivo donde se implementa la clase TestCase como lo hace el profesor, pueden hacerlo en VScode con Ctrl + Click en la clase TestCase o clase que deseen buscar su referencia
```js import unittest from src.bank_account import BankAccount class BankAccountTests(unittest.TestCase): def test_deposit(self): # Inicializa cuenta coon saldo = 1000 account = BankAccount(balance=1000) new_balance = account.deposit(500) # Nuevo balance es igual a 1500 self.assertEqual(new_balance, 1500) def test_withdraw(self): account = BankAccount(balance=1000) new_balance = account.withdraw(200) self.assertEqual(new_balance, 800) def test_get_balance(self): account = BankAccount(balance=3000) account.deposit(3000) account.withdraw(1000) actual_balance = account.get_balance() self.assertEqual(actual_balance, 5000) ```import unittestfrom src.bank\_account import BankAccount class BankAccountTests(*unittest*.TestCase): def test\_deposit(*self*): # Inicializa cuenta coon saldo = 1000 account = BankAccount(*balance*=1000) new\_balance = account.deposit(500) # Nuevo balance es igual a 1500 *self*.assertEqual(new\_balance, 1500) def test\_withdraw(*self*): account = BankAccount(*balance*=1000) new\_balance = account.withdraw(200) *self*.assertEqual(new\_balance, 800) def test\_get\_balance(*self*): account = BankAccount(*balance*=3000) account.deposit(3000) account.withdraw(1000) actual\_balance = account.get\_balance() *self*.assertEqual(actual\_balance, 5000)
```js class BankAccount: # Inicia con saldo en cero def __init__(self, balance=0): self.balance = balance def deposit(self, amount): self.balance += amount return self.balance def withdraw(self, amount): if amount > 0: self.balance -= amount return self.balance def get_balance(self): return self.balance def transfer(self, amount, target): if self.balance < amount: raise ValueError("No hay fondos suficientes") self.withdraw(amount) target.deposit(amount) # Tests import unittest from src.bank_account import BankAccount class BankAccountTests(unittest.TestCase): # Definir setup ,para no repetir código def setUp(self): self.account = BankAccount(balance=1000) def test_deposit(self): new_balance = self.account.deposit(500) # Nuevo balance es igual a 1500 self.assertEqual(new_balance, 1500) def test_withdraw(self): new_balance = self.account.withdraw(200) self.assertEqual(new_balance, 800) def test_get_balance(self): self.account.deposit(3000) self.account.withdraw(1000) actual_balance = self.account.get_balance() self.assertEqual(actual_balance, 3000) def test_success_transfer(self): target = BankAccount(balance=500) self.account.transfer(200, target) # Balance cuenta emisora self.assertEqual(self.account.get_balance(), 800) # Balance cuenta receptora self.assertEqual(target.get_balance(), 700) def test_insufficient_funds_transfer(self): target = BankAccount(balance=500) with self.assertRaises(ValueError) as context: self.account.transfer(2000, target) self.assertEqual(str(context.exception), "No hay fondos suficientes") ```class BankAccount: # Inicia con saldo en cero def \_\_init\_\_(*self*, *balance*=0): *self*.balance = *balance* def deposit(*self*, *amount*): *self*.balance += *amount* return *self*.balance def withdraw(*self*, *amount*): if *amount* > 0: *self*.balance -= *amount* return *self*.balance def get\_balance(*self*): return *self*.balance def transfer(*self*, *amount*, *target*): if *self*.balance < *amount*: raise ValueError("No hay fondos suficientes") *self*.withdraw(*amount*) *target*.deposit(*amount*)
Clase ```python class BankAccount: def __init__(self, balance=0): self.balance = balance def deposit(self, amount): if amount > 0: self.balance += amount return self.balance raise ValueError("Invalid deposit amount") def withdraw(self, amount): if 0 < amount <= self.balance: self.balance -= amount return self.balance raise ValueError("Invalid withdraw amount") def get_balance(self): return self.balance def transfer(self, account, amount): if 0 < amount <= self.balance: self.balance -= amount account.deposit(amount) return self.balance raise ValueError("Invalid transfer amount") ```Test ```python from unittest import TestCase from src.BankAccount import BankAccount class BankAccountTests(TestCase): def setUp(self): self.account = BankAccount(1000) def test_deposit(self): self.account.deposit(500) assert self.account.get_balance() == 1500 def test_withdraw(self): self.account.withdraw(500) assert self.account.get_balance() == 500 def test_withdraw_fail(self): with self.assertRaises(ValueError): self.account.withdraw(1500) def test_get_balance(self): assert self.account.get_balance() == 1000 def test_transfer(self): account2 = BankAccount(500) self.account.transfer(account2, 500) assert self.account.get_balance() == 500 assert account2.get_balance() == 1000 def test_transfer_fail(self): with self.assertRaises(ValueError): account2 = BankAccount(500) self.account.transfer(account2, 2000) ```
```python #Archivo bank_account def send_money(self,amount): if self.balance >= amount: new_balance = self.balance - amount return new_balance if self.balance < amount: raise ValueError("Fondos insuficientes") ```    ```python #archivo test_bank_account def test_send_money(self): new_balance = self.account.send_money(1500) assert new_balance == 500 ```
Paso mi intento de solución: ```js def transfer(self, amount, other): if amount <= self.balance: other.deposit(amount) self.withdraw(amount) else: raise ValueError("Not enough balance") return self.balance ```    y ahora los tests: ```js def test_transfer_success(self): new_account = BankAccount(balance=1000) new_balance = self.account.transfer(500, new_account) assert new_balance == 500 and new_account.balance == 1500 def test_transfer_not_enough_balance(self): new_account = BankAccount(balance=1000) with self.assertRaisesRegex(ValueError, 'Not enough balance'): self.account.transfer(1500, new_account) ```
Quise usar `pytest `para ver la diferencias y este es el resultado: ```python import pytest from src.bank_account import BankAccount @pytest.fixture def setup_account(): return BankAccount(balance=1000) # Balance inicial común para todas las pruebas def test_deposit(setup_account): new_balance = setup_account.deposit(250) assert new_balance == 1250 # Balance inicial (1000) + depósito (250) def test_withdraw(setup_account): setup_account.deposit(4000) # 1000 + 4000 = 5000 new_balance = setup_account.withdraw(2000) assert new_balance == 3000 # Balance esperado después de retirar def test_get_balance(setup_account): assert setup_account.get_balance() == 1000 # Verifica el balance inicial ```
Para realizar el reto cree un nuevo metodo, que recibe amount y account, hace una verificacion y resta los fondos de acount1 y los deposita a account 2 Test: ```python def test_transfer(self): account2 = BankAccount(balance=500) new_balance = self.account.transfer(500, account2) assert new_balance == 1500 assert account2.get_balance() == 1000 ```Metodo: ```js def transfer(self, amount, account): if amount > 0 and self.balance >= amount: self.withdraw(amount) account.deposit(amount) return self.balance ```def transfer(self, amount, account):        if amount > 0 and self.balance >= amount:            self.withdraw(amount)            account.deposit(amount)        return self.balance
Este es mi archivo `bank_account.py`: ```js class BankAccount(): def __init__(self, account_number, owner, balance=0): self.account_number = account_number self.owner = owner self.__balance = balance def deposit(self, amount): if amount > 0: self.__balance += amount print(f'Deposited {amount} USD. New balance is {self.__balance} USD') else: print('You must deposit at least 1 USD.') return self.__balance def withdraw(self, amount): if amount > 0: if amount <= self.__balance: self.__balance -= amount print(f'Withdrew {amount} USD. New Balance is {self.__balance} USD.') else: print(f'Insufficient funds.') else: print(f'You must withdraw at least 1 USD.') return self.__balance def transfer(self, amount, target): if self.__balance < amount: raise ValueError('Insufficient funds.') self.withdraw(amount) target.deposit(amount) def get_balance(self): return self.__balance ```
Mi respuesta al desafio ```python class BankAccount: def __init__(self, balance=0): self.balance = balance def deposit(self, amount): if amount > 0: self.balance += amount return self.balance def withdraw(self, amount): if amount >0: self.balance -= amount return self.balance def get_balance(self): return self.balance def transfer(self, amount): if self.balance < amount: raise Exception("Saldo insuficiente") self.balance -= amount return self.balance ```class BankAccount:        def \_\_init\_\_(self, balance=0):        self.balance = balance        def deposit(self, amount):        if amount > 0:            self.balance += amount        return self.balance     def withdraw(self, amount):        if amount >0:            self.balance -= amount        return self.balance        def get\_balance(self):        return self.balance     def transfer(self, amount):        if self.balance < amount:            raise Exception("Saldo insuficiente")        self.balance -= amount        return self.balance````python import unittest from src.bank_account import BankAccount class BankAccountTests(unittest.TestCase): def setUp(self) -> None: self.account = BankAccount(balance=1000) def tests_deposit(self): new_balance = self.account.deposit(500) assert new_balance == 1500 def tests_withdraw(self): new_balance = self.account .withdraw(500) assert new_balance == 500 def tests_get_balance(self): assert self.account .get_balance() == 1000 def tests_transfer(self): new_balance = self.account.transfer(amount=200) assert new_balance == 800 ```import unittest from src.bank\_account import BankAccount class BankAccountTests(unittest.TestCase):        def setUp(self) -> None:        self.account = BankAccount(balance=1000)        def tests\_deposit(self):        new\_balance = self.account.deposit(500)        assert new\_balance == 1500        def tests\_withdraw(self):        new\_balance = self.account .withdraw(500)        assert new\_balance == 500        def tests\_get\_balance(self):        assert self.account .get\_balance() == 1000        def tests\_transfer(self):        new\_balance = self.account.transfer(amount=200)        assert new\_balance == 800 ````
\*\*\*\*\*\*\*\*\*\*\* En los recursos de la clase existe un error \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* Al ejecutar las pruebas, es útil utilizar el comando con la opción `-b` (acá debería ser `-v` )**** para obtener una salida más detallada y visualizar exactamente qué pruebas se están ejecutando y dónde están ubicadas en el código. Esto ayuda a depurar y tener un mejor control sobre el flujo de las pruebas.
Tratando de "Hacerlo simple" me embole todo así, que trate de hacerlo de una manera más realista que es restar de una cuenta para añadir a otra. Aquí mi solución al retoclass     ```python class BankAccount: def __init__(self, balance): self.balance = balance def deposit(self, amount): if amount > 0: self.balance += amount return self.balance def withdraw(self, amount): if amount > 0: self.balance -= amount return self.balance def transfer(self, amount, target_account): if amount > 0 and self.balance >= amount: self.balance -= amount target_account.deposit(amount) else: raise ValueError("No tienes saldo suficiente para transferir") return self.balance def get_balance(self): return self.balance ``` ```python import unittest from src.bank_account import BankAccount class BankAccountTest(unittest.TestCase): def setUp(self) -> None: self.account = BankAccount(balance = 1000) self.target_account = BankAccount(balance=500) def test_deposit(self): new_balance = self.account.deposit(500) assert new_balance == 1500 def test_withdraw(self): new_balance = self.account.withdraw(500) assert new_balance == 500 def test_transfer(self): self.account.transfer(200, self.target_account) self.assertEqual(self.account.get_balance(), 800) self.assertEqual(self.target_account.get_balance(), 700) def test_get_balance(self): assert self.account.get_balance() == 1000 ```
```python python -m unittest discover -v -s tests ``` (ojo con esto porque ejecuta los test de raíz si solo ponemos "test" sin s al final) (ojo con esto porque ejecuta los test de raíz si solo ponemos "test" sin s al final)
Solamente agrego una pequeña función donde indico que se puede transferir únicamente si el monto a transferir a mayor o igual al balance: ```python # ----- Código de la cuenta de banco ----- class BankAccount: def __init__(self, balance=0): self.balance = balance def deposit(self, amount): if amount > 0: self.balance += amount return self.balance def withdraw(self, amount): if amount > 0: self.balance -= amount return self.balance def get_balance(self): return self.balance def transfer(self, amount): if self.balance >= amount: self.balance = self.balance - amount else: print("Fondos insuficientes.") return self.balance # ----- Código de las pruebas ----- import unittest from src.bank_account import BankAccount class BankAccountTests(unittest.TestCase): def setUp(self) -> None: self.account = BankAccount(balance=1000) def test_deposit(self): new_balance = self.account.deposit(500) assert new_balance == 1500 def test_withdraw(self): new_balance = self.account.withdraw(200) assert new_balance == 800 def test_get_balance(self): assert self.account.get_balance() == 1000 def test_transfer(self): new_balance = self.account.transfer(700) assert new_balance == 300 ```
Aqui mi solución al reto: ```python class BankAccount: def __init__(self,balance=0): self.balance = balance def deposit(self, amount): if amount > 0: self.balance += amount return self.balance def withdraw(self, amount): if amount > 0: self.balance -= amount return self.balance def get_balance(self): return self.balance def transfer(self, amout, account_number): if amout > self.balance: raise InsufficientFunds("No tienes fondos para realizar esta transferencia") elif len(account_number) < 10: raise AccountNumberNotValid("El número de cuenta debe de ser mayor o igual a 10 digitos") else: self.balance = self.balance - amout return print(f'Se tranfirio la cantidad {amout} al número de cta {account_number}. El balance de la cuenta es {self.balance}') class InsufficientFunds(Exception): def __init__(self, mensaje): self.mensaje = mensaje super().__init__(self.mensaje) class AccountNumberNotValid(Exception): def __init__(self, mensaje): self.mensaje = mensaje super().__init__(self.mensaje) #Test: import unittest from src.bank_account import BankAccount class BankAccount_test(unittest.TestCase): def setUp(self) -> None: self.account = BankAccount(1000) def test_deposit(self): account = self.account.deposit(500) assert account == 1500 def test_withdraw(self): account = self.account.withdraw(500) assert account == 500 def test_get_balance(self): account = self.account.get_balance() assert account == 1000 def test_transfer(self): account = self.account.transfer(500,'12345678901') assert account == f'Se tranfirio la cantidad {500} al número de cta {12345678901}. El balance de la cuenta es {500}' ```class BankAccount: def \_\_init\_\_(self,balance=0): self.balance = balance def deposit(self, amount): if amount > 0: self.balance += amount return self.balance def withdraw(self, amount): if amount > 0: self.balance -= amount return self.balance def get\_balance(self): return self.balance def transfer(self, amout, account\_number): if amout > self.balance: raise InsufficientFunds("No tienes fondos para realizar esta transferencia") elif len(account\_number) < 10: raise AccountNumberNotValid("El número de cuenta debe de ser mayor o igual a 10 digitos") else: self.balance = self.balance - amout return print(f'Se tranfirio la cantidad {amout} al número de cta {account\_number}. El balance de la cuenta es {self.balance}') class InsufficientFunds(Exception): def \_\_init\_\_(self, mensaje): self.mensaje = mensaje super().\_\_init\_\_(self.mensaje) class AccountNumberNotValid(Exception): def \_\_init\_\_(self, mensaje): self.mensaje = mensaje super().\_\_init\_\_(self.mensaje)
Comparto mi solución al reto. ```js def transfer(self,amount): if amount > 0 and amount <= self.balance: self.balance -= amount else: raise ValueError('Saldo insuficiente') return self.balance ``````js def test_transfer(self): new_balance = self.account.transfer(1000) assert new_balance == 0 def test_transfer_insufficient_funds(self): with self.assertRaises(ValueError): self.account.transfer(1001) ```