Shift left testing with TDD- Part II
Mamata Raote
Director- (Agile Coach) @ UBS | Driving Agile Transformation with technical Agility
We have seen what is TDD in earlier article. Now lets see what are the 3 laws of TDD by Robert C Martin who is known by name Uncle Bob.
Uncle Bob describes TDD with three rules:
Lets focus on F.I.R.S.T principles now.
F.I.R.S.T Principles of good Unit Test:
F.I.R.S.T is acronym for Fast, Isolated, Repeatable, Self-validating and Timely. Lets see them one by one:
Fast: Your unit tests should be fast enough else they will slow down your development and eventually deployment of code. Imagine you are working on a big application with number of classes and you are writing unit tests for each unit of code and you end up writing 2000 unit tests. If your unit tests are taking like 200 milliseconds to run , for entire suite will take around 6.5 minutes to run. You will still say that its fast enough, but you have to run it in your development environment multiple times of day , then it will eat lots of your bandwidth.
So question is why unit test becomes slow and how we can make sure they are fast?
Every unit test has 3 parts-
Ideally unit test is very fast to execute. In a scenario where your code has dependency with database or webservice or network etc. and you are making call to read db or webservice or socket connection in your unit test, then it will slow down your test. Hence recommended practice is to mock those dependencies to execute it faster. These type of testing is also called integration testing with TDD where we are trying to validate if your unit of code works well while interacting with other dependencies. So if you avoid making call to real dependent objects and mock it, it will not slow down your unit test.
领英推荐
The refactoring rule also applies to unit test cases. Unit test cases should not have unwanted code, it should be simple and small. As per rule , one unit test should validate only one scenario and ideally should have only one assert. You may have more than one asserts though depending on some exceptional situation. If you follow these rules, your tests will execute within fraction of a second .
Isolated: Your unit test case should not have dependency on another unit test case. Every unit test case should be unique and should be able to execute independently and pass even if you run it in any sequence. If you make your test independent, it becomes easy for your test to focus only on a small amount of behavior. It even helps programmer to fix issue in the code if any test fails as that test's intention is to test only one scenario, not more than that. You can apply the single responsibility principle for your test cases and make sure that there is only one reason for your test to fail not more than that.
Repeatable: Repeatable test is such test, which will produce same result every time you run it. Even if you run it in your local dev environment, SIT, UAT anywhere, it should produce same result. If your test is producing different result in every run, its not a good unit test. If your tests are isolated from external dependencies with mock, they become repeatable. If you absolutely need to do integration test with your unit test with a DB, there are options to use in-memory databases in your test. If you follow these rules, your tests are isolated and hence becomes repeatable.
Self-validating: Self -validating test means , the test must be able to validate the output from unit of code . Means, your test should determine if your unit of code works correct and the test fail or pass. No manual interpretation should be required to validate the result. The asserts written in test should be able to do this self validation.
Don't depend on any manual configuration to run test to validate result. Everything should be automated like setup(arrange part), invocation of method(act part) and validation of result(assert part). You should keep the data ready to validate results of test.
Timely: You should write your test just before writing your production code. Practically , programmers can write unit test cases at any time, but it does not make sense. They themselves wont remember what their code is doing, to test it with unit test cases. There should not be any time gap between your test and production code. So best practice is test driven development , where you write test and immediately write code to satisfy that test. This is called ,timely test. The benefit is, you get immediate feedback if your code is working as expected or not . This way you can identify bugs immediately and can fix those and avoid spilling over them to next test cycle.
If every programmer follow the 3 rules and F.I.R.S.T principles while writing unit test cases, the quality is the only outcome !!
That's it for today. Stay tuned for tomorrow ...
HRBP Pigments Industrial Products
3 年Nicely articulated ????
Senior Associate at JPMorgan Chase & Co.
3 年Very useful.!! Thanks.
Career Coaching For Scrum Masters, Senior Scrum Masters, RTEs & Agile Coaches, Agile Product Owners, Product Managers, Agile Project Managers, Agile Delivery Managers| Ph. D in Agile Guided by IIML & IIMK | SAFe SPC |
3 年Well said
Founding Member @Watermelon Software Inc.
3 年Insigthful. Thanks Mamta
Transformational marketing leader | Business Storyteller | Brand EQ Specialist | 0 to 1 as well as 10 to 100 journey experienced | Founding Member FLS | Strategic alliances at Sirrus.AI, Ziki
3 年I loved reading it and found the first principles really useful