Developer's Checklist For Unit Test

 Related Articles:


Unit Tests play an important role in delivering high-quality software solutions. An ideal Unit Test is a piece of code (automated test) written by a developer that exercises a small but specific area of code functionality to ensure that it works as expected.

Why Unit Test

According to the Test Triangle, in a software project the largest number of tests must be Unit Tests. Because multiple individual Unit Tests exercises small units of functionality that spans over various areas of functionality offered by the software solution.

ui test

Unit Test Check-List

When writing Unit Test(s) the following points must be considered and followed by the developers and SDETs.

Check Description
Self-Describing Names

Unit Test method names must be self-describing and Pascal case. For example choose Add_New_Customer_With_Valid_AcccountNumber over AddCustomer_with_validAcc or addCustomer and so on.

Also focus on naming style, keep the naming style consistent across all the test methods and tests.

A3 (Arrange, Asset, Act) Be sure that all the test methods are designed around arrange, act and assert.

If required refactor your code to fall into these three sections.
Test Happy and Sad Path The Unit Test should cover all possible scenarios and strive for high code coverage and ensuring good quality metrics. Unit Test methods must exercise all possible use case scenarios to test the input validations, interactions, errors messages, edge cases and exceptions and so on.
Use Attributes
Use Test Framework provided attributes like: 
[TestCategory("<describe if its Unit or Integration Test>")]
[TestCategory("<Which section of the application is being tested>")]
[Priority(n), TestCategory("<define if it’s Gated or not-Gated build Tests>")]
[Owner("<who wrote this test>")]
Have least number of asserts per test (if applicable) A good Unit Test should only have a limited number of assert statements. It should Unit Test the very functionality, as indicated in its descriptive name.

A well-defined Unit Test should contain only one assert statement per test and must not try to exercise all the validation/boundary checks and so on by multiple Asserts in one Unit Test method.
Keep assert messages descriptive Keep assert messages descriptive. Use descriptive messages to improve the readability of code and the build log.

Assert.IsTrue(customer.IsExist,"The Customer is not found in the Database");
Unit != Integration There is a very fine line between unit and integration, if you happen to go beyond what your function is supposed to be doing then you are not writing a Unit Test. In other words a Unit Test doesn't focus on interaction with external systems and software layers/dependencies.

Test doubles (for example Microsoft Fakes framework) are relevant to writing Unit Tests that have dependencies on external libraries and systems and so on.
Follow OOP Design and Adopt DI Following Dependency Injection will allow to convert potential Integration Tests into small and quickly testable Unit Tests by taking advantages of Test Doubles (for example Microsoft Fakes, Moq, FakeItEasy frameworks and so on.)  
Should be thorough Unit Tests are supposed to test all the possible areas of functionality that are subject to failure due to incorrect input/validation checks/boundary checks and so on for a given function/method.  
Must be Repeatable Unit Tests must be repeatable for every build and must produce the same results. The development best practice suggests that if you are working on code that is impacting a Unit Test then you must fix the affected Unit Test as well and ensure that it passes.  
Need to be Independent Unit Tests must be independent of another test. In other words, no collateral damage. Hence, a Unit Test must focus only on a small aspect of big functionality. When this Unit Test fails, it should be easy to discover where the issue is in the code. In other words can be tested in isolation.  
Keep it Professional Even though at times Unit Tests may appear to be very simple and small, you must write Unit Tests with coding practices as good as you use for your main development coding. You may want to follow Refactoring, Code Analysis and Code Review practices and so on as for your Test Projects as well.  
No Collateral Damage Be sure to run all related Unit Tests after any development code change whether big or small to verify and ensure that no collateral damage occurs or has been introduced.  
If you break it, You bought it If you are working on a feature and to verify no collateral damage, as a best practice run all the Unit Tests. If you observe that some Unit Tests begin failing because of your code changes then you own to fix those broken Unit Tests to ensure they continue to pass.  
Track and maintain the tests The test code changes should be tracked and maintained as an on-going effort. Continue to follow the design principles and coding guidelines.  
 Code Review the Tests
Just like any other Dev code, Unit Tests also need to be code-reviewed by peers. Regardless of the size of the test, follow the process.
Code review might include reviewing the name of test method, scenarios covered, conditions checked, scope of assertions and code / design smells, and so on.