How to do Test Driven Development

I have just 2+ years of experience in application development. In those two years my approach towards development was as following

  1. Analyze requirements
  2. Identity Core component/Objects, Required functions, Behavior, Process and their constraints
  3. Create classes, relation between them, constraints on objects behavior & states
  4. Create functions, process with behavioral constraints as per requirements
  5. Manually test application
  6. If requirement changes modify component/functions, then manually test application

Recently I got Introduced to TDD and feel that this is very good way to do development as developed code has strong reason to exists and lot of post deployment issues are mitigated.

But my problem is I am not able to do create tests first, Rather I am identifying components and just writing test for them before I actually write components. my question is

  1. Am I doing it is right? If not what exactly I have to change
  2. Is there any way you can identify whether test you have written are enough?
  3. Is it good practice to writing test for very simple functionality which might be equivalent to 1+1 = 2 or is it just an overplay?
  4. Is it good to change functionality and accordingly test if requirement changes?

2

Am I doing it is right? If not what exactly I have to change

It’s hard to say just from that short description, but I suspect that, no, you are not doing it right. Note: I am not saying that what you are doing doesn’t work or is in some way bad, but you are not doing TDD. The middle “D” means “Driven”, the tests drive everything, the development process, the code, the design, the architecture, everything.

The tests tell you what to write, when to write it, what to write next, when to stop writing. They tell you the design and the architecture. (Design and architecture emerge from the code through refactoring.) TDD is not about testing. It isn’t even about writing tests first: TDD is about letting the tests drive you, writing them first is just a necessary prerequisite for that.

It doesn’t matter whether you actually write the code down, or have it fully fleshed out: you are writing (skeletons of) code in your head, then writing tests for that code. That’s not TDD.

Letting go of that habit is hard. Really, really hard. It seems to be especially hard for experienced programmers.

Keith Braithwaite has created an exercise he calls TDD As If You Meant It. It consists of a set of rules (based on Uncle Bob Martin’s Three Rules of TDD, but much stricter) that you must strictly follow and that are designed to steer you towards applying TDD more rigorously. It works best with pair programming (so that your pair can make sure you are not breaking the rules) and an instructor.

The rules are:

  1. Write exactly one new test, the smallest test you can that seems to point in the direction of a solution
  2. See it fail; compilation failures count as failures
  3. Make the test from (1) pass by writing the least implementation code you can in the test method.
  4. Refactor to remove duplication, and otherwise as required to improve the design. Be strict about using these moves:
    1. you want a new method—wait until refactoring time, then … create new (non-test) methods by doing one of these, and in no other way:
      • preferred: do Extract Method on implementation code created as per (3) to create a new method in the test class, or
      • if you must: move implementation code as per (3) into an existing implementation method
    2. you want a new class—wait until refactoring time, then … create non-test classes to provide a destination for a Move Method and for no other reason
    3. populate implementation classes with methods by doing Move Method, and no other way

Typically, this will lead to very different designs than the oft-practiced “pseudo-TDD method” of “imagining in your head what the design should be, then writing tests to force that design, implement the design you had already envisioned before writing your tests”.

When a group of people implement something like a tic tac toe game using pseudo-TDD, they typically end up with very similar designs involving some kind of a Board class with a 3×3 array of Integers. And at least a portion of the programmers will actually have written this class without tests for it because they “know that they’re gonna need it” or “need something to write their tests against”. However, when you force that same group to apply TDD As If You Meant It, they will often end up with a wide diversity of very different designs, often not employing anything even remotely similar to a Board.

Is there any way you can identify whether test you have written are enough?

When they cover all the business requirements. Tests are an encoding of the system requirements.

Is it good practice to writing test for very simple functionality which might be equivalent to 1+1 = 2 or is it just an overplay?

Again, you have it backwards: you don’t write tests for functionality. You write functionality for tests. If the functionality to get the test to pass turns out to be trivial, that’s great! You just fulfilled a system requirement and didn’t even have to work hard for it!

