Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TDD: why, how and real world test driven code

Tags:

tdd

First, Please bear with me with all my questions. I have never used TDD before but more and more I come to realize that I should. I have read a lot of posts and how to guides on TDD but some things are still not clear. Most example used for demonstration are either math calculation or some other simple operations. I also started reading Roy Osherove's book about TDD. Here are some questions I have:

If you have an object in your solution, for instance an Account class, what is the benefit of testing setting a property on it, for example an account name, then you Assert that whatever you set is right. Would this ever fail?

Another example, an account balance, you create an object with balance 300 then you assert that the balance is actually 300. How would that ever fail? What would I be testing here? I can see testing a subtraction operation with different input parameters would be more of a good test.

What should I actually test my objects for? methods or properties? sometime you also have objects as service in an infrastructure layer. In the case of methods, if you have a three tier app and the business layer is calling the data layer for some data. What gets tested in that case? the parameters? the data object not being null? what about in the case of services?

Then on to my question regarding real life project, if you have a green project and you want to start it with TDD. What do you start with first? do you divide your project into features then tdd each one or do you actually pick arbitrarily and you go from there.

For example, I have a new project and it requires a login capability. Do I start with creating User tests or Account tests or Login tests. Which one I start with first? What do I test in that class first?

Let's say I decide to create a User class that has a username and password and some other properties. I'm supposed to create the test first, fix all build error, run the test for it to fail then fix again to get a green light then refactor. So what are the first tests I should create on that class? For example, is it:

  • Username_Length_Greater_Than_6
  • Username_Length_Less_Than_12
  • Password_Complexity

If you assert that length is greater than 6, how is that testing the code? do we test that we throw an error if it's less than 6?

I am sorry if I was repetitive with my questions. I'm just trying to get started with TDD and I have not been able to have a mindset change. Thank you and hopefully someone can help me determine what am I missing here. By the way, does anyone know of any discussion groups or chats regarding TDD that I can join?

like image 208
mghz Avatar asked Oct 13 '11 03:10

mghz


People also ask

Why does TDD want you to write the tests before the code?

Writing the test before the code helps the programmer put himself in the shoes of the user, making it easier to create clear software APIs. Using TDD helps make you more comfortable with circumscribing the scope of your code, writing shorter but more focused code, and producing easily-composable modules.

What is TDD and why is it important?

Test-driven development (TDD) is a software development process relying on software requirements being converted to test cases before software is fully developed, and tracking all software development by repeatedly testing the software against all test cases.

Which two techniques are used in test strategy in TDD?

Testing Techniques in Agile Software Development TDD, BDD and AMDD are the techniques in software testing that can be applied to any methodology. TDD is Test-Driven Development. The unit tests are written first, then a code is written to make the tests pass.

What is TDD and how do you implement it?

TDD is a software-driven process that includes test-first development. It means that the developer first writes a fully automated test case before writing the production code to fulfill that test and refactoring. It is a practice of writing a (failing) test before writing the code of a feature.


1 Answers

Have a look at low-level BDD. This post by Dan North introduces it quite well.

Rather than testing properties, think about the behavior you're looking for. For instance:

Account Behavior:
    should allow a user to choose the account name
    should allow funds to be added to the account

User Registration Behavior:
    should ensure that all usernames are between 6 and 12 characters
    should ask the password checker if the password is complex enough <-- you'd use a mock here

These would then become tests for each class, with the "should" becoming the test name. Each test is an example of how the class can be used valuably. Instead of testing methods and properties, you're showing someone else (or your future self) why the class is valuable and how to change it safely.

We also do something in BDD called "outside-in". So start with the GUI (or normally the controller / presenter, since we don't often unit-test the GUI).

You already know how the GUI will use the controller. Now write an example of that. You'll probably have more than one aspect of behavior, so write more examples until the controller works. The controller will have a number of collaborating classes that you haven't written yet, so mock those out - just dependency inject them via an interface. You can write them later.

When you've finished with the controller, replace the next thing you've mocked out in the real system by real code, and test-drive that. Oh, and don't bother mocking out domain objects (like Account) - it'll be a pain in the neck - but do inject any complex behavior into them and mock that out instead.

This way, you're always writing the interface that you wish you had - something that's easy to use - for every class. You're describing the behavior of that class and providing some examples of how to use it. You're making it safe and easy to change, and the appropriate design will emerge (feel free to be guided by patterns, thoughtful common sense and experience).

BTW, with Login, I tend to work out what the user wants to log in for, then code that first. Add Login later - it's usually not very risky and doesn't change much once it's written, so you may not even need to unit-test it. Up to you.

like image 191
Lunivore Avatar answered Nov 14 '22 04:11

Lunivore