单元测试:在设置方法中进行断言是一个好习惯吗?

发布于 2024-08-04 07:04:09 字数 539 浏览 2 评论 0原文

在单元测试中,setup方法用于创建测试所需的对象。

在这些设置方法中,我喜欢使用断言:我知道我想在这些设置中看到什么值 对象,我喜欢通过断言来记录这些知识。

在最近的一篇关于 在 stackoverflow 上调用其他单元测试的单元测试,一般的感觉似乎是单元测试不应该调用其他测试: 这个问题的答案似乎是你应该重构你的设置,所以 测试用例不相互依赖。

但是“setup-with-asserts”和“setup-with-asserts”没有太大区别 单元测试调用其他单元测试。

因此我的问题是:在设置方法中进行断言是一个好的做法吗?

编辑:

答案是:这通常不是一个好的做法。如果需要测试设置结果,建议添加单独的带有断言的测试方法(我勾选的答案);为了记录意图,请考虑使用 Java 断言。

In unit testing, the setup method is used to create the objects needed for testing.

In those setup methods, I like using assertions: I know what values I want to see in those
objects, and I like to document that knowledge via an assertion.

In a recent post on unit tests calling other unit tests here on stackoverflow, the general feeling seems to be that unit tests should not call other tests:
The answer to that question seems to be that you should refactor your setup, so
that test cases do not depend on each other.

But there isn't much difference in a "setup-with-asserts" and a
unit test calling other unit tests.

Hence my question: Is it good practice to have assertions in setup methods?

EDIT:

The answer turns out to be: this is not a good practice in general. If the setup results need to be tested, it is recommended to add a separate test method with the assertions (the answer I ticked); for documenting intent, consider using Java asserts.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

娇女薄笑 2024-08-11 07:04:09

我没有使用设置中的断言来检查结果,而是使用了一个简单的测试(与其他方法一起使用的测试方法,但定位为第一个测试方法)。

我看到了几个优点:

  • 设置保持简短和集中,以提高可读性。
  • 断言仅运行一次,效率更高

使用和讨论

例如,我将方法命名为 testSetup()。

要使用它,当我在该类中出现一些测试错误时,我知道如果 testSetup() 有错误,我不需要担心其他错误,我需要先修复这个错误。

如果有人对此感到困扰,并且想要明确此依赖关系,则可以在 setup() 方法中调用 testSetup()。但我认为这并不重要。我的观点是,在 JUnit 中,您已经可以在其余测试中拥有类似的东西:

  1. 一些测试测试本地代码,
  2. 一些测试调用更多全局代码,这些代码间接调用与先前测试相同的代码。

当您读取两者都失败的测试结果时,您已经必须处理不在测试中但在被调用的代码中的依赖关系。您必须首先修复简单测试,然后重新运行全局测试以查看是否仍然失败。
这就是为什么我不为之前解释的隐式依赖所困扰的原因。

Instead of assertions in the setup to check the result, I used a simple test (a test method along the others, but positionned as first test method).

I have seen several advantages:

  • The setup keeps short and focused, for readability.
  • The assertions are run only once, which is more efficient.

Usage and discussion :

For example, I name the method testSetup().

To use it, when I have some test errors in that class, I know that if testSetup() has an error, I don't need to bother with the other errors, I need to fix this one first.

If someone is bothered by this, and wants to make this dependency explicit, the testSetup() could be called in the setup() method. But I don't think it matters. My point is that, in JUnit, you can already have something similar in the rest of your tests:

  1. some tests that test local code,
  2. and some tests that is calls more global code, which indirectly calls the same code as the previous test.

When you read the test result where both fail, you already have to take care of this dependency that is not in the test, but in the code being called. You have to fix the simple test first, and then rerun the global test to see if it still fails.
This is the reason why I'm not bothered by the implicit dependency I explained before.

§对你不离不弃 2024-08-11 07:04:09

它们是不同的场景;我没有看到相似之处。

设置方法应该包含(理想情况下)夹具中所有测试通用的代码。因此,如果在执行其余测试代码之前某些事情必须为真,那么将断言放入测试设置方法中并没有本质上的错误。该设置是测试的延伸;它是整个测试的一部分。如果断言失败,人们就会发现哪个先决条件失败了。

另一方面,如果设置足够复杂,以至于您觉得需要断言它是正确的,那么这可能是一个警告信号。此外,如果所有测试不需要设置的完整输出,则表明夹具的内聚性较差,应根据场景进行拆分和/或重构。

