简体   繁体   English

回滚数据库的单元测试

[英]unit testing with rollback on database

I'm just starting to understand the importance of Unit Testing in ac# environment.我刚刚开始了解单元测试在 ac# 环境中的重要性。 Now, I'm wondering how do i implement a black-box unit test that does Inserts,Deletes and updates on a database and then cleaning up the data after a successful test.现在,我想知道如何实现对数据库执行插入、删除和更新的黑盒单元测试,然后在成功测试后清理数据。

How do you actually do a process that rollbacks data inserted/updated/deleted?您实际上如何执行回滚插入/更新/删除的数据的过程? do you simply reset the index and remove the inserted rows?您是否只是重置索引并删除插入的行? or restore the original state of the table by creating a script?或通过创建脚本恢复表的原始状态?

please guide me, I appreciate it.请指导我,我很感激。 thanks!谢谢!

What we do here in our development cycle. 我们在开发周期中做了什么。 we always have that unit testing and load testing in our mind when ever we are developing application. 当我们开发应用程序时,我们总是在脑海中进行单元测试和负载测试。 So we make a column in our every datadase's table with userId or else. 因此,我们使用userId或其他方法在每个数据库的表中创建一列。 Then when we run Load Test or Unit test we insert UserId -1 in that every column, pointing that it is a load test data and -2 in case of unit Test Data. 然后,当我们运行Load Test或Unit test时,我们在每列中插入UserId -1 ,指出它是负载测试数据,而在单元测试数据的情况下为-2 then we have pre Define Jobs at data base end that will clean that data after some time. 然后我们在数据库端预先定义作业,这将在一段时间后清理该数据。

As long as your test is concise, and i presume it must be - for testing your DAL, why not just do the insert / update / deletes in a transaction that is rolled back once your test is complete. 只要您的测试简洁,并且我认为它必须是 - 为了测试您的DAL,为什么不在测试完成后回滚的事务中执行插入/更新/删除操作。

Another option is to just use specific Update / Delete scripts in your test cleanup methods to roll back the exact changes that you updated / inserted to their pre-test values. 另一个选择是在测试清理方法中使用特定的更新/删除脚本来回滚您更新/插入到测试前测试值的确切更改。

I think deleting the rows in the CleanUp method should be good choice. 我认为删除CleanUp方法中的行应该是不错的选择。

By this you will always be testing your deleting rows code. 通过这种方式,您将始终测试删除行代码。

One option is to use a Mock database in place of a real database. 一种选择是使用Mock数据库代替真实数据库。 Here's a link that describes it. 这是一个描述它的链接

I was doing a research recently and found this thread as well.我最近在做研究,也发现了这个线程。 Here are my findings, which might be of some help for the future readers:以下是我的发现,可能对未来的读者有所帮助:

  • Make tests responsible for restoring the data they change.让测试负责恢复他们更改的数据。 Sth like undo for the command.就像撤销命令一样。 Tests usually know what data changes are expected, so are able to revert those in theory.测试通常知道预期的数据更改,因此能够在理论上还原这些更改。 This will surely involve additional work and could introduce some noise, unless it's automated, eg you might try to keep track of the data created/updated in the test somehow generally;这肯定会涉及额外的工作并可能引入一些噪音,除非它是自动化的,例如您可能会尝试以某种方式跟踪测试中创建/更新的数据;
  • Wrap each test in transaction and revert it afterwards.将每个测试包装在事务中,然后将其还原。 Pretty much as the one above, but easier to implement with things like TransactionScope.与上面的类似,但使用 TransactionScope 之类的东西更容易实现。 Might be not suitable if app creates own transactions as transactions aren't composable in general and if app doesn't work with TransactionScope (there are issues with Entity Framework for example);如果应用程序创建自己的事务,因为事务通常不可组合,并且应用程序不能与 TransactionScope 一起使用(例如,实体框架存在问题),则可能不合适;
  • Assert in some smart way on data relevant to test only.以某种智能方式断言仅与测试相关的数据。 Then you won't need to cleanup anything unless there is too much data.然后你不需要清理任何东西,除非数据太多。 Eg you might make your app aware of tests and set specific value to a test-only column added to every table.例如,您可以让您的应用了解测试并将特定值设置为添加到每个表的仅测试列。 I've never tried that in practice;我从未在实践中尝试过;
  • Create and initialize fresh database from scratch for every test;为每个测试从头开始创建和初始化新数据库;
  • Use database backups to restore database to the point you need;使用数据库备份将数据库恢复到您需要的点;
  • Use database snapshots for the restore;使用数据库快照进行还原;
  • Execute scripts to delete all the data and insert it again.执行脚本删除所有数据并重新插入。

I personally use the latter and even ended up implementing a Reseed library, which does all the work for me.我个人使用后者,甚至最终实现了一个Reseed库,它为我完成了所有工作。

Test frameworks usually do allow execute some logic before and after each test/test fixture run, which will mostlikely be needed for the ideas above.测试框架通常允许在每次测试/测试夹具运行之前和之后执行一些逻辑,这很可能是上述想法所需要的。 Eg for NUnit this implemented with use of OneTimeSetUp , OneTimeTearDown , FixtureSetUp , FixtureTearDown , SetUp , TearDown attributes.例如,对于 NUnit,这是使用OneTimeSetUpOneTimeTearDownFixtureSetUpFixtureTearDownSetUpTearDown属性实现的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM