Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deal with memory leaks when following TDD

Say I want to follow pure TDD i.e. write unit tests before writing any other code. When I find a bug I must write unit test that reproduces it and then implement a fix.

Say there's a memory leak in my application. I can reproduce it - running a particular method 1,000,000,000 times causes OutOfMemoryException. This test takes 10 seconds to fail.

Long running unit tests are usually not welcomed especially when they consume lots of memory. Also later there may be other memory leaks so number of such tests may increase.

So how to fix this bug TDD-way?

like image 386
Konstantin Spirin Avatar asked Feb 18 '11 05:02

Konstantin Spirin


1 Answers

TDD calls for you to write tests first but those don't necessarily have to be unit tests.

Unit tests are not always the best, or sometimes even a feasible, tool for testing all behavior or reproducing all bugs. For example a race condition might only be exposed when multiple components are used on multiple threads.

In your case you have one specific method you know to be problematic so you might be able to write a unit test to reproduce this bug but is that a reasonable solution? You'll fix this one issue but not similar problems in other methods. Are you going to write a "doesn't leak memory" test for every method?

Instead I would try to write functional or integration tests which run a more complete slice of the application under test and use whatever tools are available in your development environment to try to catch memory leaks. Some languages will allow you to execute code, force a garbage collection or other cleanup, and then confirm that memory use or allocated object counts have returned to their previous values. In other environments that may not be feasible so you may need to make broader measurements, perhaps watching the memory use of your application over time in a performance testing deployment.

Unit tests are fast (or at least they should be) and focused so they're nice when they make sense but ultimately you can consider every sort of test or analytic data you can collect about your code to be part of your TDD process. If you're able to make assertions about how your application should behave, even broad statements like "memory use should remain stable over time", develop automatable means of testing those assertions and use those tests to drive your design then I think you're practicing TDD. Write the tests which make sense.

like image 134
Jonah Avatar answered Nov 15 '22 08:11

Jonah