Unit Testing — Its never too late to start !!
As a Developer everyone know about Unit Testing and Best Practices. Almost each and everyone of us must have experienced with unit testing at some point in our development experience.
In this post I just want to share my views and experiences about unit testing.
Why should we test? That’s an obvious question almost everyone thinks when Unit Test comes into our mind. We test to make our code bullet proof, We test to reduce bugs. Unit testing makes sure that our method is tested by each and every scenarios which can occur which might not be tested in real scenarios at least from developer perspective. When we add a text field, how many times we test the scenarios and numbers, values possible in the text field. May be twice, thrice and then we leave on our testers to test.
With the pace of development and pressure we tend to miss some of the scenarios which we expect to be tested by out QA but what if they miss? Whoooo ! Its in production, what if your friend use your application and just calls you Hey man !! Your app does not accept these characters in the text field. How can I proceed ? ! .. Result….. Rating 2 in the AppStore. We certainly don’t want this result after our months and years of hard work…
So coming to the unit testing. In unit testing each component should be tested in a way that it is not aware of the other components. Every layer in the application has its own functionality and responsibility in the application. Unit testing each layer means to avoid bugs in each module and eventually it will avoid bugs in the application.
Two different ways of unit testing are TDD (Test driven development) and BDD (Behavioral driven development).
TDD: Test driven development for any module or component means testing before development. We need to write our unit test before actual implementation of the classes. This may sound weird but with this approach we can better design/test our view, view models, view controllers.
BDD: Behavioral driven development for any module or component means testing after development. This is different from the first approach as our code is already there, we need to understand the implementation and write the expected behavior of the method.
Which is the best approach between the two? TDD is always the best approach until we have some parts of the code already being written without any tests.
Code Coverage: Measuring code coverage for our testes gives a feeling of completeness of our test suites. Depending on how well we have written our unit test is determined by code coverage report. This report gives a clear picture of the percentage of code coverage our classes have lower the percentage lesser the coverage. Its very hard to achieve 100% code coverage for any application but if we are able to achieve more than 75% we are doing an awesome job. Percentage of coverage depends on project to project a good code coverage can be between 50% -75%.
What are the main areas to test in an application: Every client application has different code components which needs to be tested. In a MVVM model below are different component which can be tested.
- Data Models
- View Models
- View Controllers
- Networking layer
Best Practices to write a unit test.
- Naming Convention: Naming a unit test should be simple it should convey the idea what is being tested in the method. Descriptive names should be given to the unit test indicating its functionality.
- Using numeric digits, special characters in the test cases should be avoided. For example, test2+2is4 or test2plus2is4.
- Given, When, Then conditions — Each unit test depends on any action of a given condition. If we have different methods which has its own responsibilities it will more readable. This will also help to reuse the same code in different test methods.
- Use setUp() and tearDown() methods. We need to initialize required properties in set up and Deinitialize in tearDown
- Covering all test scenarios: If we are testing only the positive cases we are not justifying to unit test. We need to know the scenarios when our test will break and we need to test all the relevant aspects.
- If we have method which serves as utility functions for the classes we can write performance tests to measure the performance. This will help to improve code quality and makes the application faster.
- Each classes should be tested as a separate component as if it is not aware of the other component. Every component has its own functionality hence in order to function the way it should be it needs to be tested. If there are any dependencies from one component to other we need to make use of mocks, stub, fakes in order to fulfill that dependencies.
- Always check for refactoring even if the test is passing. We are writing unit test for code quality and catch bugs, we should aim to check a possibility for refactoring even if the test passes.
- XCTAsserts comments should be negative of what test says. So it the test says additionOfTwoNumbersIsFour, comment section of XCTAssert should be “Addition of the two numbers is not equal to four”
Challenges: Writing a unit test is off course a challenging ask for any project.
- Timelines: One of the major challenge is time lines. I believe writing a unit test takes same amount of time we need to implement some functionality. Off course this gap will narrow down as per experience and practice.
- Knowledge: When it comes to write a unit test we need to know what’s the best way to write it. We can find n number of ways to do it yet we don’t know the best way too write unit test. We need to learn and implement both goes hand in hand. We need to know mocks, stubs, fakes to write good unit tests.
- Code Coverage: Its not about only writing a unit test but if you manager checks the dashboard every morning then it will be a challenge to achieve minimum code coverage required by the project.
- Encapsulation abuse : Sometimes we may require to use private properties methods of the class, in this case if we are making them public then it is no longer encapsulated.
Its never too late to start and there is no tomorrow. So start today !!