{"id":5002,"date":"2022-03-29T07:08:10","date_gmt":"2022-03-29T14:08:10","guid":{"rendered":"https:\/\/coderpad.io\/?p=5002"},"modified":"2023-06-05T14:28:33","modified_gmt":"2023-06-05T21:28:33","slug":"integration-tests-vs-unit-tests-integration-matters-more","status":"publish","type":"post","link":"https:\/\/coderpad.io\/blog\/development\/integration-tests-vs-unit-tests-integration-matters-more\/","title":{"rendered":"Integration Tests vs. Unit Tests: Why Integration Tests Matter More"},"content":{"rendered":"\n<p>In the hierarchy of things developers like to do, writing tests falls at about the \u201cnecessary evil\u201d level. Like eating a heaping pile of spinach, we know it\u2019s good for us\u2013but getting motivated to do it can be a struggle. Of course running the proper tests saves us a whole lot of time and money fixing bugs down the line, but even then there are usually a million other things we\u2019d rather do than write tests.<\/p>\n\n\n\n<p>Luckily for us, many other software developers also didn\u2019t like doing it, so they created lots of automated testing tools to make it easier. These days you can find a tool for just about any testing type and programming language.&nbsp;&nbsp;<\/p>\n\n\n\n<p>For end-to-end testing you have your choice of tools like <a href=\"http:\/\/cypress.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">Cypress<\/a>, <a href=\"https:\/\/github.com\/puppeteer\/puppeteer\" target=\"_blank\" rel=\"noopener\">Pupp<\/a><a href=\"https:\/\/github.com\/puppeteer\/puppeteer\" target=\"_blank\" rel=\"noreferrer noopener\">e<\/a><a href=\"https:\/\/github.com\/puppeteer\/puppeteer\" target=\"_blank\" rel=\"noopener\">teer<\/a>, <a href=\"https:\/\/webdriver.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">Webdriver<\/a>, and <a href=\"https:\/\/www.selenium.dev\/\" target=\"_blank\" rel=\"noreferrer noopener\">Selenium<\/a>.<\/p>\n\n\n\n<p>Unit, integration, and static testing tools tend to be more language-specific. Popular tools like <a href=\"https:\/\/junit.org\/junit5\/\" target=\"_blank\" rel=\"noreferrer noopener\">JUnit<\/a>, <a href=\"https:\/\/jestjs.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">Jest<\/a>, <a href=\"https:\/\/pylint.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">pylint<\/a>, <a href=\"https:\/\/mochajs.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">mocha<\/a>, and <a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/test\/?view=vs-2022\" target=\"_blank\" rel=\"noreferrer noopener\">Visual Studio\u2019s built-in unit test feature<\/a> make it easier to automate your testing set-up.&nbsp;<\/p>\n\n\n\n<p>But no matter which tools you decide to use, it\u2019s essential to know how &#8212; <em>and when<\/em> &#8212; to use them.&nbsp;<\/p>\n\n\n<aside class=\"\n    cta-banner\n     cta-banner--bg-blue      cta-banner--has-media \"\ndata-block-name=\"cta-banner\">\n    <div class=\"inner\">\n        <div class=\"content\">\n                            <h2 class=\"headline\">Learn how to run front-end developer interviews that don&#8217;t suck<\/h2>\n            \n                            <div class=\"cta-buttons\">\n                                    <a href=\"https:\/\/coderpad.io\/blog\/interviewing\/5-tips-for-interviewing-frontend\/\" class=\"button  js-cta--read-our-guide\" data-ga-category=\"CTA\" data-ga-label=\"Learn how to run front-end developer interviews that don&#039;t suck|Read our guide\">Read our guide<\/a>\n                                <\/div>\n                    <\/div>\n                    <div class=\"media\">\n                <img loading=\"lazy\" decoding=\"async\" width=\"432\" height=\"342\" src=\"https:\/\/coderpad.io\/wp-content\/uploads\/2022\/08\/Illustration-of-man-with-beard-popping-out-of-computer-chat.png\" class=\"attachment-large size-large\" alt=\"\" srcset=\"https:\/\/coderpad.io\/wp-content\/uploads\/2022\/08\/Illustration-of-man-with-beard-popping-out-of-computer-chat.png 432w, https:\/\/coderpad.io\/wp-content\/uploads\/2022\/08\/Illustration-of-man-with-beard-popping-out-of-computer-chat-300x238.png 300w\" sizes=\"auto, (max-width: 432px) 100vw, 432px\" \/>\n            <\/div>\n            <\/div>\n<\/aside>\n\n\n\n<h2 class=\"wp-block-heading\">Different tests for different purposes<\/h2>\n\n\n\n<p>Usually, the choice between what test to use boils down to the tradeoffs between the time\/costs of running that test and your confidence in the test results. We\u2019ve graded four testing types\u2014end-to-end, integration, unit, and static\u2014on a scale of 1-4 \ud83d\udcb2(cost\/time) and \ud83d\udc4d(confidence) to help you understand when to deploy each.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">End-to-end testing&nbsp;<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong>Cost\/Time<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>|<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>Confidence<\/strong><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><br>\ud83d\udcb2\ud83d\udcb2\ud83d\udcb2\ud83d\udcb2<\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>|<br>|<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><br>\ud83d\udc4d\ud83d\udc4d\ud83d\udc4d\ud83d\udc4d<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>End-to-end testing tests the application from start to finish. It tests the entire user journey of an application, mimicking the quality issues a user might encounter while trying to carry out an action in your application. Generally, these tests are the most time &amp; money intensive but will also <a href=\"https:\/\/kentcdodds.com\/blog\/write-tests\" target=\"_blank\" rel=\"noreferrer noopener\">give you the most confidence<\/a> that your application won\u2019t bug out on users.<\/p>\n\n\n\n<p>End-to-end tests are expensive because they require more heavily powered servers to spin up and take longer to complete (time = money).<br><br>They take so much longer because instead of mocking out the backend, they make calls against a real server. While this is good because it can catch a lot, it\u2019s bad because if an end-to-end test fails, it may not be because of the frontend\u2019s code but maybe because the backend is having problems.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Integration testing<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong>Cost\/Time<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>|<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>Confidence<\/strong><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><br>\ud83d\udcb2\ud83d\udcb2\ud83d\udcb2 <\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>|<br>|<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><br>\ud83d\udc4d\ud83d\udc4d\ud83d\udc4d<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Integration testing tests interactions between components \u2013 think between backend services or components in a frontend framework.&nbsp;&nbsp;<\/p>\n\n\n\n<p>These tests are necessary to make sure components work correctly together \u2013 your unit tests may show that each part works correctly, but there may be data or logic errors that only show up when the components are tested outside of isolation.<\/p>\n\n\n\n<p>Integration tests are cheaper since you can spin up a <strong>much<\/strong> lighter process&nbsp; to run the test but still catch many potential issues. We\u2019ll discuss more why you should focus on integration testing below.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Unit testing<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong>Cost\/Time<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>|<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>Confidence<\/strong><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><br>\ud83d\udcb2\ud83d\udcb2<\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>|<br>|<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><br>\ud83d\udc4d\ud83d\udc4d<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Unit tests don\u2019t test integration with any other part of the code but instead centralize on a specific bit of code and make sure a particular set of inputs match a set of outputs \u2013 <a href=\"https:\/\/smartbear.com\/learn\/automated-testing\/what-is-unit-testing\/\" target=\"_blank\" rel=\"noreferrer noopener\">like conditional logic and function calls.<\/a><\/p>\n\n\n\n<p>Because of this focus on smaller bits of logic and data processes, they\u2019re great for testing libraries.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Static testing<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong>Cost\/Time<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>|<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>Confidence<\/strong><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><br>\ud83d\udcb2<\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>|<\/strong><br><strong>|<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><br>\ud83d\udc4d<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Static testing is your basic linting or static code analysis. It helps you find fundamental issues like typos and missing characters. Static tests are the quickest and cheapest test to run but won\u2019t give you much confidence in the quality of the entire application.&nbsp;<\/p>\n\n\n\n<p>Static tests are commonplace and utilized in almost every IDE and every language.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The understated importance of integration testing<\/h2>\n\n\n\n<p>Prominent software engineers like Kent C. Dodds of Remix.run and  Guillermo Rauch of Vercel advocate for a bigger emphasis on integration tests since they cost less than end-to-end testing but cover more than unit tests.&nbsp;<\/p>\n\n\n\n<p>To help explain his viewpoint, Dodds created the \u201ctesting trophy\u201d \u2013 an updated version of <a href=\"https:\/\/martinfowler.com\/bliki\/TestPyramid.html\" target=\"_blank\" rel=\"noreferrer noopener\">Martin Fowler\u2019s \u201ctesting pyramid.\u201d<\/a><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/03\/img_623c8e4bbc328.png\" alt=\"testing pyramid with e2e at top integration tests at middle and unit tests at bottom\" width=\"298\" height=\"280\"><\/td><td class=\"has-text-align-center\" data-align=\"center\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/03\/img_623c8e4d68668.png\" alt=\"testing trophy with static tests at bottom then unit tests then large section of integration tests and then e2e small at the top\" width=\"298\" height=\"296\"><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong>Testing Pyramid<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>Testing Trophy<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Fowler\u2019s pyramid is pretty well known \u2013 it shows that as costs rise, the speed of a test tends to decline, hence why many developers minimize E2E testing and maximize unit testing. The testing trophy, on the other hand, is a bit less obvious, so here\u2019s how Dodds describes it:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p><em>The general idea is that you get *great* value for the cost out of static analysis tools and integration tests. Then you get *good* value out of unit and e2e tests. Use them all<\/em>.<\/p><cite><a href=\"https:\/\/twitter.com\/kentcdodds\/status\/960723176031272962\" target=\"_blank\" rel=\"noreferrer noopener\">Kent C. Dodds<\/a><\/cite><\/blockquote>\n\n\n\n<p>Part of the great value of integration tests is that they still test user behavior like end-to-end tests. Users will <em>rarely<\/em> be using components in isolation, rather most software runs as a series of interactions among different components &#8212; and it&#8217;s exactly these interactions that integration testing is verifying. This makes them a confidence improvement on unit tests, which simply test inputs and outputs of a particular piece of logic. Or, to put it another way:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p><em>It doesn&#8217;t matter if your component &lt;A \/&gt; renders component &lt;B \/&gt; with props c and d if component &lt;B \/&gt; actually breaks if prop e is not supplied. So while having some unit tests to verify these pieces work in isolation isn&#8217;t a bad thing, it doesn&#8217;t do you any good if you don&#8217;t also verify that they work together properly. And you&#8217;ll find that by testing that they work together properly, you often don&#8217;t need to bother testing them in isolation.<\/em><\/p><cite><a href=\"https:\/\/kentcdodds.com\/blog\/write-tests\" target=\"_blank\" rel=\"noreferrer noopener\">Kent C. Dodds<\/a><\/cite><\/blockquote>\n\n\n\n<p>Of course, this is only true of well-written integration tests.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What makes a good integration test?<\/h2>\n\n\n\n<p>You should try to mock out as little as possible with good integration tests. You want to maximize the amount of application functionality that you test.<\/p>\n\n\n\n<p>This is not a natural testing inclination, especially if most of your testing experience has been in unit testing. A notable example of this in frontend development is the predisposition to creating <a href=\"https:\/\/enzymejs.github.io\/enzyme\/docs\/api\/shallow.html\" target=\"_blank\" rel=\"noreferrer noopener\">\u201cShallow Render\u201d tests<\/a>.<\/p>\n\n\n\n<p>Shallow Render tests only test a single component rather than the interaction of multiple elements on a screen. But this tends to be bad practice since it won\u2019t catch issues with the integration between multiple components.<\/p>\n\n\n\n<p>If you\u2019re one of the developers with a bias towards mocking and shallow rendering, you\u2019ll have to pay extra attention to make sure that your integration tests actually test interactions between your different components.&nbsp;<\/p>\n\n\n\n<p>There\u2019s a trend towards emphasizing integration tests as part of an overall testing framework, and there\u2019s a good reason it\u2019s not going away anytime soon:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>Integration tests strike a great balance on the trade-offs between confidence and speed\/expense. This is why it&#8217;s advisable to spend most (not all, mind you) of your effort there.<\/p><cite>&nbsp;<a href=\"https:\/\/kentcdodds.com\/blog\/write-tests\" target=\"_blank\" rel=\"noreferrer noopener\">Kent C. Dodds<\/a><\/cite><\/blockquote>\n\n\n\n<p>A comprehensive testing strategy will use a combination of the four different testing types; however, it\u2019s hard to beat the bang-for-the-buck that integration tests provide.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Unit tests are good, but integration tests may be better for testing what really matters.<\/p>\n","protected":false},"author":12,"featured_media":5190,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[9],"tags":[],"persona":[29],"blog-programming-language":[],"keyword-cluster":[],"class_list":["post-5002","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development"],"acf":[],"_links":{"self":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/5002","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/comments?post=5002"}],"version-history":[{"count":43,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/5002\/revisions"}],"predecessor-version":[{"id":7852,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/5002\/revisions\/7852"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/media\/5190"}],"wp:attachment":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/media?parent=5002"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/categories?post=5002"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/tags?post=5002"},{"taxonomy":"persona","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/persona?post=5002"},{"taxonomy":"blog-programming-language","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/blog-programming-language?post=5002"},{"taxonomy":"keyword-cluster","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/keyword-cluster?post=5002"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}