我正在创建一个使用开放式并发控制的Django库,以防止并发写入导致数据不一致。 我希望能够为此功能编写单元测试,但不确定如何实现。
我知道Django的单元测试是单线程的,所以我可以设想测试工作的唯一方法是同时打开两个单独的数据库连接(到同一数据库),并切换执行查询时Django ORM使用哪个连接,尽管我 我不确定在Django中是否还可以进行连接切换。
使用Django测试并发数据库操作有哪些技术?
What are some techniques for testing concurrent database operations with Django?
实际上,Django在这里不是问题。
用于乐观并发控制的库必须可以作为独立单元进行测试。
在Django之外;仅使用unittest。
您需要使用多线程(和多处理)测试驱动程序进行测试。在Django之外。
一旦确定可以使用,就可以在Django内部进行测试,以确保API可以正常使用。
一旦确定所有功能都能正常运行,就应该编写一个简单的urllib2测试驱动程序,该驱动程序针对单独的Django服务器执行大量并发事务。我们编写了一个小工具,它可以启动Django服务器,使用urllib2运行测试,然后终止Django服务器。
从根本上讲,您将需要某种相当正式的证据来证明您的想法有效。这比任何测试都重要得多。
我的库指定了一个抽象模型,该模型创建以下形式的查询:update table_name set field_name = value, revision = (old_revision + 1) where id = record_id and revision = old_revision。 它利用Django的ORM。 真正的并发控制是通过行级锁在数据库级实现的。 单元测试将确保查询正确生成,并且数据库后端提供适当的并发处理。 唯一的测试方法是将并发请求发送到测试服务器是否正确?
@shanked:"真正的并发控制是通过行级锁在数据库级实现的。" 听起来像您在测试并发性。 对? 如果是这样,则需要发出并发请求以测试并发性。 我没有实际进行并发性的任何方法来测试并发性。
实际上,测试并发技术是否有效几乎是不可能的。错过一个小的比赛条件非常容易。唯一的真实方法是证明您的代码,但是,这是很多工作;)
一种解决方法是在指向同一数据库的单独进程中生成Django runserver的多个副本。然后,您的单元测试将生成线程/进程,并且它们都在行使您的并发性的运行服务器上崩溃。在拆卸期间,您将参与所有过程。
使用gevent:
import gevent
def foo():
print('Running in foo')
gevent.sleep(0)
print('Explicit context switch to foo again')
def bar():
print('Explicit context to bar')
gevent.sleep(0)
print('Implicit context switch back to bar')
gevent.joinall([
gevent.spawn(foo),
gevent.spawn(bar),
])
Running in foo
Explicit context to bar
Explicit context switch to foo again
Implicit context switch back to bar
http://sdiehl.github.io/gevent-tutorial/