Preamble
Testing in a project is usually done by QA. However, as developers, we also need to be aware of the quality of the project through improving our skills in testing. This article shares some knowledge of testing for developers that is primarily aimed at some of the things that need attention when writing unit tests, a job that developers often have to do.
1. At least you need to perform testing for the APIs
Most projects do not have any automated tests due to development time constraints or just test projects. So instead of starting to do automated testing we should start with testing APIs. API testing is the simplest way to help ensure a project’s quality better with a relatively large test range, we can even be done without having to write the code in the tools like Postman
. Later, when we have more time and resources, we can continue to add and develop more tests such as unit testing, data testing (DB testing), and performance testing. performance testing, …
=> You can spend a lot of time writing unit tests even though you know that it can only cover about 20% of the system. Instead, you should prioritize API testing, which is easier to do and does not require too much effort and can improve the quality of your project. Of course if you have enough time and resources, performing other tests is still necessary to help ensure the quality of your project but make sure you at least apply the API test to the project. mine.
2. Name a test case
In a project, members are not only programmers but also a combination of parts like QA, PO, etc. who may not be familiar with reading code. Therefore, writing a test case according to a standard makes it easy for people to understand the scope and function of the test case (it is also necessary for the programmer because sometimes reading the code of You don’t even understand yourself: v). A good test case when looking at us needs to have answers to 3 questions:
- What is the test case testing for? Example: Testing for the ProductsService.addNewProduct method
- Test case is taking place under what circumstances, what are the conditions? Example: No price value is passed into the method.
- What is the desired result? Example: Product not created.
Good test case
1 2 3 4 5 6 7 8 9 10 | <span class="token function">describe</span> <span class="token punctuation">(</span> <span class="token string">'Products Service'</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">describe</span> <span class="token punctuation">(</span> <span class="token string">'Add new product'</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">//Kịch bản và kết quả mong muốn được thể hiện rất rõ ràng.</span> <span class="token function">it</span> <span class="token punctuation">(</span> <span class="token string">'When no price is specified, then the product status is pending approval'</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> newProduct <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ProductService</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">add</span> <span class="token punctuation">(</span> <span class="token operator">...</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token function">expect</span> <span class="token punctuation">(</span> newProduct <span class="token punctuation">.</span> status <span class="token punctuation">)</span> <span class="token punctuation">.</span> to <span class="token punctuation">.</span> <span class="token function">equal</span> <span class="token punctuation">(</span> <span class="token string">'pendingApproval'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Test case is not good
1 2 3 4 5 6 7 8 9 10 | <span class="token function">describe</span> <span class="token punctuation">(</span> <span class="token string">'Products Service'</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">describe</span> <span class="token punctuation">(</span> <span class="token string">'Add new product'</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">it</span> <span class="token punctuation">(</span> <span class="token string">'Should return the right status'</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">//Test case đang kiểm tra cái gì?, kết quả là gì? Hmm, khá là bối rối.</span> <span class="token keyword">const</span> newProduct <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ProductService</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">add</span> <span class="token punctuation">(</span> <span class="token operator">...</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token function">expect</span> <span class="token punctuation">(</span> newProduct <span class="token punctuation">.</span> status <span class="token punctuation">)</span> <span class="token punctuation">.</span> to <span class="token punctuation">.</span> <span class="token function">equal</span> <span class="token punctuation">(</span> <span class="token string">'pendingApproval'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Only a few small details have made the test case much more meaningful, making it easy to understand the meaning as well as search when changing. In the past, my project also had a lot of badly named unit tests as above. Then we had to correct the following law, you can refer to:
1 2 3 4 5 6 7 8 | <span class="token function">describe</span> <span class="token punctuation">(</span> <span class="token string">'Vị trí của đoạn code cần test trong dự án'</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">describe</span> <span class="token punctuation">(</span> <span class="token string">'Tên hàm/class được test'</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">test</span> <span class="token punctuation">(</span> <span class="token string">'return {kết quả} if {điều kiện xảy ra}'</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token operator">...</span> <span class="token operator">...</span> <span class="token operator">...</span> <span class="token operator">...</span> <span class="token operator">...</span> <span class="token operator">...</span> <span class="token operator">...</span> <span class="token operator">...</span> <span class="token operator">...</span> <span class="token operator">...</span> <span class="token operator">...</span> <span class="token operator">...</span> <span class="token operator">...</span> <span class="token operator">...</span> <span class="token operator">...</span> <span class="token operator">...</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
3. Structure a test case with AAA parttern
When defining a test case unit test you should structure it into 3 clearly separated parts: Arrange, Act & Assert (AAA).
Arrange
: Turn off all the settings to simulate the test script.Act
: Execute a unit of test, usually written by a single line.Assert
: Testing to ensure that the value received meets the expectation, usually in only one line
Good test case
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token function">describe</span> <span class="token punctuation">(</span> <span class="token string">'Customer classifier'</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">test</span> <span class="token punctuation">(</span> <span class="token string">'When customer spent more than 500$, should be classified as premium'</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">//Arrange</span> <span class="token keyword">const</span> customerToClassify <span class="token operator">=</span> <span class="token punctuation">{</span> spent <span class="token punctuation">:</span> <span class="token number">505</span> <span class="token punctuation">,</span> joined <span class="token punctuation">:</span> <span class="token keyword">new</span> <span class="token class-name">Date</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> id <span class="token punctuation">:</span> <span class="token number">1</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> DBStub <span class="token operator">=</span> sinon <span class="token punctuation">.</span> <span class="token function">stub</span> <span class="token punctuation">(</span> dataAccess <span class="token punctuation">,</span> <span class="token string">'getCustomer'</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">reply</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> id <span class="token punctuation">:</span> <span class="token number">1</span> <span class="token punctuation">,</span> classification <span class="token punctuation">:</span> <span class="token string">'regular'</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">//Act</span> <span class="token keyword">const</span> receivedClassification <span class="token operator">=</span> customerClassifier <span class="token punctuation">.</span> <span class="token function">classifyCustomer</span> <span class="token punctuation">(</span> customerToClassify <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">//Assert</span> <span class="token function">expect</span> <span class="token punctuation">(</span> receivedClassification <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">toMatch</span> <span class="token punctuation">(</span> <span class="token string">'premium'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Test case is not good
1 2 3 4 5 6 7 8 | <span class="token function">test</span> <span class="token punctuation">(</span> <span class="token string">'Should be classified as premium'</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> customerToClassify <span class="token operator">=</span> <span class="token punctuation">{</span> spent <span class="token punctuation">:</span> <span class="token number">505</span> <span class="token punctuation">,</span> joined <span class="token punctuation">:</span> <span class="token keyword">new</span> <span class="token class-name">Date</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> id <span class="token punctuation">:</span> <span class="token number">1</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> DBStub <span class="token operator">=</span> sinon <span class="token punctuation">.</span> <span class="token function">stub</span> <span class="token punctuation">(</span> dataAccess <span class="token punctuation">,</span> <span class="token string">'getCustomer'</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">reply</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> id <span class="token punctuation">:</span> <span class="token number">1</span> <span class="token punctuation">,</span> classification <span class="token punctuation">:</span> <span class="token string">'regular'</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> receivedClassification <span class="token operator">=</span> customerClassifier <span class="token punctuation">.</span> <span class="token function">classifyCustomer</span> <span class="token punctuation">(</span> customerToClassify <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token function">expect</span> <span class="token punctuation">(</span> receivedClassification <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">toMatch</span> <span class="token punctuation">(</span> <span class="token string">'premium'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
We see in the test case on isolated components, it is easier to observe than writing a block like the test case below.
Conclude
The article is referenced and summarized from mục 4.1
to mục 4.3
of nodebestpractices.You can refer more about testing and other knowledge through the best practices I find very good, although I do not fully understand. . One of my luck is being done in a project that applies many of the best practices mentioned here, so it is also possible to grasp the tip of the iceberg. Hope the article is useful for you.
References
https://github.com/goldbergyoni/nodebestpractices#4-testing-and-overall-quality-practices
https://medium.com/@me_37286/yoni-goldberg-javascript-nodejs-testing-best-practices-2b98924c9347