使用 TDD:“自上而下"与“自下而上" [英] Using TDD: "top down" vs. "bottom up"

查看:31
本文介绍了使用 TDD:“自上而下"与“自下而上"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于我是 TDD 新手,我目前正在开发一个微型 C# 控制台应用程序以进行练习(因为熟能生巧,对吧?).我首先绘制了一个关于如何组织应用程序(按类)的简单草图,然后开始一个一个地开发我可以识别的所有领域类(当然,首先要测试).

Since I'm a TDD newbie, I'm currently developing a tiny C# console application in order to practice (because practice makes perfect, right?). I started by making a simple sketchup of how the application could be organized (class-wise) and started developing all domain classes that I could identify, one by one (test first, of course).

最后,为了使应用程序可运行,必须将类集成在一起,即将必要的代码放置在调用必要逻辑的 Main 方法中.但是,我不知道如何以先测试"的方式完成最后一个集成步骤.

In the end, the classes have to be integrated together in order to make the application runnable, i.e. placing necessary code in the Main method which calls the necessary logic. However, I don't see how I can do this last integration step in a "test first" manner.

如果我使用自上而下"的方法,我想我不会遇到这些问题.问题是:我该怎么做?我应该从测试 Main() 方法开始吗?

I suppose I wouldn't be having these issues had I used a "top down" approach. The question is: how would I do that? Should I have started by testing the Main() method?

如果有人能给我一些指点,我将不胜感激.

If anyone could give me some pointers, it will be much appreciated.

推荐答案

自上而下"是 已在计算中用于描述分析技术.我建议改用由外到内"这个词.

"Top-down" is already used in computing to describe an analysis technique. I suggest using the term "outside-in" instead.

由外而内是来自 BDD 的一个术语,我们认识到一个系统通常有多个用户界面.用户可以是其他系统也可以是人.BDD 方法类似于 TDD 方法;它可能对您有所帮助,所以我将简要介绍一下.

Outside-in is a term from BDD, in which we recognise that there are often multiple user interfaces to a system. Users can be other systems as well as people. A BDD approach is similar to a TDD approach; it might help you so I will describe it briefly.

在 BDD 中,我们从一个场景开始——通常是一个用户使用系统的简单示例.围绕场景的对话帮助我们确定系统应该真正做什么.我们编写了一个用户界面,如果需要,我们可以针对该用户界面自动执行场景.

In BDD we start with a scenario - usually a simple example of a user using the system. Conversations around the scenarios help us work out what the system should really do. We write a user interface, and we can automate the scenarios against that user interface if we want.

当我们编写用户界面时,我们会尽可能地保持简洁.用户界面将使用另一个类 - 控制器、视图模型等 - 我们可以为其定义 API.

When we write the user interface, we keep it as thin as possible. The user interface will use another class - a controller, viewmodel, etc. - for which we can define an API.

在这个阶段,API 要么是一个空类,要么是一个(程序)接口.现在我们可以编写用户界面如何使用该控制器的示例,并展示该控制器如何交付价值.

At this stage, the API will be either an empty class or a (programme) interface. Now we can write examples of how the user interface might use this controller, and show how the controller delivers value.

示例还显示了控制器职责的范围,以及它如何将其职责委托给其他类,如存储库、服务等.我们可以使用模拟来表达该委托.然后我们编写该类以使示例(单元测试)工作.我们编写的示例刚好足以让我们的系统级场景通过.

The examples also show the scope of the controller's responsibility, and how it delegates its responsibilities to other classes like repositories, services, etc. We can express that delegation using mocks. We then write that class to make the examples (unit tests) work. We write just enough examples to make our system-level scenarios pass.

我发现重新编写模拟示例是很常见的,因为模拟的接口最初只是猜测,然后随着类的编写而更加完整.这将帮助我们定义下一层接口或 API,我们将为其描述更多示例,依此类推,直到不再需要模拟并且第一个场景通过为止.

I find it's common to rework mocked examples as the interfaces of the mocks are only guessed at first, then emerge more fully as the class is written. That will help us to define the next layer of interfaces or APIs, for which we describe more examples, and so on until no more mocks are needed and the first scenario passes.

当我们描述更多场景时,我们会在类中创建不同的行为,我们可以重构以消除不同场景和用户界面需要相似行为的重复.

As we describe more scenarios, we create different behaviour in the classes and we can refactor to remove duplication where different scenarios and user interfaces require similar behaviour.

通过以由外向内的方式执行此操作,我们可以获得尽可能多的关于 API 应该是什么的信息,并尽快重新设计这些 API.这符合 真实期权的原则(除非你知道为什么,否则不要提前提交).我们不创建任何我们不使用的东西,API 本身是为可用性而设计的——而不是为了便于编写.代码倾向于使用领域语言而不是编程语言以更自然的风格编写,使其更具可读性.由于代码的阅读量是编写量的 10 倍左右,因此这也有助于使其易于维护.

By doing this in an outside-in fashion we get as much information as to what the APIs should be as possible, and rework those APIs as quickly as we can. This fits with the principles of Real Options (never commit early unless you know why). We don't create anything we don't use, and the APIs themselves are designed for usability - rather than for ease of writing. The code tends to be written in a more natural style using domain language more than programming language, making it more readable. Since code is read about 10x more than it's written, this also helps make it maintainable.

出于这个原因,我会使用由外而内的方法,而不是自下而上的智能猜测.我的经验是它会产生更简单、更强解耦、更易读和更易于维护的代码.

For that reason, I'd use an outside-in approach, rather than the intelligent guesswork of bottom-up. My experience is that it results in simpler, more strongly decoupled, more readable and more maintainable code.

这篇关于使用 TDD:“自上而下"与“自下而上"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