{"id":63372,"date":"2025-02-02T02:06:20","date_gmt":"2025-02-02T02:06:20","guid":{"rendered":"https:\/\/peraltafinancing.com\/analytics\/why-invest-in-unit-testing\/"},"modified":"2025-02-02T02:06:20","modified_gmt":"2025-02-02T02:06:20","slug":"why-invest-in-unit-testing","status":"publish","type":"post","link":"https:\/\/fivemor.com\/?p=63372","title":{"rendered":"Why invest in unit testing?"},"content":{"rendered":"<p> <br \/>\n<\/p>\n<div id=\"wtr-content\" data-bg=\"#0cacf8\" data-fg=\"#0cacf8\" data-width=\"5\" data-mute=\"\" data-fgopacity=\"1.00\" data-mutedopacity=\"1.00\" data-placement=\"top\" data-placement-offset=\"48\" data-content-offset=\"0\" data-placement-touch=\"top\" data-placement-offset-touch=\"0\" data-transparent=\"1\" data-shadow=\"1\" data-touch=\"\" data-non-touch=\"1\" data-comments=\"0\" data-commentsbg=\"#0cacf8\" data-location=\"page\" data-mutedfg=\"#0cacf8\" data-endfg=\"#f44813\" data-rtl=\"\">\n<p>What are unit tests? Who is responsible for them? Why write them? Do we have enough of them? How do you design them? And what do you do with this hard-to-test code?\u00a0A wide range of\u00a0questions that I will try to answer below.\u00a0<\/p>\n<p>This article is particularly aimed at developers who have questions or want to be reassured about best practices. However, it is also for all those who are directly or indirectly involved in their company\u2019s testing strategy or \u201cquality approach\u201d.<\/p>\n<h2>The test levels\u00a0<\/h2>\n<p>Let\u2019s first put unit tests in context. According to the recommendations of the ISTQB (<a rel=\"noreferrer noopener\" href=\"https:\/\/www.istqb.org\/\" target=\"_blank\">International Software Testing Qualification Board<\/a>),\u00a0unit tests are\u00a0the first level of dynamic testing in the software testing process.\u00a0As a\u00a0reminder, \u201cdynamic\u201d tests are the tests carried out by executing the code, as opposed to so-called \u201cstatic\u201d tests for which the code is not executed (code analysis,\u00a0linting, compliance with coding rules, code reviews, etc.).\u00a0<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/Tests-boite-blanche.jpg\" alt=\" &quot;white box&quot; tests\" class=\"wp-image-17677\" width=\"496\" height=\"276\" srcset=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/Tests-boite-blanche.jpg 992w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/Tests-boite-blanche-300x167.jpg 300w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/Tests-boite-blanche-768x427.jpg 768w\" sizes=\"auto, (max-width: 496px) 100vw, 496px\"\/><\/figure>\n<\/div>\n<p>They are \u201cwhite box\u201d tests because they are defined by having access to the internal structure of the system, unlike the \u201cblack box\u201d tests that I explain in a\u00a0<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.atinternet.com\/en\/system-tests-an-objective-look-at-the-product\/\" target=\"_blank\">previous article<\/a>.<\/p>\n<p>At\u00a0AT\u00a0Internet, \u201cwhite box\u201d tests are implemented by developers, while \u201cblack box\u201d tests are automated by testers and acceptance tests are conducted by the customer\u2019s representatives (the product owners). This organisation can vary from company to company with one consistent theme: unit testing is an integral part of development!\u00a0<\/p>\n<h2>What is a unit test?\u00a0<\/h2>\n<p>There are several definitions of unit tests, with one common theme \u2013 they are \u201ca test that validates a unit of code in isolation\u201d. This can take different forms depending on the source and can be interpreted in many ways, which may make the true nature of these tests unclear. Some questions often come up: <\/p>\n<ul>\n<li>What unit of code should be considered in a unit test?\u00a0<\/li>\n<li>How do you isolate the code you want to test?\u00a0<\/li>\n<li>Are we \u201callowed\u201d to load several functions\/methods\/classes in a single test?\u00a0<\/li>\n<li>Must a single test cover the entire\u00a0business\u00a0of the \u201cunit of code\u201d under consideration?\u00a0<\/li>\n<\/ul>\n<p>Personally, I think that the definition on\u00a0<a href=\"https:\/\/en.wikipedia.org\/wiki\/Unit_testing\" target=\"_blank\" rel=\"noreferrer noopener\">Wikipedia<\/a>\u00a0is a good start, but still needs some clarification:\u00a0<\/p>\n<p><em>[the unit test is] \u201ca\u00a0<\/em><strong><em>procedure<\/em><\/strong><em>\u00a0to verify\u00a0<\/em><strong><em>the proper functioning<\/em><\/strong><em>\u00a0of a\u00a0<\/em><strong><em>specific part<\/em><\/strong><em>\u00a0of a software program or portion of a program (referred to as a \u201cunit\u201d or \u201cmodule\u201d)\u201d.<\/em>\u00a0<\/p>\n<p>I think it is important to clarify certain terms:\u00a0<\/p>\n<h3>\u201cThe proper functioning\u201d\u00a0<\/h3>\n<p>This is most often the correct application of a business rule or functional behaviour that can be written in the form of:\u00a0<\/p>\n<p><code><em>should do XXXX when XXXX<\/em><\/code><\/p>\n<p>It can also include non-functional aspects such as system performance or resilience. We will then have a title more along these lines:\u00a0<\/p>\n<p><code><em>should run in less than X\u00a0ms<\/em><\/code><\/p>\n<p><code><em>should retry X times if no response from DB<\/em><\/code><\/p>\n<h3>\u201cA specific part of a piece of software\u201d\u00a0<\/h3>\n<p>This is the minimal code to be used to validate the targeted behaviour. Depending on the structure of the code and the language used, it can be:\u00a0<\/p>\n<ul>\n<li>A method\u00a0<\/li>\n<li>Several methods\u00a0<\/li>\n<li>One class\u00a0<\/li>\n<li>Several classes\u00a0<\/li>\n<li>etc.\u00a0<\/li>\n<\/ul>\n<p>The more \u201cbehaviour oriented\u201d the code is through the use of practices such as DDD (domain driven design), BDD (behaviour driven development) or TDD (test driven development), the easier it will be to isolate the code providing a given behaviour. We will come back to this point later in this article. <\/p>\n<h2>Do you observe the symptoms or identify the causes? <\/h2>\n<p>It is important to differentiate between the symptoms and root causes of an anomaly. To do this you can use the following analogy: <\/p>\n<p>Your car won\u2019t start this morning! (symptom) So you call a breakdown mechanic who will investigate to find the causes of this problem and find a suitable solution. <\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-5.png\" alt=\"Your car won't start this morning example\" class=\"wp-image-17665\" width=\"220\" height=\"176\" srcset=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-5.png 440w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-5-300x240.png 300w\" sizes=\"auto, (max-width: 220px) 100vw, 220px\"\/><\/figure>\n<\/div>\n<p>This is a valid process when it comes to studying a \u201cmalfunction\u201d of an automobile. Let\u2019s apply this to a defect in a piece of software: <\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-6.png\" alt=\"Example applied on a bug\" class=\"wp-image-17666\" width=\"278\" height=\"134\" srcset=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-6.png 555w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-6-300x144.png 300w\" sizes=\"auto, (max-width: 278px) 100vw, 278px\"\/><\/figure>\n<\/div>\n<p>A \u201cbug\u201d is detected by the user: a feature does not behave as expected (symptom). A developer analyses the problem, investigates the code to find the root cause of the problem, identifies the piece of code responsible and makes a correction (bugfix). <\/p>\n<p>This process is very costly for the company and can undermine project planning by \u201crequisitioning\u201d a developer to investigate. It is also uncomfortable for the developer who has to stop what they were doing to find a solution to the problem, often last minute. The developer\u2019s main role is not to spend most of their time searching for the causes of a problem, unlike a mechanic whose primary task is to \u201cfind the malfunction\u201d. <\/p>\n<p>In our field, we are fortunate to be able to place the different \u201caspects\u201d of our product under permanent control with unit tests. We can then benefit directly from information on the root causes of potential defects in our product and, with good tests, go from the simple observation of a symptom to the automatic identification of the cause of the problem.  <\/p>\n<p>Let\u2019s go back to our broken-down car \u2013 these two messages displayed on the screen give different information: one describes a symptom (the engine does not start), the other targets the cause of the problem (injection failure): <\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"848\" height=\"200\" src=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-7.png\" alt=\"Photo of two messages displayed on the screen give different information\" class=\"wp-image-17668\" srcset=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-7.png 848w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-7-300x71.png 300w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-7-768x181.png 768w\" sizes=\"auto, (max-width: 848px) 100vw, 848px\"\/><figcaption> <strong>\u201cengine failure (symptom)\u201d =&gt; \u201cinjection problem (root cause)\u201d<\/strong>\u00a0<\/figcaption><\/figure>\n<\/div>\n<p>Here\u2019s another example, on a software product\u00a0like\u00a0Explorer, a data mining tool in AT Internet\u2019s\u00a0<a rel=\"noreferrer noopener\" href=\"https:\/\/www.atinternet.com\/\" target=\"_blank\"><em>Analytics Suite<\/em><\/a>.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"990\" height=\"326\" src=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-8.png\" alt=\"Example of Analytics suite\" class=\"wp-image-17670\" srcset=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-8.png 990w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-8-300x99.png 300w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-8-768x253.png 768w\" sizes=\"auto, (max-width: 990px) 100vw, 990px\"\/><\/figure>\n<\/div>\n<p>It is now clearer that in case of error, unit tests must allow users to directly target the faulty part of the code. This allows the developer to save precious investigation time and also to be under less pressure (and therefore\u00a0be\u00a0more motivated)!\u00a0<\/p>\n<h2>Why invest in unit testing?\u00a0<\/h2>\n<p>Why do we need to have such detailed information on the internal behaviour of our products, by investing in the implementation of these unit tests? There are several objectives. Among these, I can see four main reasons for this investment:\u00a0<\/p>\n<ul>\n<li>Risk management\u00a0<\/li>\n<li>Individual responsibility\u00a0<\/li>\n<li>Development comfort\u00a0<\/li>\n<li>Cost optimisation\u00a0<\/li>\n<\/ul>\n<h3>Better manage risks\u00a0 <\/h3>\n<p>Detecting bugs before production release is a daily challenge for software publishers. At\u00a0AT\u00a0Internet, we have chosen to invest as early as possible in the development cycle to avoid regressions in our products. Investing in the different levels of testing allows us to manage this risk as well as possible, starting with the unit tests.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-9.png\" alt=\"Unit test in the development cycle\" class=\"wp-image-17673\" width=\"485\" height=\"220\" srcset=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-9.png 969w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-9-300x136.png 300w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-9-768x348.png 768w\" sizes=\"auto, (max-width: 485px) 100vw, 485px\"\/><\/figure>\n<\/div>\n<p>The earlier the \u201cstamp\u201d is applied in the process, the lower the risk of discovering a bug in production.<\/p>\n<h3>Extending individual responsibility\u00a0 <\/h3>\n<ul>\n<li>How can you be proud of your code without\u00a0having made\u00a0sure it works properly?\u00a0<\/li>\n<li>How can you feel responsible without providing\u00a0your successor\u00a0with a set of tests that will be used to secure future refactoring or maintenance? (and this successor can be\u00a0you!)\u00a0<\/li>\n<\/ul>\n<p>Pride and responsibility are two important characteristics in the developer\u2019s job and very present in Agility. Writing unit tests serves both! We make sure that the product code works properly without entrusting someone else with this responsibility (tester, product owner, other team, other company (third party software testing)\u2026) and at the same time, we ensure a level of quality over the entire life of the product. This longer-term vision of one\u2019s activity is an important sign of responsibility and even professionalism! <\/p>\n<p>For the rebellious, there are many \u201cgood\u201d excuses for not writing unit tests available online. I\u2019ll let you find out about them \u2013 there are really many that look very appealing, some of them very creative! <\/p>\n<h3>Improve team comfort levels <\/h3>\n<p>Having good unit tests means avoiding future emergencies, bugs that need to be fixed in a hurry, under pressure, dissatisfied customers, and loss of reputation for the company. <\/p>\n<p>All these situations make life difficult for development teams and can have a direct impact on the motivation of developers if there are too many of them. The best way to protect yourself is to implement enough unit tests (if they are relevant). <\/p>\n<p>Another equally important aspect of comfort is to reduce the amount of time spent debugging: the analysis you need to do to trace back to the line of code in question in order to apply the appropriate correction. The worst situation is to have to launch the entire application in \u201cdebug mode\u201d to follow its behaviour step by step and finally succeed in identifying the faulty code. A good unit test allows you to directly target portions of code and validate their respective behaviour(s).  <\/p>\n<p>There will always be defects in production \u2013  but the goal is simply to limit their number and their impact. Any bug detected in production will give the opportunity to add the missing unit test(s) so that you don\u2019t have to invest again all the time spent on the analysis and correction of the problem. <\/p>\n<p>This is an opportunity to remind you that unit tests provide quick feedback, in a few tens of seconds. So much so that they have been systematized by the principles applied in practices such as eXtreme Programming: <\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-10.png\" alt=\"eXtreme Programming feedback loops \" class=\"wp-image-17675\" width=\"378\" height=\"358\" srcset=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-10.png 504w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-10-300x284.png 300w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-10-24x24.png 24w\" sizes=\"auto, (max-width: 378px) 100vw, 378px\"\/><figcaption> <strong>eXtreme\u00a0Programming feedback loops<\/strong><\/figcaption><\/figure>\n<\/div>\n<p>By saving analysis time and anticipating the appearance of numerous bugs in production through the use of unit tests, everyone can keep the focus on adding value to the product rather than compensating for a lack of quality afterwards. <\/p>\n<h3>Optimising the ROI of our testing process <\/h3>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/ROI-test.jpg\" alt=\"Sch\u00e9ma of optimising the ROI of our test pyramid\" class=\"wp-image-17676\" width=\"400\" height=\"276\" srcset=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/ROI-test.jpg 800w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/ROI-test-300x207.jpg 300w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/ROI-test-768x529.jpg 768w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\"\/><\/figure>\n<\/div>\n<p>The higher we go up in our test pyramid, the higher the costs. This effect is multiplied because the cost increases involve both: <\/p>\n<ul>\n<li> Setting up the tests <\/li>\n<li>Maintenance of tests in place <\/li>\n<li>The cost of executing the tests (machine time, servers\u2026) <\/li>\n<li>The time it takes to obtain a test result <\/li>\n<li>Analysis time when a bug is detected <\/li>\n<\/ul>\n<p>These are all good reasons to invest in the deepest layers to optimise the ROI of our testing process. Each stage will complement the tests already passed, with a lower test volume. Each test level has its importance and is essential to ensure the level of quality we want for our customers, but we have to consciously evaluate the investments at all levels so as not to be overtaken by the induced costs which can easily escalate. <\/p>\n<p>The graph below also illustrates the costs and time required to achieve status throughout the development cycle. This is another good reason to invest in unit testing!<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-11.png\" alt=\"Schema of the bug cost \" class=\"wp-image-17678\" width=\"484\" height=\"317\" srcset=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-11.png 968w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-11-300x196.png 300w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-11-768x502.png 768w\" sizes=\"auto, (max-width: 484px) 100vw, 484px\"\/><figcaption> <strong>Bug cost (Copyright 2006-2009 Scott W. Ambler)<\/strong><\/figcaption><\/figure>\n<\/div>\n<h3>The \u201cshift left\u201d approach\u00a0<\/h3>\n<p>To complete the cost optimisation process and to further improve the return on investment of our testing strategy, we have adopted a \u201cshift left\u201d approach. This approach aims to shift test operations \u201cto the left\u201d to be carried out as early as possible in the development cycle. We therefore increase the effort to detect defects in the unit test phase, which enables us to limit the costs generated in the rest of the cycle:\u00a0<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"799\" height=\"406\" src=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/Shift-Left-Defect-Detection-and-Remediation_4.gif\" alt=\"Gif of the &quot;shift left&quot; approach\" class=\"wp-image-17680\"\/><\/figure>\n<\/div>\n<p>It is possible to take this approach even further and try to detect more defects during the code phase itself by using static tests such as code analysis (with or without tools) or by extending peer-programming practices which are very effective in terms of the quality of the code produced, not to mention the positive impact on team spirit and skill sharing.\u00a0<\/p>\n<h2>Best (and not so good) practices\u00a0<\/h2>\n<p>It is therefore important to invest in the implementation of unit tests, but what can you do to ensure that they are relevant and effective? It is important to be aware of best practices when implementing unit tests.\u00a0<\/p>\n<p>First, I think it is useful to remember that the test aims to detect if there is a difference between the expected behaviour and the implemented behaviour. It is therefore preferable to design these tests based on the specifications (whatever they are: prerequisites, technical specifications, stories\u2026) rather than on the code itself, otherwise we risk only validating the implemented behaviours which may differ from the expected behaviours!\u00a0<\/p>\n<p>The best way to avoid falling into this trap is to write the tests first, using any \u201ctest first\u201d approach, for example in TDD (Test Driven Development).\u00a0<\/p>\n<p>When designing and writing unit tests, it is a good idea to follow certain best practices or conventions:\u00a0<\/p>\n<ul>\n<li><strong>Tests must be restricted (in their functional scope):<\/strong> do not attempt to validate 50 things in a single test!\u00a0<\/li>\n<li><strong>They must be quick to run:<\/strong> no waiting time (60s) in a unit test!\u00a0<\/li>\n<li><strong>They must be automated: <\/strong>no manual execution of unit tests (has anyone really ever thought of doing that?\u00a0\ud83d\ude0a).\u00a0<\/li>\n<li><strong>Tests are clearly named and organised:<\/strong> today\u2019s frameworks make it possible to perfectly organise tests and encourage\u00a0you\u00a0to choose relevant names,\u00a0e.g.\u00a0<code>\"describe CONTEXT... it SHOULD DO THIS\"<\/code>\u00a0<\/li>\n<li><strong>Tests can be run on the developer\u2019s workstation:<\/strong> it must be possible to have a status of the unit tests without having to implement a complex mechanism of deployment \/ server startup etc.\u00a0<\/li>\n<li><strong>1 test = 1 use case<\/strong>. Ideally, only one assertion per unit test: this makes it possible to know right away what is wrong when a test is in error (in real life, we can afford several assertions to validate the boundaries of the same behaviour).\u00a0<\/li>\n<li><strong>The results of a unit test must be stable over time<\/strong>. The test that \u2018flashes\u2019:\u00a0a \u2018red\u2019 shot, a \u2018green\u2019 shot\u00a0is unreliable and must be modified or deleted!\u00a0<\/li>\n<li><strong>The tests must be isolated and independent :<\/strong> each test must be able to be executed, alone, and after or before any other test. Its proper functioning should not depend on the context provided by another test.\u00a0<\/li>\n<\/ul>\n<p>Other practices, however, should be <strong>avoided<\/strong>:\u00a0<\/p>\n<ul>\n<li><strong>Validating implementation details in a unit test:<\/strong> make sure that a method called with this parameter does not bring anything if it is not part of the behaviour of the code under test (for example, in the case of an orchestrator). This link with the implementation will make the test useless in case of refactoring the internal structure of the code: we will simply know that the implementation has been modified without knowing if the expected overall behaviour has been kept or not.\u00a0<\/li>\n<li><strong>Loading \u201ctoo much\u201d code for a unit test:<\/strong> this often depends on the design of the code, loading too much code is often a sign of too complex code or too little decoupled structures.\u00a0<\/li>\n<li><strong>Depend on external services: <\/strong>dependence on an external service will lead to a test sometimes in error, sometimes not, depending on the availability of this dependency. The use of\u00a0mocks (stub, spy, fake, mock)\u00a0is preferable to avoid this.\u00a0<\/li>\n<li><strong>Use try\u2026catch:<\/strong> in unit tests, we expect this or that specific error. We prefer (when the framework allows it) the assertion on the good triggering of an error.\u00a0<\/li>\n<\/ul>\n<p>I could list other good and bad practices, but I think it is already very effective to follow all these.\u00a0<\/p>\n<h2>What is the coverage? Where do you stop? <\/h2>\n<p>Depending on the context (legal obligations, company strategies, team guidelines\u2026), you can set objectives for code coverage by unit tests (lines, branches, conditions). But watch out! It is easy to achieve very good coverage without ensuring business rules are really covered by tests. <\/p>\n<p>I recently came across a file that seemed \u201cvery well tested\u201d: <\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"889\" height=\"65\" src=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-12.png\" alt=\"Example of a &quot;very well tested&quot; message\" class=\"wp-image-17681\" srcset=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-12.png 889w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-12-300x22.png 300w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-12-768x56.png 768w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-12-870x65.png 870w\" sizes=\"auto, (max-width: 889px) 100vw, 889px\"\/><\/figure>\n<\/div>\n<p>This same project, after a simple refactoring (method extraction) and a more extensive use of mocks in the tests fell to this level of coverage: <\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"70\" src=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-13.png\" alt=\"Example of a code that is not well tested\" class=\"wp-image-17682\" srcset=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-13.png 1024w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-13-300x21.png 300w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/image-13-768x53.png 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\"\/><\/figure>\n<\/div>\n<p>The tests in place had not evolved and the functional had not been extended: a simple reorganisation of the code and limitation of the code loaded by the tests showed that the job in this code was not as well tested as we thought! <\/p>\n<h3>So how do we proceed? How far do we go? <\/h3>\n<p>I quite like the point of view of Martin Fowler who advises (in his book \u201cRefactoring\u201d) to stop \u201cas soon as you are confident that, if someone comes to introduce a regression in the code you have just produced, one of the tests in place will fall into error\u201d. <\/p>\n<p>Beyond this mindset, the extent of the unit tests that we choose to implement may depend, in my opinion, on different parameters:<\/p>\n<ul>\n<li><strong>The risks incurred in the event of failure of the code concerned:<\/strong> a critical project for our customers recently saw the implementation of more than 500 unit tests for 699 lines of code (with a coverage of \u201conly\u201d 88.9% of the code).\u00a0<\/li>\n<li><strong>Long-term testing comfort management:<\/strong> a project for which we wanted to avoid costly maintenance operations at all costs (for reasons of internal team organisation) saw its branch coverage approach 100%.\u00a0<\/li>\n<li><strong>Personal appreciation\/team judgement:<\/strong> during code reviews carried out in teams, unit tests are also reviewed and the decision to have enough or not is a decision that is made by the whole team and may depend on the project, the context, the company\u2026\u00a0<\/li>\n<\/ul>\n<p>The main thing is to understand why the decision is made to stop (or continue to expand) testing. This decision must be conscious and informed to allow for a healthy life of the project over time.\u00a0<\/p>\n<h2>Design\u00a0<\/h2>\n<p>To avoid writing unnecessary tests or falling into an illusion of good coverage, it is important to design your unit tests well. For this I will distinguish two cases: designing tests on future code and designing tests on existing code (called \u201clegacy\u201d).\u00a0<\/p>\n<h3>Unit tests on new code <\/h3>\n<p>On the new code, we are lucky to have access to the desired behaviours: these are the behaviours to be implemented. We can then more easily define the unit test cases to implement, based on the acceptance criteria of the sprint backlog stories. We will proceed in 3 steps: <\/p>\n<p><strong>1.<\/strong> List the desired behaviours for a given work element.\u00a0<\/p>\n<ul>\n<li>Base them on the stories and their acceptance criteria.\u00a0<\/li>\n<li>Define input data sets and expected results.\u00a0<\/li>\n<\/ul>\n<p>This can be an opportunity to challenge the product owner to define certain behaviours more precisely, if necessary.\u00a0<\/p>\n<p><strong>2.<\/strong> Define the set of use cases for each behaviour or \u201cbusiness rule\u201d.\u00a0<\/p>\n<ul>\n<li>Passing cases\u00a0<\/li>\n<li>Error cases\u00a0<\/li>\n<li>Borderline cases\u00a0<\/li>\n<\/ul>\n<p>To do this, we can use different techniques for designing use cases such as decision trees (to go through all the paths in test cases) or equivalence classes (to avoid testing the same thing several times).\u00a0<\/p>\n<p><strong>3.<\/strong> Design the code to be able to test these behaviours (testable code).\u00a0<\/p>\n<ul>\n<li>Ideally in a \u201ctest first\u201d approach.\u00a0<\/li>\n<\/ul>\n<blockquote class=\"wp-block-quote\">\n<p><em>\u201cTDD is not a testing activity, it is a design activity\u201d (M. Fowler).<\/em>\u00a0<\/p>\n<\/blockquote>\n<h3>Unit testing on existing code <\/h3>\n<p>On existing code (or \u201clegacy\u201d), it is often more difficult to access the behaviours initially expected. It is then perilous to add unit tests when they are missing because we don\u2019t have access to the original specification. It is then difficult to get out of a vicious circle that nobody wants to enter: <\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/Circle-tests.jpg\" alt=\"Vicious circle of a development process\" class=\"wp-image-17683\" width=\"400\" height=\"276\" srcset=\"https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/Circle-tests.jpg 800w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/Circle-tests-300x207.jpg 300w, https:\/\/blog.atinternet.com\/wp-content\/uploads\/2020\/06\/Circle-tests-768x529.jpg 768w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\"\/><\/figure>\n<\/div>\n<h3>Reverse engineering <\/h3>\n<p>The most common approach (but also the least comfortable and most time-consuming) is to engage in a brave reverse engineering to try to re-discover the behaviour of the code. This may shed some light on how the code currently works, but it doesn\u2019t give us any information about the behaviour that is actually expected. User documentation can sometimes also help us \u2013 when it exists! <\/p>\n<h3>Taking advantage of developments <\/h3>\n<p>If we are in the presence of business users (product owner, product manager, development team, users\u2026), a request for evolution or the detection of a bug by a user can be an opportunity to review the business in place. <\/p>\n<h3>Use the current characteristics of the system as a basis <\/h3>\n<p>We can request the code with different input data sets and simply record the resulting outputs. These outputs will be used as \u2018expected behaviour\u2019 for further testing to ensure that the current behaviour (whether correct or not) is not altered by the changes we are going to make to the code. <\/p>\n<p>There is substantial literature on the subject, including Michael Feathers\u2019 \u201cWorking effectively with legacy code\u201d. <\/p>\n<h3>Mutation testing to identify gaps <\/h3>\n<p>When unit tests are already present and you want to extend the coverage of the business by testing, you can use mutation testing. This type of test consists of modifying the behaviour of the code by introducing \u201cmutants\u201d (certain conditions are modified, certain operators replaced by others, the body of certain branches emptied, etc.) and then running the existing unit tests to see if they detect the modification. <\/p>\n<p>If a unit test fails, the mutant has been \u201ckilled\u201d. Conversely, if no test fails, it means that the behaviour that has been changed is not within the scope of the unit tests in place: the mutant has \u201csurvived\u201d. <\/p>\n<p>This practice makes it possible, despite sometimes very good code coverage, to have a better view of whether the different behaviours in the code are covered or not. We can then prioritise the implementation of new unit tests on the code where the mutants have survived. Be careful however, the execution of these mutant tests is costly in machine time and can take a very long time: this is why we most often target certain carefully chosen files for these kinds of tests. <\/p>\n<h2>Code Testability <\/h2>\n<p>The question of code testability comes up fairly regularly when we talk about unit tests. The most recurring difficulties are described below. The simplest solution to these various issues is not to let them take hold, through the use of best practices or adapted tools: <\/p>\n<ul>\n<li><strong>Methods that are too complex to test:<\/strong> tools such as SonarQube ensure that \u201cacceptable\u201d complexities are not exceeded. The use of \u201cquality barriers\u201d even allows you to be alerted as soon as the code becomes too complex.\u00a0<\/li>\n<li><strong>Mocks that are too numerous and difficult to set up:<\/strong> the need for many mocks can be avoided by a different code structure. Good refactoring can make the code more easily testable and thus lead to tests that are simpler to design and implement.\u00a0<\/li>\n<li><strong>The need to load too much code to be able to test a behaviour:<\/strong> the TDD approach avoids having the behaviour too widespread in the code, diluted in many methods\/classes. Only what is needed to render a given behaviour is coded, no more and no less. Principles such as KISS (Keep It Stupid Simple) or YAGNI (You\u00a0Ain\u2019t\u00a0Gonna\u00a0Need It) also promote a good match between code structure and product behaviour.\u00a0<\/li>\n<\/ul>\n<p>Many refactoring techniques exist and are often integrated directly into the IDE (Extract method, extract variable, rename function etc\u2026). I recommend Martin Fowler\u2019s book \u201cRefactoring\u201d, which is a superb toolbox to modify\/improve\/upgrade any software code. <\/p>\n<p>Keep in mind that any code that seems difficult to test will also be difficult to maintain, evolve and be subject to many bugs throughout its life. <\/p>\n<h2>Conclusion <\/h2>\n<p>In conclusion, I would stress that unit tests, if they are well designed and written to validate system behaviour, are an efficient investment, even essential to ensure the comfort and profitability of projects over their entire lifecycle. They form the defence against many potential regressions in production and make maintenance or refactoring actions safe. <\/p>\n<p>At AT Internet, we have chosen to invest in this level of testing, by providing information, training, and support to the teams on the subject. We also encourage practices such as peer programming and code reviews (including test code) and listen to the teams to evaluate the problems encountered and spend time to find solutions. <\/p>\n<p>Photo credits:  <a rel=\"noreferrer noopener\" href=\"https:\/\/unsplash.com\/@stagfoo\" target=\"_blank\">Alex King<\/a> <\/p>\n<\/div>\n\n","protected":false},"excerpt":{"rendered":"<p>What are unit tests? Who is responsible for them? Why write them? Do we have enough of them? How do you design them? And what do you do with this hard-to-test code?\u00a0A wide range of\u00a0questions that I will try to answer below.\u00a0 This article is particularly aimed at developers who have questions or want to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":63373,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12033],"tags":[11079,12632,4505],"dealstore":[],"offerexpiration":[],"class_list":["post-63372","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-analytics","tag-invest","tag-testing","tag-unit"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Why invest in unit testing? - Som2ny Network<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fivemor.com\/?p=63372\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Why invest in unit testing? - Som2ny Network\" \/>\n<meta property=\"og:description\" content=\"What are unit tests? Who is responsible for them? Why write them? Do we have enough of them? How do you design them? And what do you do with this hard-to-test code?\u00a0A wide range of\u00a0questions that I will try to answer below.\u00a0 This article is particularly aimed at developers who have questions or want to [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fivemor.com\/?p=63372\" \/>\n<meta property=\"og:site_name\" content=\"Som2ny Network\" \/>\n<meta property=\"article:published_time\" content=\"2025-02-02T02:06:20+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/Unit-testing-image-scaled.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1707\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"19 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fivemor.com\/?p=63372#article\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/?p=63372\"},\"author\":{\"name\":\"admin\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371\"},\"headline\":\"Why invest in unit testing?\",\"datePublished\":\"2025-02-02T02:06:20+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=63372\"},\"wordCount\":3827,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fivemor.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=63372#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/Unit-testing-image-scaled.jpg\",\"keywords\":[\"Invest\",\"Testing\",\"Unit\"],\"articleSection\":[\"Analytics\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fivemor.com\/?p=63372#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fivemor.com\/?p=63372\",\"url\":\"https:\/\/fivemor.com\/?p=63372\",\"name\":\"Why invest in unit testing? - Som2ny Network\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=63372#primaryimage\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=63372#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/Unit-testing-image-scaled.jpg\",\"datePublished\":\"2025-02-02T02:06:20+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fivemor.com\/?p=63372#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fivemor.com\/?p=63372\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/?p=63372#primaryimage\",\"url\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/Unit-testing-image-scaled.jpg\",\"contentUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/Unit-testing-image-scaled.jpg\",\"width\":2560,\"height\":1707},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fivemor.com\/?p=63372#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/fivemor.com\/?bp_activities=1\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Why invest in unit testing?\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fivemor.com\/#website\",\"url\":\"https:\/\/fivemor.com\/\",\"name\":\"Som2ny Network\",\"description\":\"Daily Deals\",\"publisher\":{\"@id\":\"https:\/\/fivemor.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fivemor.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/fivemor.com\/#organization\",\"name\":\"Som2ny Network\",\"url\":\"https:\/\/fivemor.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png\",\"contentUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png\",\"width\":300,\"height\":86,\"caption\":\"Som2ny Network\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png\",\"caption\":\"admin\"},\"sameAs\":[\"https:\/\/fivemor.com\"],\"url\":\"https:\/\/fivemor.com\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Why invest in unit testing? - Som2ny Network","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fivemor.com\/?p=63372","og_locale":"en_US","og_type":"article","og_title":"Why invest in unit testing? - Som2ny Network","og_description":"What are unit tests? Who is responsible for them? Why write them? Do we have enough of them? How do you design them? And what do you do with this hard-to-test code?\u00a0A wide range of\u00a0questions that I will try to answer below.\u00a0 This article is particularly aimed at developers who have questions or want to [&hellip;]","og_url":"https:\/\/fivemor.com\/?p=63372","og_site_name":"Som2ny Network","article_published_time":"2025-02-02T02:06:20+00:00","og_image":[{"width":2560,"height":1707,"url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/Unit-testing-image-scaled.jpg","type":"image\/jpeg"}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"admin","Est. reading time":"19 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fivemor.com\/?p=63372#article","isPartOf":{"@id":"https:\/\/fivemor.com\/?p=63372"},"author":{"name":"admin","@id":"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371"},"headline":"Why invest in unit testing?","datePublished":"2025-02-02T02:06:20+00:00","mainEntityOfPage":{"@id":"https:\/\/fivemor.com\/?p=63372"},"wordCount":3827,"commentCount":0,"publisher":{"@id":"https:\/\/fivemor.com\/#organization"},"image":{"@id":"https:\/\/fivemor.com\/?p=63372#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/Unit-testing-image-scaled.jpg","keywords":["Invest","Testing","Unit"],"articleSection":["Analytics"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fivemor.com\/?p=63372#respond"]}]},{"@type":"WebPage","@id":"https:\/\/fivemor.com\/?p=63372","url":"https:\/\/fivemor.com\/?p=63372","name":"Why invest in unit testing? - Som2ny Network","isPartOf":{"@id":"https:\/\/fivemor.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/fivemor.com\/?p=63372#primaryimage"},"image":{"@id":"https:\/\/fivemor.com\/?p=63372#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/Unit-testing-image-scaled.jpg","datePublished":"2025-02-02T02:06:20+00:00","breadcrumb":{"@id":"https:\/\/fivemor.com\/?p=63372#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fivemor.com\/?p=63372"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/?p=63372#primaryimage","url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/Unit-testing-image-scaled.jpg","contentUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/Unit-testing-image-scaled.jpg","width":2560,"height":1707},{"@type":"BreadcrumbList","@id":"https:\/\/fivemor.com\/?p=63372#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/fivemor.com\/?bp_activities=1"},{"@type":"ListItem","position":2,"name":"Why invest in unit testing?"}]},{"@type":"WebSite","@id":"https:\/\/fivemor.com\/#website","url":"https:\/\/fivemor.com\/","name":"Som2ny Network","description":"Daily Deals","publisher":{"@id":"https:\/\/fivemor.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fivemor.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/fivemor.com\/#organization","name":"Som2ny Network","url":"https:\/\/fivemor.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/#\/schema\/logo\/image\/","url":"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png","contentUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png","width":300,"height":86,"caption":"Som2ny Network"},"image":{"@id":"https:\/\/fivemor.com\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371","name":"admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png","caption":"admin"},"sameAs":["https:\/\/fivemor.com"],"url":"https:\/\/fivemor.com\/?author=1"}]}},"_links":{"self":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts\/63372","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=63372"}],"version-history":[{"count":0,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts\/63372\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/media\/63373"}],"wp:attachment":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=63372"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=63372"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=63372"},{"taxonomy":"dealstore","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fdealstore&post=63372"},{"taxonomy":"offerexpiration","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fofferexpiration&post=63372"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}