测试依赖于 NUnit 的常用功能
我有一些初始化代码来使用我的 API。初始化可能会失败,我想在 NUnit 测试中测试它。
初始化之后就可以使用API了。我也在测试 API,但我所有的测试方法都将使用相同的、通用的初始化代码。
我理想的情况是如果出现以下行为:
- 运行初始化测试。
- 如果 [1] 成功,则运行其他测试。
在 [1] 失败的所有情况下,所有其他测试也会失败。但有价值的信息是[1]失败了。这就是我最有可能发现问题的地方。如果其他测试可以用 ? 标记,那就太好了。或其他东西,表明它们没有执行,因为它们所依赖的功能没有通过测试。
我知道测试不应该是脆弱的。但我无法回避这样一个事实:初始化代码对于正确执行其他功能是必需的。
这是一个更普遍的问题,其中某些功能依赖于其他功能。 “其他功能”过于常用,无法通过依赖它的所有测试来提供任何实际价值。如果“其他功能”单独测试会更好。
I have some initialization code to use my API. The initialization may fail and I´d like to test it in an NUnit test.
After the initialization the API may be used. I´m testing the API too, but all my test methods will use the same, common, initialization code.
What I would ideally like is if this behavior:
- The Initialization test is run.
- The other tests are run if [1] succeeded.
In all cases where [1] will fail, so will all other tests. But the valuable information is that [1] fails. That's where I most likely will find the problem. It would be nice if the other tests could be marked with ? or something, indicating that they did not execute as functionality they depend on didn't pass the tests.
I know that tests should not be brittle. But I can't get around the fact that the initialization code is necessary for correct execution of other functionality.
This is a more general problem where some functionality depends on other functionality. Where the "other functionality" is far too commonly used to provide any real value by failing all tests depending on it. It would be better if the "other functionality" would be tested separately.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
好的,这就是我将如何解决这个问题...
将公共初始化放入安装方法中,因为所有测试都需要它。如果初始化抛出错误,您会看到
如果这对您来说太隐晦,您可以(尽管我不建议这样做)向同一个套件添加一个具有好名称的空测试。如果该测试显示为绿色,则可以确定安装/通用初始化代码已成功。
更新:看来你有一个相当利基的要求。我不知道 NUnit 中是否有任何机制来指定此类测试的条件执行 - 例如,仅当 Test1 通过时才运行 Test2 至 10。
OK here's how I would go about this...
Put the common initialization into a Setup method since its needed for all tests. If initialization throws an error, you'd see
If this is too implicit for you, you may (although I wouldn't recommend it) add an empty test with a good name to the same suite. If that test shows up as green, you can be sure that Setup / common init code has succeeded.
Update: Seem like you have a pretty niche requirement. I don't know of any mechanism in NUnit to specify such conditional execution of tests - e.g. Run Test2 thru 10 only if Test1 passes.
我一直在与 NUnit 开发人员保持联系。如果不编写一个相当复杂的插件,目前这是不可能的。该功能将出现在 3.x 代码库中的某个位置,但不会出现在 2.5 中。我会考虑写,但暂时不会。
I've been in contact with the NUnit developers. It's not possible at the moment without writing a pretty complex plugin. The feature will turn up somewhere in the 3.x code base but will not appear in 2.5. I will consider writing it, but not for the time being.
试试这个:
将“初始化测试”定义为测试用例
使所有其他测试成为此测试用例的子类
创建一个以某种特定顺序运行测试的套件,以便您的“初始化测试”位于第一个。
Try this:
Define the "Initialization test" as a TestCase
Make all your other tests a subclass of this TestCase
Create a Suite which runs your tests in some specific order so that your "Initialization test" is first.
我认为这非常明确。问题是您很难区分 API 职责。你有两个。 API的初始化和API的执行。编写具有这种依赖性的测试可能会杀了你。
因此,我建议 API 创建一个初始化对象,然后创建各种命令对象来执行 API。命令对象将存储在某种存储中,或者您可以动态创建。
API 将使用模拟的初始化对象,并将使用模拟的命令对象。
除了您需要初始化的内容之外,初始化对象实际上没有任何依赖项。
命令对象将需要一个模拟的初始化对象。
[编辑]
如果初始化测试失败,有两种方法可以让其他测试失败
向测试用例添加私有变量。
私有 isInitialized = false;
。然后所有其他测试都会检查该变量的状态,如果不为 true,则失败。使用 API 类扩展您的测试用例。添加询问初始化状态的私有函数。
两者中更干净的是 2。最快的实现是 1。
恕我直言当您必须以这种方式耦合测试时,这可能会产生代码味道。如果正如你所说,这是一个集成测试。为什么要单独测试初始化。集成更多的是针对您的 API 运行一些操作。因此,每个集成测试都必须初始化 API。
您可能需要重新考虑级联故障场景。完成测试时噪音可能太大。
[EDIT1a]
我认为满足您的要求的唯一方法是扩展 NUnit。具体研究测试用例生成器和测试装饰器。
该链接的日期为 2008 年 3 月,因此希望它不会过时。
I think that this pretty clear cut. The problem is that you're having a hard time separating out your API responsibilities. You have two. Initialization of API and API execution. Writing your tests to have this kind of dependency can kill you.
So I would recommend that the API create an initialization object and then various command objects to execute the API. The command objects will be in some kind of store or you could create on the fly.
The API will use a mocked initialization object and it will use mocked command objects.
The Initialization Object really doesn't have any dependencies except for whatever you need to initialize.
The Command objects will need a mocked initialization object.
[EDIT]
There are two way to get the other tests to fail if the initialization test fails
Add a private variable to the test case.
private isInitialized = false;
. Then all your other tests check the state of this variable if not true then fail.Extend your test case with the API class. Add private function that interrogate state of initialization.
The cleaner of the two is 2. The fastest implementation is 1.
IMHO This can be a code smell when you have to couple your tests in such a manner. If as you said it is an integration tests. Why do you have a separate test for initialization. Integration is more along the lines of run some action against your API. So each integration test MUST initialize the API.
You might want to rethink your cascade failure scenario. It might be too much noise at completion of tests.
[EDIT1a]
The only way I can see to satisfy your requirements is to extend NUnit. Specifically look into Test Case Builders and Test Decorators.
The link is dated March 2008, so hopefully it isn't to out of date.