在 Python 中模拟一个 MySQL 数据库
Mock a MySQL database in Python
我使用来自 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")
我现在想为我的应用程序编写测试代码,我想在每个测试用例的 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)")
我一直在谷歌搜索,发现了一些关于 SQLite
和 MySQLdb
的事情。我有以下问题:
sqlite3
或MySQLdb
是否适合在内存中快速创建数据库?
- 如何在 Anaconda 包中安装
MySQLdb
?
- 是否有在
setUp
中创建的测试数据库示例?这是个好主意吗?
我的计算机本地没有 MySQL 服务器 运行。
pymysql、MySQLdb 和 sqlite 都需要一个真正的数据库来连接。
如果你只想测试你的代码,你应该在你想要测试的模块上模拟 pymysql 模块,并相应地使用它
(在您的测试代码中:您可以将模拟对象设置为 return 硬编码结果到预定义的 SQL 语句)
查看本机 Python 模拟库的文档,网址为:
https://docs.python.org/3/library/unittest.mock.html
或者,对于 Python 2:
https://pypi.python.org/pypi/mock
您可以使用 testing.mysqld (pip install testing.mysqld
)
模拟 mysql 数据库
由于一些noisy error logs that crop up,我在测试时喜欢这个设置:
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
我使用来自 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")
我现在想为我的应用程序编写测试代码,我想在每个测试用例的 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)")
我一直在谷歌搜索,发现了一些关于 SQLite
和 MySQLdb
的事情。我有以下问题:
sqlite3
或MySQLdb
是否适合在内存中快速创建数据库?- 如何在 Anaconda 包中安装
MySQLdb
? - 是否有在
setUp
中创建的测试数据库示例?这是个好主意吗?
我的计算机本地没有 MySQL 服务器 运行。
pymysql、MySQLdb 和 sqlite 都需要一个真正的数据库来连接。 如果你只想测试你的代码,你应该在你想要测试的模块上模拟 pymysql 模块,并相应地使用它 (在您的测试代码中:您可以将模拟对象设置为 return 硬编码结果到预定义的 SQL 语句)
查看本机 Python 模拟库的文档,网址为: https://docs.python.org/3/library/unittest.mock.html
或者,对于 Python 2: https://pypi.python.org/pypi/mock
您可以使用 testing.mysqld (pip install testing.mysqld
)
由于一些noisy error logs that crop up,我在测试时喜欢这个设置:
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