Is it good to change functionality and accordingly test if requirement changes?

No. The other way round. If a requirement changes, you change the test which corresponds to that requirement, watch it fail, then change code to make it pass. The tests always come first.

It is hard to do this. You need dozens, maybe hundreds of hours of deliberate practice in order to build up some sort of “muscle memory” to get to a point, where when the deadline looms and you are under pressure, you don’t even have to think about it, and doing this becomes the fastest and most natural way to work.

8

You describe your development approach as a “top-down-only” process – you start from a higher abstraction level and go more and more into the details. TDD, at least in the form as it is popular, is a “bottom-up” technique. And for someone who is working mostly “top-down” it can be indeed very unusal to work “bottom-up”.

So, how can you bring more “TDD” into your development process? First, I assume your actual development process is not always so “top-down” as you described it above. After step 2, you will probably have identified some components which are independent from other components. Sometimes you decide to implement those components first. The details of the public API of those components probably does not follow your requirements alone, the details also follow your design decisions. This is the point where you can start with TDD: imagine how you are going to use the component, and how you actually will use the API. And when you start coding such an API usage in form of a test, you just started with TDD.

Second, you can do TDD even when you are going to code more “top-down”, starting with components which are dependent on other, non-existing components first. What you have to learn is how to “mock out” these other dependencies first. That will allow you to create and test high-level components before going to the lower-level components. A very detailed example on doing TDD in a top-down-manner can be found in this blog post of Ralf Westphal.

Am I doing it is right? If not what exactly I have to change

You’re doing just fine.

Is there any way you can identify whether test you have written are enough?

Yes, use a test/code coverage tool. Martin Fowler offers some good advice on test coverage.

Is it good practice to writing test for very simple functionality which might be equivalent to 1+1 = 2 or is it just an overplay?

In general, any function, method, component etc. that you expect to yield some result given some inputs is a good candidate for a unit test. However, as with most things in (engineering) life, you need to consider your trade-offs: Is the
effort offset by writing the unit test resulting in a more stable code-base in the long-run? In general, opt to write test code for crucial/critical functionality first. Later if you find there are bugs associated with some untested part of the code, add more tests.

Is it good to change functionality and accordingly test if requirement changes?

The good thing about having automated tests is that you will immediately see if a change breaks previous assertions. If you expect this because of changed requirements, yes it is ok to change the test code (in fact, in pure TDD you would change the tests first according to requirements, then adopt the code until it meets the new requirements).

1

Writing tests first is a completely different approach to writing software. Tests are not only a tool of proper code functionality verification (they all pass) but the force that defines the design. While test coverage might be a useful metric, it must not be the goal in itself – the goal of TDD is not to get to a good % of code coverage, but to think about testability of your code before writing it.

If you have troubles with writing tests first, I would highly recommend doing a session of pair-programming with someone who is experienced in TDD, so that you get a hands on experience of “the way to think” about the whole approach.

Another good thing to do is to watch online video where software is being developed using TDD from the very first line of it. Good one that I once used to introduce myself to TDD was Let’s Play TDD by James Shore. Take a look, it will illustrate how emergent design works, what questions should you ask yourself while writing tests and how new classes and methods are created, refactored and iterated upon.

Is there any way you can identify whether test you have written are
enough?

I believe this is the wrong question to ask. When you do TDD, you chose to do TDD and emergent design as the way to write software. If any new functionality you need to add always starts with a test, it will always be there.

Is it good practice to writing test for very simple functionality
which might be equivalent to 1+1 = 2 or is it just an overplay?

Obviously it depends, use your judgement. I prefer not to write tests on parameters null checks, if the method is not part of public API, but otherwise, why would you not confirm that method Add(a,b) returns a+b indeed?

Is it good to change functionality and accordingly test if requirement
changes?

Again, when you change or add new functionality to your code, you start with a test, whether it’s adding new test or changing existing one when requirements change.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật