NUnit:在单个测试中运行多个断言
我被要求编写一个测试应用程序,需要在数据库中的多行上测试新的存储过程,本质上我想做这样的事情:
[Test]
public void TestSelect()
{
foreach(id in ids)
{
DataTable old = Database.call("old_stored_proc",id);
DataTable new_ = Database.call("new_stored_proc",id);
Assert.AreEqual(old.Rows[0]["column"],ne_.Rows[0]["column"]);
}
}
当我运行此测试时,如果 1 行与另一行不匹配,整个测试失败; 相反,我想计算断言通过了多少次以及失败了多少次。 有没有办法用 NUnit 来做到这一点?
我意识到 NUnit 可能有点大材小用,如果没有它,这就是一个简单的任务......我只是想学习它。 ;)
I have been asked to write a testing application that needs to test a new stored procedure on multiple rows in a database, in essence I want to do something like this:
[Test]
public void TestSelect()
{
foreach(id in ids)
{
DataTable old = Database.call("old_stored_proc",id);
DataTable new_ = Database.call("new_stored_proc",id);
Assert.AreEqual(old.Rows[0]["column"],ne_.Rows[0]["column"]);
}
}
When I run this test, if 1 row doesn't match the other, the entire test fails; instead I would like to count how many times the assertion was passed and how many times it has failed. Is there a way to do this with NUnit?
I realize that NUnit might be overkill and this is a simple task without it...I just wanted to learn it. ;)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
我最近也遇到了同样的问题。 我将计数错误的想法与 Yann Trevin 提到的 Assert.Multiple 结合到了 IEnumberable 的扩展方法中,它可以让我执行以下操作:
导致 NUnit 输出:
OP 问题的解决方案是:
这是扩展方法(请注意,为了与 Linq 术语保持一致,我使用“全部”而不是“多个”):
I recently had the same issue. I combined the idea of counting errors with Yann Trevin's mention of Assert.Multiple into an extension method for IEnumberable that lets me do things like:
Which results in the NUnit output:
And the solution to the OP's problem would be:
Here is the extension method (note that I used "All" instead of "Multiple" for consistency with Linq terminology):
我会计算不匹配的行数,然后编写一个断言,将该数字与 0 进行比较,并返回消息中不匹配字符串的数量。
您还可以使用
Assert.Greater
来实现此目的。PS 原则上,您应该尝试为每个单元测试执行一个断言。 这就是它的要点。
I would count the number of rows which do not match and then would write an assertion which will compare this number with 0 and would return the number of non matching strings in the message.
you could also use
Assert.Greater
for this.P.S. In principal you should try to do one assertion per unit test. That's the gist of it.
您可以使用
[TestCase()]
属性如果是简单的硬编码 ID 列表。这将为每个 ID 生成三个单独的测试,并且您使用的任何 nunit 测试运行程序都将显示通过/失败计数。
如果需要生成动态 ID 列表,则建议使用
[TestCaseSource()]
属性。You can use
[TestCase()]
attribute if a simple hard coded list of IDs.This will generate three separate tests for each ID and whatever nunit test runner you use will display pass/fail counts.
If need to generate a dynamic list of IDs then recommend using
[TestCaseSource()]
attribute.那么,您可以声明一个计数器,然后断言计数器的值来确定通过/失败
此外,您可以在测试设置中完成大部分工作,然后创建多个测试。
我不清楚为什么您需要在同一测试中使用所有断言 stmt。
Well you could declare a counter and then assert the value of the counter to determine pass/fail
Also, you could do the bulk of the work in the test setup, and then just create multiple tests.
I'm not clear as to why you need all the assert stmts in the same test.
根据您制定的目标,如果一行与另一行不匹配,则整个测试应该失败。 与将预期结果与实际得到的结果进行比较相比,计算断言通过或失败的次数所提供的信息要少。
Based on the objective you laid out, the entire test should fail if one row doesn't match another. Counting the number of times an assertion passes or fails gives you less information than a comparison of the outcome you expected with the outcome you actually got.
我知道这个问题是专门关于 NUnit 的,但有趣的是, Gallio/MbUnit 有一个功能,允许运行和捕获多个立即断言。
Assert.Multiple
正在捕获所有失败的断言,并将在测试结束时报告它们。I know that the question is specifically about NUnit, but interestingly enough, Gallio/MbUnit has a feature which allows to run and catch several assertions at once.
The
Assert.Multiple
is catching all the failing assertions and is going to report them at the end of the test.看来你只是在断言错误的事情。 如果您想检查所有值,然后断言没有错误(或显示错误数量),请尝试以下操作:
Seems like you are just Asserting the wrong thing. If you want to check all the values and then assert that there are no errors (or show the number of errors) then try this:
1) 如果 id 是恒定的并且在测试运行时未查找,则为每个 id 创建一个单独的单元测试装置。 这样您就会知道哪些 id 实际上出现了故障。 请参阅此处有关数据驱动测试问题的文章:
http://googletesting.blogspot.com/2008/09/tott -data-driven-traps.html
2) 如果您需要动态查找 id,从而无法为每个 id 创建固定装置,请使用 akmad 的建议进行一项更改。 保留值不相等的 id 列表,并将该列表添加到错误消息中。 诊断仅指出错误数量的失败测试将非常困难,因为您不知道是什么 id 导致了错误。
3)我不知道在NUnit中做起来有多困难,但是在PyUnit中,当我们需要对动态生成的数据运行测试时,我们动态创建测试装置并将它们附加到TestCase类,这样我们就失败了对每一条不通过的数据进行测试。 不过我想如果没有 python 的动态能力,这会困难得多。
1) If the id's are constant and not looked up at test run time, create a separate unit test fixture for each id. That way you will know which id's are actually failing. See here for a write up on the problems with data driven tests:
http://googletesting.blogspot.com/2008/09/tott-data-driven-traps.html
2) If you need to dynamically look up the id's making it impossible to create a fixture for each id, use akmad's suggestion with one change. Keep a list of id's where the values are not equal and add the list to the error message. It will be extremely difficult to diagnose a failing test that only states the number of errors, as you won't know what id's cause the errors.
3) I don't know how difficult it would be to do in NUnit, but in PyUnit, when we need to run tests on dynamically generated data, we dynamically create tests fixtures and attach them to the TestCase class so that we have a failed test for each piece of data that does not pass. Though I imagine this would be much more difficult without python's dynamic abilities.