用Python模拟MySQL数据库

phy*_*ion 10 python mysql sqlite mysql-python pymysql

我使用Anaconda发行版的Python 3.4.在这个发行版中,我发现该pymysql库连接到现有的MySQL数据库,该数据库位于另一台计算机上.

import pymysql
config = {
      'user': 'my_user',
      'passwd': 'my_passwd',
      'host': 'my_host',
      'port': my_port
    }

    try:
        cnx = pymysql.connect(**config)
    except pymysql.err.OperationalError : 
        sys.exit("Invalid Input: Wrong username/database or password")
Run Code Online (Sandbox Code Playgroud)

我现在想为我的应用程序编写测试代码,我希望在setUp每个测试用例中创建一个非常小的数据库,最好是在内存中.但是,当我尝试使用pymysql它时,它无法建立连接.

def setUp(self):
    config = {
      'user': 'test_user',
      'passwd': 'test_passwd',
      'host': 'localhost'
    }
    cnx = pymysql.connect(**config)

pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'localhost' ([Errno 61] Connection refused)")
Run Code Online (Sandbox Code Playgroud)

我一直在谷歌搜索,并发现了一些关于SQLiteMySQLdb.我有以下问题:

  1. sqlite3MySQLdb适合在内存中快速创建数据库?
  2. 如何MySQLdb在Anaconda包中安装?
  3. 是否有一个测试数据库的例子,在setUp?这甚至是个好主意吗?

我的计算机上没有本地运行的MySQL服务器.

Rom*_*man 14

您可以使用testing.mysqld ( pip install testing.mysqld)模拟 mysql 数据库

由于出现了一些嘈杂的错误日志,我在测试时喜欢这个设置:

import testing.mysqld
from sqlalchemy import create_engine

# prevent generating brand new db every time.  Speeds up tests.
MYSQLD_FACTORY = testing.mysqld.MysqldFactory(cache_initialized_db=True, port=7531)


def tearDownModule():
    """Tear down databases after test script has run.
    https://docs.python.org/3/library/unittest.html#setupclass-and-teardownclass
    """
    MYSQLD_FACTORY.clear_cache()


class TestWhatever(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.mysql = MYSQLD_FACTORY()
        cls.db_conn = create_engine(cls.mysql.url()).connect()

    def setUp(self):
        self.mysql.start()
        self.db_conn.execute("""CREATE TABLE `foo` (blah)""")

    def tearDown(self):
        self.db_conn.execute("DROP TABLE foo")

    @classmethod
    def tearDownClass(cls):
        cls.mysql.stop()  # from source code we can see this kills the pid

    def test_something(self):
        # something useful
Run Code Online (Sandbox Code Playgroud)


jsb*_*eno 6

pymysql,MySQLdb和sqlite都需要一个真正的数据库连接.如果你只想测试你的代码,你应该只模拟你要测试的模块上的pymysql模块,并相应地使用它(在你的测试代码中:你可以设置模拟对象以将硬编码结果返回到预定义的SQL语句)

查看本机Python模拟库的文档:https: //docs.python.org/3/library/unittest.mock.html

或者,对于Python 2:https: //pypi.python.org/pypi/mock

  • 对于未来的读者:这是Docker容器的用例.它简化了这种类型的集成测试,并且不难找到支持文档. (4认同)
  • 这似乎不可能是我想要的.我的目标不是模拟pymysql,因为我想测试代码是否适用于"真正的"SQL数据库.如果它具有MySQL的所有特性并不重要,但它应该能够通过pymysql进行通信.在我运行测试的每台机器上本地安装MySQL服务器是不切实际的. (2认同)
  • SQLite*是一个"真正的"数据库,而不是pymysql和MySQLdb,它们只是MySQL的连接器. (2认同)