Ответ
Тестирование банкомата — комплексная задача, охватывающая функциональность, безопасность, надежность и юзабилити.
1. Функциональное тестирование (Основные сценарии)
- Аутентификация:
- Ввод корректного/некорректного PIN-кода.
- Блокировка карты после 3 неудачных попыток.
- Работа с истекшей или заблокированной картой.
- Операции с балансом:
- Запрос баланса (отображение, валюта, маскирование данных).
- Выдача наличных: корректная сумма, комиссия, недостаток средств в счете/банкомате.
- Внесение наличных: прием купюр, подсчет, зачисление на счет.
- Дополнительные услуги: Переводы между счетами, оплата услуг, смена PIN-кода.
2. Тестирование безопасности
- Защита от скимминга: Обнаружение посторонних устройств на кард-ридере.
- Шифрование данных: Защита PIN-кода (должен никогда не передаваться в открытом виде).
- Физическая безопасность: Реакция на вскрытие корпуса, датчики движения.
- Логирование и аудит: Невозможность удаления или подмены журнала операций.
3. Нагрузочное и тестирование надежности
- Пиковая нагрузка: Одновременное обслуживание нескольких карт (очередь запросов).
- Длительная работа: Стабильность при сотнях операций подряд.
- Восстановление после сбоев: Отключение питания во время выдачи денег (должен произойти откат транзакции).
- Работа с периферией: Отказ принтера чеков, датчика купюр, сетевого соединения.
4. Интеграционное тестирование
- Взаимодействие с процессинговым центром: Корректное формирование и парсинг ISO-8583 сообщений (или иного протокола).
- Сверка остатков (Settlement): Ежедневная сверка сумм в банкомате с операциями в core-банковской системе.
Пример тест-кейса для выдачи наличных:
import pytest
def test_cash_withdrawal_success(atm, valid_card):
"""Успешная выдача средств со счета, имеющего достаточный баланс."""
initial_balance = valid_card.get_balance()
withdrawal_amount = 5000
# Аутентификация
assert atm.authenticate(valid_card, correct_pin="1234") is True
# Выполнение операции
result = atm.withdraw_cash(withdrawal_amount)
# Проверки
assert result["status"] == "SUCCESS"
assert result["dispensed_amount"] == withdrawal_amount
assert valid_card.get_balance() == initial_balance - withdrawal_amount - result["fee"]
assert atm.get_cash_balance() == initial_cash_in_atm - withdrawal_amount
# Проверка записи в логе
assert atm.last_transaction_id() in valid_card.get_statement()
def test_cash_withdrawal_insufficient_funds(atm, valid_card):
"""Попытка снять сумму, превышающую баланс счета."""
valid_card.set_balance(1000)
atm.authenticate(valid_card, correct_pin="1234")
with pytest.raises(ATMException, match="Insufficient funds"):
atm.withdraw_cash(5000)
# Баланс не должен измениться
assert valid_card.get_balance() == 1000
5. Юзабилити и Accessibility
- Интерфейс: Ясность инструкций, поддержка нескольких языков.
- Доступность: Высота и наклон экрана, поддержка аудио-инструкций для слабовидящих, тактильная клавиатура.