DEV Community

Discussion on: How to implement test driven development in the real world?

Collapse
 
sargalias profile image
Spyros Argalias

I think it depends. However I'm not so sure about the particular example above.

Sure, maybe if you're really experienced with TDD, you could work with that. But it might be best to start with very little code per test. That way you focus on testing a unit, a public function of the class, not the entire class in one test.

// You can substitute for interfaces, dependency injection and anything else.

test('dog should bark', () => {
  dog = new Dog('name', 'something', 'something else');
  const result = dog.bark();
  expect(result).toBe('woof');
});

test('dog should have correct furcolor', () => {
  dog = new Dog('name', 'something', 'something else');
  expect(dog.furcolor).toBe('something');
});

So you only test a small thing at a time, and design a small thing at a time. Also you can go in a loop of writing a single test, making it pass, repeat. It's not necessary to write more.

One of the important parts is the design, please see my previous comment for more details on that.

As I also mentioned, TDD is optional. If your code design is sufficient, and you don't require the benefits of TDD, then that's okay too.

Thread Thread
 
slavius profile image
Slavius • Edited

In a test you should test isolated feature.

In my example I tested correct instantiation of an object only. That's it. I didn't even test if the function Bark() produces any result, let alone a correct result based on constructor parameters. Only if it exists in a list of available object functions for a dog type object. I honestly don't think that's too much for a test content.

Do you think it is?

In contrast any other approach cannot even compile your test project as it cannot resolve Dog class.
Then if you fix it, it won't compile unless you implement missing properties.
Then you implement the properties but you miss getter logic (e.g. return age if only birth date was provided).
And so on.

I need some explanation from you.
Your test examples instantiate the dog class twice to compare immutable properties. You did not even change the object state, why should you write another test to make sure the dog can bark while not testing his fur color? I don't think that makes sense. It would, only if barking changes the fur color or if the fur color changes does in fact change the output of the Bark() function. But I assume that is not the case, is it?

I find it unusable that my tests do not compile and do not fail properly until I implement the missing code. That's a big no-no for my CI/CD pipeline...

Thread Thread
 
sargalias profile image
Spyros Argalias • Edited

Okay fair enough. Yeah I guess the example you gave didn't really have functionality, it was more of an object which just holds properties.

You're right that we need to test an isolated feature. However what is an isolated feature? It's subjective. For an object with getters and setters, I would argue that an isolated feature is a single property you can set and get. But someone could argue that the object can't be used until everything has been set properly. In that case the test would require setting everything, as you say.

So in the end it depends. If we don't need to set everything at once, then perhaps it would be easier to have one test where we only check the age getter and setter, and another test for the name, and so on... But of course it's up to requirements and personal preference.

Not compiling is acceptable when we do TDD, it's just something we have to work with.

Edit: For the CI/CD pipeline, we don't have to commit until both a test and implementation are working.

I'm repeating myself here but TDD is optional. If it doesn't work for your workflow or preference that's fine. Sometimes I can't use it either. Sometimes I just build and refactor later.

Thread Thread
 
slavius profile image
Slavius

My issue with not compiling is that it breaks my CI/CD pipeline. I'd like to create tests in my test project and the whole solution just compiles but the tests fail. This way my Jenkins/Bamboo/whatever can produce meaningful message to the developers in form of a failed test report instead of a bunch of compiler errors hidden in tons of output.

Thanks for discussion I realized some thinks I was not aware of. ;)

Thread Thread
 
sargalias profile image
Spyros Argalias

*I added a quick edit above about the CI/CD issue.