我正在阅读(仍为测试版)prag progs 编写的 rspec 书 因为我对对象的行为测试感兴趣。从我到目前为止收集到的信息来看(警告:仅阅读了 30 分钟后),基本想法是我希望确保我的对象在“外部”表现符合预期,即在其输出中以及与其他对象的关系。
那么我是否应该只对我的对象进行黑盒测试以确保正确的输出/与其他对象的交互?
这可能是完全错误的,但考虑到所有的注意力都集中在我的对象在系统中的行为方式上,这似乎是人们会采取的意识形态。如果是这样,我们如何专注于对象的实现呢?如何测试我的私有方法是否正在为所有不同类型的输入执行我希望它执行的操作?
我想这个问题可能对所有类型的测试都有效?我对 TDD 和 BDD 还很陌生。
I'm reading through the (still beta) rspec book by the prag progs as I'm interested in behavioral testing on objects. From what I've gleaned so far (caveat: after only reading for 30 min), the basic idea is that I want ensure my object behaves as expected 'externally' i.e. in its output and in relation to other objects.
Is it true then that I should just be black box testing my object to ensure the proper output/interaction with other objects?
This may be completely wrong, but given all of the focus on how my object behaves in the system, it seems this is ideology one would take. If that's so, how do we focus on the implementation of an object? How do I test that my private method is doing what I want it to do for all different types of input?
I suppose this question is maybe valid for all types of testing?? I'm still fairly new to TDD and BDD.
发布评论
评论(3)
如果您想更好地理解 BDD,请尝试在不使用“测试”一词的情况下思考它。
您不需要编写测试,而是编写一个示例来说明如何使用您的类(并且除非通过公共方法,否则您不能使用它)。您将展示为什么您的课程对其他课程有价值。您正在定义类的职责范围,同时显示(通过模拟)在其他地方委派了哪些职责。
同时,您可以质疑职责是否适当,并调整类上的方法,使其尽可能直观可用。您正在寻找易于理解和使用的代码,而不是易于编写的代码。
如果您可以根据示例进行思考并通过行为提供价值,您将创建易于使用的代码,并提供其他人可以遵循的示例和描述。您将使您的代码安全且易于更改。如果你考虑测试,你就会把它固定下来,这样就没有人可以破坏它。你会让你很难改变。
如果它足够复杂以至于您确实想要单独测试某些内部方法,请将它们分解为另一个类,然后说明为什么该类很有价值以及它对使用它的类做了什么。
希望这有帮助!
If you want to understand BDD better, try thinking about it without using the word "test".
Instead of writing a test, you're going to write an example of how you can use your class (and you can't use it except through public methods). You're going to show why your class is valuable to other classes. You're defining the scope of your class's responsibilities, while showing (through mocks) what responsibilities are delegated elsewhere.
At the same time, you can question whether the responsibilities are appropriate, and tune the methods on your class to be as intuitively usable as possible. You're looking for code which is easy to understand and use, rather than code which is easy to write.
If you can think in terms of examples and providing value through behaviour, you'll create code that's easy to use, with examples and descriptions that other people can follow. You'll make your code safe and easy to change. If you think about testing, you'll pin it down so that nobody can break it. You'll make it hard to change.
If it's complex enough that there are internal methods you really want to test separately, break them out into another class then show why that class is valuable and what it does for the class that uses it.
Hope this helps!
我认为这里有两个问题。
一是从 BDD 角度来看,您通常在比 TDD 角度更高的级别进行测试。因此,您的 BDD 测试将断言比 TDD 测试更大的功能,并且应该始终是“黑盒”测试。
第二个是,如果您觉得需要测试私有方法,即使是在单元测试级别,这也可能是您的代码违反了 单一职责原则
并且应该重构,以便您关心的方法可以作为不同类的公共方法进行测试。 Michael Feathers 最近对此进行了一次有趣的演讲,名为“可测试性和良好设计之间的深层协同。”
I think there are two issues here.
One is that from the BDD perspective, you are typically testing at a higher level than from the TDD perspective. So your BDD tests will assert a bigger piece of functionality than your TDD tests and should always be "black box" tests.
The second is that if you feel the need to test private methods, even at the unit test level, that could be a code smell that your code is violating the Single Responsibilty Principle
and should be refactored so that the methods you care about can be tested as public methods of a different class. Michael Feathers gave an interesting talk about this recently called "The Deep Synergy Between Testability and Good Design."
是的,重点关注类的公开功能。私有方法只是您将测试的公共函数的一部分。这一点有点争议,但在我看来,测试一个类的公共功能应该足够了(其他一切也违反了 OOP 原则)。
Yes, focus on the exposed functionality of the class. Private methods are just part of a public function you will test. This point is a bit controversial, but in my opinion it should be enough to test the public functionality of a class (everything else also violates the OOP principle).