部分原因是我倾向于避免使用安装方法。在可能的情况下,我使用私有工厂方法或类似的方法来进行设置。它使测试更具可读性并避免混淆。有时这是不切实际的(例如,使用紧密耦合的类和/或编写集成测试时),但对于我的大多数测试来说,它可以完成工作。

They're different scenarios; I don't see the similarity.

Setup methods should contain code that is common to (ideally) all tests in a fixture. As such, there's nothing inherently wrong with putting asserts in a test setup method if certain things must be true before the rest of the test code executes. The setup is an extension of the test; it is part of the test as a whole. If the assert trips, people will discover which pre-requisite failed.

On the other hand, if the setup is complicated enough that you feel the need to assert it is correct, it may be a warning sign. Furthermore, if all tests do not require the setup's full output, then it is a sign that the fixture has poor cohesion and should be split up based on scenarios and/or refactored.

It's partly because of this that I tend to stay away from using Setup methods. Where possible, I use private factory methods or similar to set things up. It makes the test more readable and avoids confusion. Sometimes this is not practical (e.g. working with tightly coupled classes and/or when writing integration tests), but for the majority of my tests it does the job.

你的背包 2024-08-11 07:04:09

不建议在 Setup/TearDown 方法中使用断言。如果用户需要“理解”某些测试逻辑不在测试方法中,则会降低测试的可读性。
有时,您别无选择,只能将设置/拆卸方法用于其预期目的以外的用途。

这个问题有一个更大的问题:一个测试调用另一个测试,这是测试中某些问题的味道。
每个测试都应该测试代码的一个特定方面,并且应该只包含一个或两个断言,因此如果您的测试调用另一个测试,您可能会在该测试中测试太多的东西。
有关更多信息,请阅读:Unit测试:一项测试,一项断言 - 为什么它有效

Having assertions in the Setup/TearDown methods is not advisable. It makes the test less readable if the user needs to "understand" that some of the test logic is not in the test method.
There are times when you do not have a choice but to use the setup/teardown methods for something other than what they where intended for.

There is a bigger issue in this question: a test that calls another test, it is a smell for some problem in your tests.
Each test should test a specific aspect of your code and should only have one or two assertions in it, so if your test calls another test you might be testing too many things in that test.
For more information read: Unit Testing: One Test, One Assertion - Why It Works

逆流 2024-08-11 07:04:09

跟随你的心/眨眼的决定。设置方法中的断言可以记录意图;提高可读性。所以我个人会支持你这一点。
它与调用其他测试的测试不同 - 这很糟糕。没有测试隔离。一项测试不应影响另一项测试的结果。

虽然这不是一个频繁的用例,但我有时在设置方法中使用断言,以便我可以知道测试设置是否没有按照我的预期进行;通常当我处理不是我自己编写的组件时。断言失败,显示“安装失败!”在错误选项卡中 - 快速帮助我专注于设置代码,而不必查看一堆失败的测试。

设置失败通常会导致该装置中的所有测试失败 - 您的鼻子很快就会闻到这种气味。 “所有测试失败通常意味着安装程序损坏”,因此并不总是需要断言。也就是说,要务实,看看您的具体情况并“添加到口味”。

Follow your heart / Blink decisions. Asserts within a Setup method can document intent ; improver readability. So personally I'd back you up on this.
It is different from a test calling other tests - which is bad. No test isolation. A test should not influence the outcome of another test.

Although it is not a freq use-case, I sometimes use Asserts inside a Setup method so that I can know if test setup has not taken place as I intended it to; usually when I'm dealing with components that I didn't write myself. An Assertion failure which reads 'Setup failed!' in the errors tab - quickly helps me zone in on the setup code instead of having to look at a bunch of failed tests.

A Setup failure usually should cause all tests in that fixture to fail - which is a smell that your nose should soon pickup. 'All tests failed usually implies Setup broke ' So assertions are not always needed. That said be pragmatic, look at your specific context and 'Add to taste.'

楠木可依 2024-08-11 07:04:09

在需要此类操作的情况下,我使用 Java 断言,而不是 JUnit 断言。例如,当您使用其他一些实用程序类来设置测试数据时:

byte[] pkt = pktFactory.makePacket(TIME, 12, "23, F2");
assert pkt.length == 15;

失败意味着“系统甚至没有处于尝试运行此测试的状态”。

I use Java asserts, rather than JUnit ones, in the cases where something like this is necessary. e.g. when you use some other utility class to set up test data.:

byte[] pkt = pktFactory.makePacket(TIME, 12, "23, F2");
assert pkt.length == 15;

Failing has the implication 'system is not in a state to even try to run this test'.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文