English 中文(简体)
之后编写单元测试
原标题:
  • 时间:2009-04-01 20:23:15
  •  标签:

我知道TDD风格是先编写测试,看它失败,然后使其变为绿色,这是很好的东西。有时候它对我真的很有效。

然而,特别是当我正在尝试一些东西时(即不确定设计,不确定是否会起作用),或者疯狂地编写代码时,我不想编写单元测试,因为它会打断我的思路。

我倾向于稍后编写单元测试,特别是在事情变得太复杂之前。另外,晚些时候编写它们还有另一个问题,那就是通常更无聊。

我不确定这是否是一个好方法(绝不是最好的)。

你觉得呢?你是在编写后编写单元测试代码的?还是你是如何处理流程问题或实验设计/代码阶段的?

最佳回答

我所学到的是不存在实验性代码,至少在生产环境和/或紧迫截止日期下工作。通常进行实验,直到某些“可行”的代码成为生产代码。

这一背后的原因是,从一开始实行TDD将会导致你的代码更好的设计。如果你事后编写测试,你会更频繁地思考、重新工作和重构代码。

问题回答

I ve written tests after the fact. Better late then never. They are always worth having.

However, I have to say, the first time I wrote them before writing the tested code, it was extremely satisfying. No more fiddling around with manual testing. I was surprised just how good it felt.

Also, I tend to write unit tests before refactoring legacy code - which, almost by definition, means that I m writing tests to test code that s already written. Provides a security blanket that makes me more comfortable with getting into big blocks of code written by others.

"I m not quite sure if this is a good approach (definitely not the best)."

Not good? Why not?

Are you designing for testability? In that case, your design is test-driven. What more can anyone ask for?

Whether the tests come first, in the middle or last doesn t matter as much as designing for testability. In the end, changes to the design will make tests fail, and you can fix things. Changes to the tests in anticipation of design changes will make the tests fail, also. Both are fine.

If you get to the end of your design work, and there s something hard to test in the middle, then you failed to do TDD. You ll have to refactor your design to make it testable.

I often take the same approach you re talking about. What seems to work well is to treat the exerimental code exactly as such, and then start a proper design based on what you ve learned. From here you can write your tests first. Otherwise, you re left with lots of code that was written as temporary or experimental, and probably won t get around to writing tests for all of it.

I would say that for normal development, TDD works extremely well. There are cases where you may not need to write the tests first (or even at all), but those are infrequent. Sometimes, however, you need to do some exploration to see what will work. I would consider this to be a "spike", and I don t necessarily think that TDD is absolutely necessary in this case. I would probably not use the actual "spike" code in my project. After all, it was just an exploration and now that I have a better idea of how it ought to work, I can probably write better code (and tests) than my "spike" code. If I did decide to use my "spike" code, I d probably go back and write tests for it.

Now, if you find that you ve violated TDD and written some production code before your tests - it happens - then, too, I d go back and write the tests. In fact, on the occasions where this has happened to me I ve often found things that I ve neglected once I start writing the tests because more tests come to mind that aren t handled by the code. Eventually, you get back in the TDD rythym (and vow never to do that again).

Consider the psychological tendencies associated with sunk cost. That is, when you get to the second part of the equation, that laziness gene we all have makes us want to protect the work we have already done. The consequences?

If you write the tests first...

You tend to write the code to fit the tests. This encourages the "simplest thing that solves the problem" type development and keeps you focused on solving the problem not working on meta-problems.

If you write the code first...

You will be tempted to write the tests to fit the code. In effect this is the equivalent of writing the problem to fit your answer, which is kind of backwards and will quite often lead to tests that are of lesser value.

Although I d be surprised if 1 programmer out of 50 ALWAYS writes tests first, I d still argue that it is something to strive for if you want to write good software.

I usually write my tests first but sometime while experimenting I write the code after. Once I get an idea of what my code is supposed to do, I stop the code and start the tests.

Writing the code first is natural when you re trying to figure out how your code is going to work. Writing the test first helps you determine what your code show do (not how it should do it). If you re writing the code first, you re trying to solve the problem without completely defining the problem. This isn t necessarily "bad", but you are using unit tests as a regression tool rather than a development tool (again, not "bad" - just not TDD).

VS 2008 has a nice feature that will generate test classes for an object, the tests needs to me tweaked but it dose a lot of the grunt work for you. Its really nice for crating tests for your less then diligent co-workers.

Another good point for this is it help to prevent you from missing something, expectantly when your working on code that isn t yours.

if your using a different testing framework then MSUnitTest, it s fairly simple to convert then tests from MSUnit to Nunit, etc. just do some copy and past.

I would like to say that I always write Unit tests first but of course I don t (for numerous reasons well known to any real programmer :-)). What I (ok, also not always...) do is to convert every bug which takes me more than five minutes to find into a unit test. Even before I fix it. This has the following advantages:

  • It documents the bug and alerts me if it shows up again at a later point of time.
  • It helps in finding the bug, since I have a well-defined place to put debugging code into (setting up my data structures, call the right methods, set breakpoints on etc.) Before I discovered unit testing I modified the main() function for this testing code resulting in strange results when I forgot to remove it afterwards ...
  • Usually it gives me good ideas what else could go wrong, so it quite often evolves in a whole bunch of unit tests and resulting in more than one bug getting discovered resp. fixed.




相关问题
热门标签