Почему запись в MySQL не сохраняется при запуске из unittest Python? - PullRequest
0 голосов
/ 03 августа 2020

В настоящее время я пишу тестовый пример для вновь созданной базы данных MySQL, используя unittest в Python 3.8. База данных представляет собой экземпляр AWS RDS, на котором запущена Aurora MySQL 5.6 - в нем есть таблица users с одним полем первичного ключа uuid VARCHAR(36). Тестовый пример выглядит следующим образом:

import unittest
import mysql.connector
from config import MYSQL_CONNECTION_INFO

class SQLSchemaTests(unittest.TestCase):
    """Verifies the correct behavior of the schema itself. (i.e. that the tables were set up correctly)"""
    
    def setUp(self):
        self.cnxn = mysql.connector.connect(**MYSQL_CONNECTION_INFO)
        self.cursor = self.cnxn.cursor()
        
    def tearDown(self):
        self.cnxn.close()
    
    def test_create_users(self):
        """Verify that a client can create user entries in the data store with appropriate parameters."""
        self.cursor.execute("SELECT COUNT(*) from users")
        user_entries_count = self.cursor.fetchone()[0]
        self.assertEqual(user_entries_count, 0)
        
        self.cursor.execute("INSERT INTO users (uuid) VALUES ('aaa-bbb-ccc-ddd-eee')")
        
        self.cursor.execute("SELECT COUNT(*) from users")
        user_entries_count = self.cursor.fetchone()[0]
        self.assertEqual(user_entries_count, 1)

Что меня смущает, так это то, что этот тестовый пример проходит каждый раз, когда он запускается - другими словами, без каких-либо действий по очистке с моей стороны он не терпит неудачу из-за повторяющихся записей. Я использовал отладчик PyCharm, чтобы разместить точку останова после оператора INSERT, а затем запустил SELECT COUNT(*) from users в отдельной консоли базы данных, пока выполнение теста было приостановлено: результат вернулся как ноль. Более того, когда я использовал консоль базы данных для записи идентичной записи в users таблицу , только тогда тест не удался из-за повторяющейся записи.

Я хотел бы знайте следующее:

  • Почему операторы INSERT в модульном тесте не сохраняются в таблице? Это вызвано коннектором MySQL, unittest или чем-то еще?
  • Какие правила определяют, как это происходит? При каких обстоятельствах такое поведение гарантируется?
  • Есть ли официальная документация, которая могла бы прояснить эти моменты?

1 Ответ

1 голос
/ 03 августа 2020

Чтобы увидеть, что вставка сохраняется между тестами, мне нужно было добавить self.cnxn.commit() после того, как я вызвал execute в операторе INSERT: Python документы коннектора указывают, что автоматическая фиксация отключено по умолчанию.

Более того, причина, по которой я мог получить обновленный счетчик из в тесте, но не из отдельной консоли базы данных, связана с изоляцией транзакции на уровне базы данных (в данном случае - REPEATABLE-READ). Более подробная информация доступна в MySQL документах и в статье Википедии об изоляции в базах данных.

...