ATDD 与 BDD 以及框架的正确使用
我刚刚开始了解 BDD 的概念,并且已经听了 Scott Bellware 与 Herding Code 人员的演讲。我一直在尝试使用 SpecFlow,并且非常喜欢它。
我理解博客文章 对 BDD 工具进行分类(单元测试驱动与验收测试驱动)以及一些 BDD 历史,但这让我想到了一个问题。
如上所述,使用 BDD 工具(例如 MSpec)不就是另一种单元测试框架吗?在我看来确实如此。
此外,这似乎表明使用 SpecFlow 来指定较低级别的组件(例如您的存储库和服务)是错误的。如果我可以对较低级别组件的 ATDD 和 TDD 使用相同的工具,为什么不应该呢?这里似乎还有一些模糊的界限,我觉得我不太明白。
I am just getting into the concept of BDD and have listened to Scott Bellware's talk with the Herding Code guys. I have been playing around with SpecFlow some and like it pretty well.
I understand the distinction between ATDD and TDD as described in the blog post Classifying BDD Tools (Unit-Test-Driven vs. Acceptance Test Driven) and a bit of BDD history, but that leads me to a question.
As described, isn't using a BDD tool (such as MSpec) just another unit testing framework? It seems to me that it is.
Furthermore, this seems to suggest that using SpecFlow to spec out the lower level components (such as your repositories and services) would be wrong. If I can use the same tool for both ATDD and TDD of lower level components, why shouldn't I? There seems to still be some blurry lines here that I feel like I'm not quite understanding.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
快速回答
需要提出的非常重要的一点是,行为驱动开发有两种风格。这两种风格是xBehave和 >x规格。
xBehave BDD:SpecFlow
SpecFlow(与 Ruby 堆栈中的 cucumber 非常相似)在促进 xBehave 方面非常出色BDD 测试作为验收标准。然而,它并没有提供在单元级别编写行为测试的好方法。还有其他一些 xBehave 测试框架,但 SpecFlow 已经获得了很大的关注。
xSpec BDD:NSpec
对于单元级别的行为驱动开发,我建议 NSpec (直接受到 RSpec for Ruby) 的启发。您可以通过简单地使用 NUnit 或 MSTest 在单元级别上完成 BDD...但它们有点不足(增量构建上下文真的很难)。 MSpec 也是一个选项,已经投入了大量的工作它,但有些东西在 NSpec 中更简单(您可以在 MSpec 中增量构建上下文,但它需要继承,这可能会变得复杂)。
长答案
BDD 的两种风格之所以存在,主要是因为它们提供了正交的好处。
xBehave(GWT 语法)的优点和缺点 优点
。
缺点
xSpec(上下文/规范)的优点和缺点 优点
允许
缺点
示例
Bowling Kata 是一个很好的例子。
SpecFlow 示例
以下是 SpecFlow 中的规范(同样,这非常适合作为验收测试,因为它直接与业务进行通信):
Feature File
功能文件是测试的常用方言。
Step Definition File
的映射
步骤定义文件是测试的实际执行,该文件包括 SpecFlow NSpec Sample、xSpec、Context/Specification
这是一个 NSpec 相同保龄球型的示例:
所以是的...SpecFlow 很酷,NSpec 很酷
随着您做越来越多的 BDD,您会发现 BDD 的 xBehave 和 xSpec 风格需要。 xBehave 更适合验收测试,xSpec 更适合单元测试和领域驱动设计。
相关链接
The Quick Answer
One very important point to bring up is that there are two flavors of Behavior Driven Development. The two flavors are xBehave and xSpec.
xBehave BDD: SpecFlow
SpecFlow (very similar to cucumber from the Ruby stack) is excellent in facilitating xBehave BDD tests as Acceptance Criteria. It does not however provide a good way to write behavioral tests on a unit level. There are a few other xBehave testing frameworks, but SpecFlow has gotten a lot of traction.
xSpec BDD: NSpec
For behavior driven development on a unit level, I would recommend NSpec (inspired directly by RSpec for Ruby). You can accomplish BDD on a unit level by simply using NUnit or MSTest...but they kinda fall short (it's really hard to build up contexts incrementally). MSpec is also an option, there has been a lot of work put into it, but there are just somethings that are just simpilier in NSpec (you can build up context incrementally in MSpec, but it requires inheritance which can become complex).
The Long Answer
The two flavors of BDD primarily exist because of the orthogonal benefits they provide.
Pros and Cons of xBehave (GWT Syntax)
Pros
Cons
Pros and Cons of xSpec (Context/Specification)
Pros
Cons
Samples
The Bowling Kata is a pretty good example.
SpecFlow Sample
Here is what the specification would look like in SpecFlow (again, this is great as an acceptance test, because it communicates directly with the business):
Feature File
The feature file is the common dialect for the test.
Step Definition File
The step definition file is the actual execution of the test, this file includes the mappings for SpecFlow
NSpec Sample, xSpec, Context/Specification
Here is a NSpec example of the same bowling kata:
So Yea...SpecFlow is cool, NSpec is cool
As you do more and more BDD, you'll find that both the xBehave and xSpec flavors of BDD are needed. xBehave is more suited for Acceptance Tests, xSpec is more suited for unit tests and domain driven design.
Relevant Links
真正的行为驱动工具类似于 Cucumber。我们在工作中针对 .NET 代码使用它。这使我们能够编写定义整个系统行为的功能,然后我们可以执行这些功能并验证系统是否符合我们的预期。整个过程对我们来说非常有效。
http://cukes.info/
有一个名为 NStep 的 .net 实现,它通过有线协议连接到 cucumber,它允许您使用 lambda 在 C# 中编写步骤定义...这非常棒。
步骤定义如下所示:
http://github.com/clearwavebuild/nStep
A true behavior driven tool would be something like Cucumber. We use it at my job against .NET code. This allows us to write features that define behavior of the system as a whole and we can then execute the features and verify that the system does what we expect. The whole process works very well for us.
http://cukes.info/
There is a .net implementation called NStep that connects to cucumber via the wire protocol, it allows you to write step definitions in C# using lambdas...its pretty awesome.
Step definitions look like this:
http://github.com/clearwavebuild/nStep
我想你的理解和我的一致。 BDD 更适合集成测试,通常作为最终用户测试您的系统,例如:
没有理由不在更细粒度的级别对您的存储库进行单元测试。我认为两者都是有用且合适的。
I think your understanding is in line with mine. BDD is more suited for integration testing and generally tests your system as the end user, eg:
There is no reason to not to unit test your repositories at a more granular level. I think both are useful and appropriate.
我不能只使用普通的单元测试工具吗?
BDD 是一种过程和心态,所以,是的,您可以使用任何工具来完成(或者不使用,如果您愿意,您可以在没有工具的情况下编写自己的工具)。然而,TDD 工具有某些假设,当尝试以 BDD 方式做事时,这些假设会导致一些摩擦。例如,TDD 假设您正在测试软件的架构单元;类、模块、服务。而 BDD 假设您正在指定系统的某些功能部分。
我应该使用 SpecFlow/Cucumber 来描述较低级别的组件吗?
首先,我认为这个问题有点误导。您不会倾向于描述组件,除非这些组件直接表示行为。我仍然会回答我认为问题的实质所在。
像 Cucumber 这样的面向故事的工具非常适合从客户/用户的角度讨论行为。它可以让您制定外行人容易理解的规范。然而,使用这些工具描述大量或复杂的状态可能很乏味。
在处理复杂或大型状态设置时,单元测试或更多面向代码的规范工具(例如 rSpec 和 Machine.Specification)可能会方便得多。您可以使用该语言可用的各种工具来管理状态。诸如继承和伪造/模拟之类的东西。 Machine.Specification 对于具有 .NET 思维的人来说有一些很好的方法。
那么,您应该使用 Cucumber 来指定较低级别的行为吗?我想说,只有当对特定行为具有高水平的可见性很重要时。在我当前的项目中,我们开发了一个架构组件来表示系统的某些业务规则密集部分。这些组件是用 Cucumber 指定的,但大部分系统是用 NUnit 覆盖的。
顺便说一句,对于刚刚接触 BDD 的 .NET 人员来说,SpecFlow 确实非常好且平易近人,但最终您会希望升级到成熟的 Cucumber+nStep。 Cucumber 生态系统庞大且很有帮助。 SpecFlow 的尺寸要小得多。
此外,nStep 提供的 lambda 语法比必须像 SpecFlow 或 Cuke4Nuke 那样装饰方法要好得多。
免责声明/背景:
我在 nStep 上进行了一些原始开发,但我在当前的项目中使用 SpecFlow。我正在努力在这里介绍 BDD,并且需要一些简单易懂的东西。
Can't I just use normal unit testing tools?
BDD is a process and mentality and so, yes, you can do it with any tools (or not, you can write your own without a tool if you want). However, the TDD tools had certain assumptions which cause some friction when trying to do things in a BDD way. For instance, TDD assumes you are testing an architectural unit of the software; class, module, service. Whereas BDD assumes you are specifying some functional portion of the system.
Should I use SpecFlow/Cucumber to describe lower-level components?
First of all, I think the question is a bit misguided. You wouldn't tend to describe components unless those components directly represent behavior. I'll still answer what I believe the spirit of the question is.
Story oriented tools like Cucumber are great for talking about behavior from a customer/user perspective. It can allow you to make specifications that are easily approachable by laymen. However, it can be tedious to describe large amounts or complex state with those tools.
Unit testing, or more code oriented specification tools like rSpec and Machine.Specification, can be a lot more convenient when dealing with complex or large state setups. You can use the various tools available to the languages to manage the state. Things like inheritance and fakes/mocks. Machine.Specification has some good approaches to this for the .NET minded.
So, should you use Cucumber to specify lower-level behavior? I'd say only if its important to have high levels of visibility for that particular behavior. On my current project, we've developed an architectural component to represent certain business-rule intensive portions of the system. Those components are specified with Cucumber, but the majority of system is covered with NUnit.
Btw, SpecFlow is really nice and approachable for .NET folks just getting into BDD, but eventually you'll want to graduate to full-blown Cucumber+nStep. The Cucumber ecosystem is HUGE and helpful. SpecFlow's is much smaller.
Also, the lambda syntax offered by nStep is quite a bit nicer than having to decorate methods a la SpecFlow or Cuke4Nuke.
Disclaimer/Background:
I did some of the original development on nStep but I'm using SpecFlow on my current project. I'm working to introduce BDD here and needed something simple and approachable.
有趣的是,这个关于 BDD 工具分类的博客讨论了 TDD 和 ATDD。正如 Liz Keogh 指出的:BDD 是关于对话和探索。所有参与人员越容易做出贡献、交流意图、分享想法、理解他人等,我们就能越快获得适当的解决方案并构建更好的软件。当我们最终遵循工具路径时,最能支持软件项目利益相关者之间协作的工具是什么?
基于 这篇关于 TDD、BDD 之间差异的博客,和 ATDD 我想说,至少有三种不同风格的 BDD 工具:
JUnit 改变了我们对开发和测试的看法。它的优点之一是可以使用与应用程序本身相同的编程语言来编写测试。因此,我们可以利用交付团队已有的知识。当测试甚至被用来驱动开发时,我们就到达了 TDD 的天堂。
编程语言已经过优化以减少冗余,罗恩·杰弗里斯认为这是开发人员最严重的罪过之一。因此,在进行技术测试时,我们经常依赖这些工具来正确构建产品,因为它们可以帮助我们提高效率。
有几个人试图让自动化测试更容易理解,因为单元测试并不真正可读。最初的尝试之一是解析单元测试并提供非开发人员也可读的简洁摘要。例如 TestDox / AgileDox 从 JUnit 测试类的方法名称或 Pickels 基于用 Gherkin 编写的功能文件生成文档。
MSpec 等框架有助于编写更具可读性的测试,并另外提供可读输出。这些 BDD 工具侧重于人类可读的输出,这使得非开发人员能够在开发人员完成工作后参与进来。
为了在开发周期的早期让利益相关者参与,创建了新的工具更多地关注可读的输入。 Cucumber 利用纯文本文件为自动化测试提供人类可读的输入。文本文件包含以基于给定-当时-当时结构的特殊结构化语言编写的场景。这些框架是支持协作定义验收标准的出色工具。
与 BDD 理念并行的,另一种工具也被开发出来,其中 FIT 是早期的代表。这个集成测试框架允许在嵌入到与以下内容相关的文档中的表格中指定示例例子。编写这些文档不需要任何开发技能,非技术人员可以轻松阅读和审阅它们,因为它们纯粹基于文本。此外,文本可以结构化,因为文档不是纯文本文件,而是丰富编辑器的输出。
FitNesse 允许基于 wiki 协作指定预期行为。由于wiki易于访问和使用,入门和学习曲线较低,这推动了整个团队的共同工作。许多敏捷支持者强调,最好的协作方式是面对面的沟通。但是,如果你写下你的想法和讨论的内容,它应该尽可能丰富且结构良好。
Concordion 提供了很大的灵活性,因为您可以使用段落、表格和正确的标点符号以正常语言描述您的要求。描述的任何部分都可以用作自动化测试的输入,并用于验证被测系统的输出。由于它基于 HTML,您可以构建文档并集成图像。简而言之,您可以利用网络的表现力来描述预期的行为。
BDD 应该有助于构建正确的产品
您可以使用所有三种类型的工具来实施 BDD,但每种工具都有其优点和缺点。单元测试框架和类似 xSpec 的工具完美地利用了编程的优势。由于它们是开发人员为开发人员提供的工具,因此如果您尝试正确处理技术部分,它们是完美的选择。
当您想要传达应用程序的意图时,您最好使用与编辑人员在工作中使用的工具密切相关的工具。如果规范仅包含输入和预期输出,则任何阅读它的人都必须根据输入与预期输出的关系重建您的想法。标题中解释规范目标的简短描述有助于读者理解规范的结构。基于示例规范的文档可能如下所示:
是的,SpecFlow 很酷,NSpec 很酷...
FitNesse 和 Concordion 也很酷
It is interesting that this blog on Classifying BDD Tools talks about TDD and ATDD. As Liz Keogh points out: BDD is about conversation and exploration. The easier it is for all involved guys to contribute, communicate intension, share ideas, understand the others, etc. the faster we get to an adequate solution and the better software we build. When we finally follow the tool path, what are the tools that support collaboration between stakeholders of software projects best?
Based on the this blog on the differences between TDD, BDD, and ATDD I would say that there are at least three different flavors of BDD tool:
JUnit changed our view on development and testing. One of its strengths is that tests can be written in the same programming language as the application itself. Thus, we can build on the knowledge we already have in the delivery team. When the tests are even used to drive the development we reach the heaven of TDD.
Programming languages have been optimized to reduce redundancy, which is according to Ron Jeffries one of the worst sins of developers. Therefore, we often rely on these tools when we do technical testing to build the product right as they help us to be most efficient.
Several guys tried to make automated tests more understandable, as unit tests aren't really readable. One of the first attempts was to parse unit tests and provide a concise summary that is also readable to non-developers. For example TestDox / AgileDox creates simple documentation from the method names of JUnit test classes or Pickels generates documentation based on feature files written in Gherkin.
Frameworks such as MSpec help to write tests that are better readable and additionally provide readable output. These flavor of BDD tools focuses on human readable output, which enables the involvement of non-developers after the developers did their job.
To involve stakeholders earlier in the development cycle, new tools were created that focus more on readable input. Cucumber utilizes plain text files to provide human readable inputs for automated tests. The text files contain scenarios written in a specially structured language based on the given-when-then structure. These frameworks are great tools that support collaborative definition of acceptance criteria.
In parallel to the BDD idea, another flavor of tools has been developed, where FIT was an early representative. This Framework for Integrated Test allows to specify examples within tables that are embedded into a documentation related to the examples. To write these documents no development skills are required and they can be easily read and reviewed by non technical guys as they are purely text based. Additionally, the text can be structured as the documents are not plain text files but the output of rich editors.
FitNesse allows to specify the expected behavior collaboratively based on a wiki. As wikis are easy to access and use, it has a low entry and learning curve, which propels the common work of the entire team. Many agile proponents emphasize that the best way for collaboration is face-to-face communication. But, if you write down what you have thought and discussed, it should be as rich and well structured as possible.
Concordion provides a lot of flexibility as you can describe your requirements in normal language using paragraphs, tables and proper punctuation. Any part of your description can be used as input to your automated tests and for the validation of the outputs of your system under test. As it is based on HTML you can structure your documents and integrate images. Simply, you have the expressiveness of the web to describe the expected behavior.
BDD should help to build the right product
You could implement BDD with all three flavors of tools, but each has its strengths and weaknesses. Unit testing frameworks and xSpec like tools perfectly use the strengths of programming. As they are tools from developers for developers, they are a perfect choice if you try to get the technical part right.
When you want to communicate the intention of the application you are probably better off with a tool that is strongly related with tools that editors use for their work. If a specification contains only inputs and expected outputs, anyone who reads it will have to reconstruct your ideas from the relation of inputs to expected outputs. A short description explaining the goal of a specification in the header helps the reader understand the structure of the specification. Documents based on specification-by-example could look like:
Yes, SpecFlow is cool, NSpec is cool ...
FitNesse and Concordion are cool as well