Django单元测试类和测试数据回滚
Django单元测试每个测试用例中写入数据库的测试数据在用例执行完后都会被撤销,这是通过事务回滚或者manage.py flush实现的。
TestCase与TransactionTestCase都是继承自SimpleTestCase,两者主要的区别在于:
- TestCase在测试开始时,判断当前连接的数据库是否支持事务特性,如支持,则开启事务操作;在测试结束时,同样判断是否支持事务特性,如支持,执行事务回滚,然后关闭所有链接。具体setUpClass与tearDownClass方法如下
@classmethoddef setUpClass(cls):super(TestCase, cls).setUpClass()if not connections_support_transactions(): # 事务支持判断returncls.cls_atomics = cls._enter_atomics() # 开启事务,TestCase中测试代码均处于此事务Block中if cls.fixtures:for db_name in cls._databases_names(include_mirrors=False):try:call_command('loaddata', *cls.fixtures, **{'verbosity': 0,'commit': False,'database': db_name,})except Exception:cls._rollback_atomics(cls.cls_atomics)raisecls.setUpTestData()@classmethod
def tearDownClass(cls):if connections_support_transactions(): # 事务支持判断cls._rollback_atomics(cls.cls_atomics) # 回滚所有操作for conn in connections.all(): # 关闭所有链接conn.close()super(TestCase, cls).tearDownClass()
- TransactionTestCase与TestCase不同,在此测试类中并不开启事务块,测试结束时通过进行Fush操作清空数据。此类没有重写SimpleTestCase的setUp和tearDown方法,只修改了_post_teardown等如下:
def _post_teardown(self):"""* 清空数据库的内容* 关闭链接"""try:self._fixture_teardown()super(TransactionTestCase, self)._post_teardown()if self._should_reload_connections():for conn in connections.all():conn.close()finally:if self.available_apps is not None:apps.unset_available_apps()setting_changed.send(sender=settings._wrapped.__class__,setting='INSTALLED_APPS',value=settings.INSTALLED_APPS,enter=False)def _fixture_teardown(self):for db_name in self._databases_names(include_mirrors=False):call_command('flush', verbosity=0, interactive=False,database=db_name, reset_sequences=False,allow_cascade=self.available_apps is not None,inhibit_post_migrate=self.available_apps is not None)
在事务方面的区别使得:使用TestCase时,如果被测试代码中出现必须在事务块中执行的代码,则会抛出异常,如官方举例的select_for_update():
class SampleTestCase(TestCase):def setUp(self):Sample.objects.create(**{'field1': 'value1, 'field2': 'value2'})def test_difference_testcase(self):sample = Sample.objects.select_for_update().filter()print(sample)class SampleTransactionTestCase(TransactionTestCase):def setUp(self):Sample.objects.create(**{'field1': 'value1, 'field2': 'value2'})def test_difference_transactiontestcase(self):sample = Sample.objects.select_for_update().filter()print(sample)
第一个TestCase会抛出异常:
AssertionError: TransactionManagementError not raised
第二个TTC会通过测试。
小结
- 使用TestCase,相当于后续代码都会处于一个外层事务的Block内执行,因此测试者不能测试必须运行在事务Block中的代码 (For instance, you cannot test that a block of code is executing within a transaction, as is required when using select_for_update())
- TestCase中,最终事务需要进行回滚,因此如果在测试代码中进行了conn.close()一类的操作将会引起异常
- TransactionTestCase不开启事务,并且通过测试结束时Flush DB的方案来还原干净环境
ref: https://blog.csdn.net/BDuck2014/article/details/86521755
Django单元测试类和测试数据回滚相关推荐
- java简单的事务单元_junit 单元测试事务自动回滚(亲测有效)
junit 单元测试事务会自动回滚.通过@Rollback(true)注解来实现,默认是true,事务会回滚,可以不写.false时事务不会回滚,数据会写到数据库中. 实例: package com. ...
- sqlsever回滚操作_sqlserver事务与回滚
如果要在Production执行数据改动必须小心,可以使用事务提前验证一下自己写的SQL是不是你期望的.尤其是Update的where 条件有问题的话,跟新的记录就会超出预期的范围.如下面的语句,一着 ...
- SpringBoot单元测试如何回滚测试数据
SpringBoot单元测试如何回滚测试数据 在做单元测试的时候,不想测试的数据保留在数据库,所以可以给测试类添加事务,让其回滚. 查了一下资料,网上说在方法前面添加@Transactional和@R ...
- java 单元测试_在springboot中写单元测试解决依赖注入和执行后事务回滚问题
往期文章 「Java并发编程」谈谈Java中的内存模型JMM 面试官:说说你知道多少种线程池拒绝策略 为什么不要在MySQL中使用UTF-8编码方式 前言 很多公司都有写单元测试的硬性要求,在提交代码 ...
- springboot 事务嵌套问题_在springboot中写单元测试解决依赖注入和执行后事务回滚问题...
往期文章 「Java并发编程」谈谈Java中的内存模型JMM 面试官:说说你知道多少种线程池拒绝策略 为什么不要在MySQL中使用UTF-8编码方式 前言 很多公司都有写单元测试的硬性要求,在提交代码 ...
- JUnit测试类完成后事务是默认 回滚的。只能查询数据,不能增删改。
JUnit测试类完成后事务是默认 回滚的.只能查询数据,不能增删改. 在测试类或者测试方法上面加上注解 @Rollback(false) 表示事物不回滚,这样数据就可以提交到数据库中了. 转载于:h ...
- Spring事务回滚和异常类
转载自 https://www.cnblogs.com/tianyuchen/p/6678084.html 1.异常的一些基本知识 异常的架构 异常的继承结构:Throwable为基类,Error和E ...
- Django 事务回滚
一.事务的四大特性 一般来说,事务是必须满足4个条件(ACID)::原子性(Atomicity,或称不可分割性).一致性(Consistency).隔离性(Isolation,又称独立性).持久性(D ...
- 单元测试JunitTest加@Transactional事务自动回滚
问题 在测试事务传播行为的时候,使用单位测试加了@Transactional,一开始是正常,后面出现了异常,即使没有报错的情况下,事务也会自动回滚 代码 @RunWith(SpringRunner.c ...
最新文章
- 10-1-直接插入排序-内部排序-第10章-《数据结构》课本源码-严蔚敏吴伟民版
- MyBatis之传入参数——parameterType(转)
- 2015华为校招机试题
- DCMTK:创建,编写和读取细分对象
- CF464E The Classic Problem(主席树+哈希+最短路)
- 构建持续交付_如何使交付成为您的重点将如何帮助您构建高质量的应用程序
- MySQL 修改和删除索引
- Android修改高度,android – 如何在运行时更改软键盘的高度?
- python 幅度和相位求复数_皮质运动兴奋性不受中央区mu节律相位的调节
- NVMe驱动详解系列_第一部:NVMe驱动初始化与注销
- Linux 常用的命令
- 华为笔试题 2022.3.30
- 普通IC、M1、UID、CUID、FUID、UFUID卡的区别
- 基于springboot网上书城系统
- 学习RPA-电商自动化入门①
- tplink怎样设置虚拟服务器,tplink怎么设置虚拟服务器
- Unity接TalkingData自动集成XCode
- python 中 while 语句的练习题
- TortoiseSVN patch 创建并应用补丁
- 海思SD3403开发板学习(一)