{"id":6913,"date":"2023-01-10T13:09:52","date_gmt":"2023-01-10T05:09:52","guid":{"rendered":"https:\/\/slash.bravefactor.com\/?post_type=resources&#038;p=6913"},"modified":"2024-01-30T16:11:35","modified_gmt":"2024-01-30T08:11:35","slug":"the-software-testing-pyramid","status":"publish","type":"resources","link":"https:\/\/slash.co\/articles\/the-software-testing-pyramid","title":{"rendered":"The software testing pyramid"},"content":{"rendered":"<h2><span style=\"font-weight: 500;\">3 key layers <\/span><\/h2>\n<p><span style=\"font-weight: 400;\"><br \/>\nNothing is perfect, or so the saying goes. Everything can always be improved upon and try as we may, nothing is devoid of flaws or defects in regards to manufactured products. Software is no different, it\u2019s a product subject to the same imperfections other products experience. We of course, are referring to the much dreaded software bugs. Those little programming hiccups and imperfections that demand attention before wreaking havoc.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Just like any product, software is subject to a QC\/QA process to verify quality, but also confirm there are no bugs present in the code. In steps software testing. Testing is vital to delivering bug free code and reducing or hopefully eliminating the negative ramifications of uncaught bugs. Software bugs can cost money and even lives. Two examples come to mind:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">In 1985, a software bug caused Canada\u2019s Therac-25 radiation therapy machine to malfunction, delivering lethal doses of radiation to patients resulting in the deaths of 3 people.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">In April of 1999, a software bug caused the failure of a $1.2 billion military satellite launch, the costliest accident in history.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">So clearly , testing is important. Whether you\u2019re testing software for some corporate enterprise solution, public mass transport system, online banking or other, the tests should not be taken lightly.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">A testing pyramid is a framework that can assist both developers and QA engineers in building high-quality software. It minimizes the amount of time required for developers to determine if an update they made affects the code. It also aids in developing a more robust test suite.<\/span><\/p>\n<p><img fetchpriority=\"high\" decoding=\"async\" class=\"size-medium wp-image-7096 aligncenter\" src=\"https:\/\/slash.co\/wp-content\/uploads\/2023\/01\/1-385x324.png\" alt=\"1\" width=\"385\" height=\"324\" title=\"\"><\/p>\n<p style=\"text-align: center;\"><span style=\"font-weight: 400;\">Khorikov,V. (2020) Unit Testing Principles, Practices and Patterns. Page 87<\/span><\/p>\n<p><span style=\"font-weight: 400;\">As you can see from what the image above suggests, the layer width corresponds directly with the amount of testing. Additionally, the height <\/span><span style=\"font-weight: 400;\">is a measure of how close the tests are to emulating end user behavior. The layers represent three different tests:<\/span><\/p>\n<ul>\n<li><strong>Unit tests<\/strong><span style=\"font-weight: 400;\"> \u2013 find logical errors at the most fundamental level. They are fast and require very few resources to run.<\/span><\/li>\n<li><b>Integration tests<\/b><span style=\"font-weight: 400;\"> \u2013 verify that services and databases work well together with the code and the written classes. They can only find problems at the interfaces where two or more components meet.<\/span><\/li>\n<li><b>End-to-end (E2E) tests<\/b><span style=\"font-weight: 400;\"> \u2013 depend on the complete application being able to start. These are the most comprehensive type of tests\u00a0 and therefore, require the most computing resources and time to run.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">Let\u2019s look at each layer individually to better understand the purpose they serve.<\/span><\/p>\n<h2><span style=\"font-weight: 500;\">Unit testing<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">The testing begins with unit tests which are very low level and close to the source of an application. The procedure consists of testing individual methods and functions of the classes, components, or modules used by the software. The key goal here is to isolate and focus on testing the code where all external dependencies are replaced with pre-programmed behavior, ensuring that the test\u2019s outcome is only determined by the correctness of the unit being tested. Unit tests are generally quite cheap to automate and can be executed quickly by a continuous integration server. The drawback, however, is that unit tests cannot cover the interaction between dependencies; therefore, integration tests become beneficial at that point.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For a simple example, consider you have a function called \u201cgetPopularMovies.\u201d This function will call an API to get a list of movies and the top three records to return as popular movies. In this case, we need to mock the API call and only test the popular movie logic.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">So what is good unit testing? That is without a doubt the Arrange-Assert-Act (AAA) test pattern process. This three step process allows you to first \u201carrange\u201d or establish the conditions needed for the second \u201cact\u201d step to manage while you \u201cassert\u201d or confirm the expected results were reached in the final step.<\/span><\/p>\n<p style=\"text-align: right;\"><i><span style=\"font-weight: 400;\">File: movies.js<\/span><\/i><\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-7097 aligncenter lazyload\" data-src=\"https:\/\/slash.co\/wp-content\/uploads\/2023\/01\/2.png\" alt=\"2\" width=\"340\" height=\"438\" title=\"\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 340px; --smush-placeholder-aspect-ratio: 340\/438;\"><\/p>\n<p style=\"text-align: right;\"><i><span style=\"font-weight: 400;\">File: movies.test.js<\/span><\/i><\/p>\n<p><img decoding=\"async\" class=\"size-medium wp-image-7098 aligncenter lazyload\" data-src=\"https:\/\/slash.co\/wp-content\/uploads\/2023\/01\/3-385x350.png\" alt=\"3\" width=\"385\" height=\"350\" title=\"\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 385px; --smush-placeholder-aspect-ratio: 385\/350;\"><\/p>\n<h2><span style=\"font-weight: 500;\">Integration testing<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Moving up the pyramid we come to integration testing. Integration tests verify that different modules or services used by the application work well together.\u00a0Obviously there are many moving parts behind the scenes when the software is working so it\u2019s key to ensure all those parts are playing nice and getting along. Integration tests are quite useful for small systems especially as they deliver quick results. That being said, there are some limitations to them as well. It can be more difficult to locate faults, riskier modules don\u2019t receive concentrated attention and there is always a possibility of missing a module.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Now for example, let\u2019s consider you are testing the interaction with the API and confirming that the third party API works together as expected.\u00a0In this case, we test the \u201cgetPopularMovies\u201d call to the real API. If we give the code the same parameters and it works correctly, then it has passed. This groups together two or more modules of an application to ensure they function collectively. This type of testing also reveals the interface, communication and data flow defects between modules.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">These types of tests are more expensive to run as they require multiple parts of the application to be up and running; therefore, this testing cannot begin early. Additionally, mock function testing is not used as use of the external library itself is necessary.<\/span><\/p>\n<p style=\"text-align: right;\"><i><span style=\"font-weight: 400;\">File: movies.integration.test.js<\/span><\/i><\/p>\n<p><img decoding=\"async\" class=\"wp-image-7099 aligncenter lazyload\" data-src=\"https:\/\/slash.co\/wp-content\/uploads\/2023\/01\/4-385x150.png\" alt=\"4\" width=\"429\" height=\"167\" title=\"\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 429px; --smush-placeholder-aspect-ratio: 429\/167;\"><\/p>\n<h2><span style=\"font-weight: 500;\">End-to-end testing<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Finally we reach the peak of the pyramid, the ultimate test of code excellence. End-to-end testing replicates a user behavior with the software in a complete application environment.\u00a0E2E tests verify that various user flows work as expected; this can be as simple as loading a web page, logging in, or much more complex scenarios like verifying email notifications, online payments and so on. The goal is to mimic how the software works in real life through executing typical user scenarios and subsequently noting any and all errors that occur.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">End-to-end tests are very useful, but they&#8217;re expensive to perform and can be hard to maintain when they&#8217;re automated. It is recommended to have a few key E2E tests and rely more on lower level types of testing (unit and integration tests) to be able to quickly identify breaking changes. There are some major JS frameworks for E2E testing such as Cypress, TestCafe, NightwatchJS, Protractor, Webdriver JS and so on which can be utilized.<\/span><\/p>\n<p><img decoding=\"async\" class=\"size-medium wp-image-7100 aligncenter lazyload\" data-src=\"https:\/\/slash.co\/wp-content\/uploads\/2023\/01\/5-385x183.png\" alt=\"5\" width=\"385\" height=\"183\" title=\"\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 385px; --smush-placeholder-aspect-ratio: 385\/183;\"><\/p>\n<p style=\"text-align: center;\"><span style=\"font-weight: 400;\">Khorikov,V. (2020) Unit Testing Principles, Practices and Patterns. Page 6<\/span><\/p>\n<p><span style=\"font-weight: 400;\">To summarize, the value of testing should be obvious and as a result, demand an appropriate amount of attention paid to it. <\/span><span style=\"font-weight: 400;\">It is more expensive to fix a bug at the end of the project than during; the later you find the issue, the more costly it will be to fix. The software industry is not the automotive industry, we can be releasing our products to then only be forced to recall them to correct issues we should have caught before it went out the door. When you find an issue post production, it costs time &amp; money for a developer to find &amp; report the bug; plus, if considerable enough time has passed before something goes wrong, you may lose business value so the earlier you detect and correct, the better!<\/span><\/p>\n","protected":false},"featured_media":11866,"parent":0,"template":"","resource-topic":[],"resource-type":[43],"class_list":["post-6913","resources","type-resources","status-publish","has-post-thumbnail","hentry","resource-type-articles"],"_links":{"self":[{"href":"https:\/\/slash.co\/wp-json\/wp\/v2\/resources\/6913","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/slash.co\/wp-json\/wp\/v2\/resources"}],"about":[{"href":"https:\/\/slash.co\/wp-json\/wp\/v2\/types\/resources"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/slash.co\/wp-json\/wp\/v2\/media\/11866"}],"wp:attachment":[{"href":"https:\/\/slash.co\/wp-json\/wp\/v2\/media?parent=6913"}],"wp:term":[{"taxonomy":"resource-topic","embeddable":true,"href":"https:\/\/slash.co\/wp-json\/wp\/v2\/resource-topic?post=6913"},{"taxonomy":"resource-type","embeddable":true,"href":"https:\/\/slash.co\/wp-json\/wp\/v2\/resource-type?post=6913"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}