<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://web.dev/</id>
  <title>Ramona Schwering on web.dev</title>
  <updated>2026-04-15T23:21:06Z</updated>
  <author>
    <name>Ramona Schwering</name>
  </author>
  <link href="https://web.dev/authors/ramona/feed.xml" rel="self"/>
  <link href="https://web.dev/"/>
  <icon>https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/JjZvG1rUMq9DRil4MnIT.jpeg?auto=format</icon>
  <logo>https://web.dev/images/shared/rss-banner.png</logo>
  <subtitle>A frontend developer who ❤️ Test Automation and JavaScript.</subtitle>
  
  
  <entry>
    <title>Four common types of code coverage</title>
    <link href="https://web.dev/ta-code-coverage/"/>
    <updated>2023-09-06T00:00:00Z</updated>
    <id>https://web.dev/ta-code-coverage/</id>
    <content type="html" mode="escaped">&lt;p&gt;Have you heard the phrase &amp;quot;code coverage&amp;quot;? In this post, we will explore what code coverage in tests is and four common ways to measure it.&lt;/p&gt;
&lt;h2 id=&quot;what-is-code-coverage&quot;&gt;What is code coverage? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-code-coverage/#what-is-code-coverage&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Code coverage is a metric that measures the percentage of source code your tests execute. It helps you identify areas that may lack proper testing.&lt;/p&gt;
&lt;p&gt;Often, recording these metrics looks like this:&lt;/p&gt;
&lt;style type=&quot;text/css&quot;&gt;
  .tg {
    border: 1px solid var(--color-stroke);
  }

  .tg tbody {
    background-color: var(--color-mid-bg);
  }
  .tg-zo2y span {
    color: var(--color-state-bad-text);
  }
  .tg-bsyc span {
    color: var(--color-state-good-text);
  }
  .tg-kfug span {
    color: var(--color-state-warn-text);
  }
&lt;/style&gt;
&lt;table class=&quot;tg&quot;&gt;
&lt;thead&gt;
  &lt;tr&gt;
    &lt;th class=&quot;tg-1wig&quot;&gt;&lt;span&gt;File&lt;/span&gt;&lt;/th&gt;
    &lt;th class=&quot;tg-1wig&quot;&gt;&lt;span&gt;% Statements&lt;/span&gt;&lt;/th&gt;
    &lt;th class=&quot;tg-1wig&quot;&gt;&lt;span&gt;% Branch&lt;/span&gt;&lt;/th&gt;
    &lt;th class=&quot;tg-1wig&quot;&gt;&lt;span&gt;% Functions&lt;/span&gt;&lt;/th&gt;
    &lt;th class=&quot;tg-1wig&quot;&gt;&lt;span&gt;% Lines&lt;/span&gt;&lt;/th&gt;
    &lt;th class=&quot;tg-1wig&quot;&gt;&lt;span&gt;Uncovered lines&lt;/span&gt;&lt;/th&gt;
  &lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
  &lt;tr&gt;
    &lt;td class=&quot;tg-0lax&quot;&gt;&lt;span&gt;file.js&lt;/span&gt;&lt;/td&gt;
    &lt;td class=&quot;tg-bsyc&quot;&gt;&lt;span&gt;90%&lt;/span&gt;&lt;/td&gt;
    &lt;td class=&quot;tg-bsyc&quot;&gt;&lt;span&gt;100%&lt;/span&gt;&lt;/td&gt;
    &lt;td class=&quot;tg-bsyc&quot;&gt;&lt;span&gt;90%&lt;/span&gt;&lt;/td&gt;
    &lt;td class=&quot;tg-bsyc&quot;&gt;&lt;span&gt;80%&lt;/span&gt;&lt;/td&gt;
    &lt;td class=&quot;tg-zo2y&quot;&gt;&lt;span&gt;89,256&lt;/span&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td class=&quot;tg-0lax&quot;&gt;&lt;span&gt;coffee.js&lt;/span&gt;&lt;/td&gt;
    &lt;td class=&quot;tg-kfug&quot;&gt;&lt;span&gt;55.55%&lt;/span&gt;&lt;/td&gt;
    &lt;td class=&quot;tg-bsyc&quot;&gt;&lt;span&gt;80%&lt;/span&gt;&lt;/td&gt;
    &lt;td class=&quot;tg-kfug&quot;&gt;&lt;span&gt;50%&lt;/span&gt;&lt;/td&gt;
    &lt;td class=&quot;tg-kfug&quot;&gt;&lt;span&gt;62.5%&lt;/span&gt;&lt;/td&gt;
    &lt;td class=&quot;tg-zo2y&quot;&gt;&lt;span&gt;10-11, 18&lt;/span&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;As you add new features and tests, increasing code coverage percentages can give you more confidence that your application has been thoroughly tested. However, there is more to discover.&lt;/p&gt;
&lt;h2 id=&quot;four-common-types-of-code-coverage&quot;&gt;Four common types of code coverage &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-code-coverage/#four-common-types-of-code-coverage&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are four common ways to collect and calculate code coverage: function, line, branch, and statement coverage.&lt;/p&gt;
&lt;img alt=&quot;Four types of text coverage.&quot; decoding=&quot;async&quot; height=&quot;449&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/W9iaHL2YtKeBz5vRmWFQ.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/W9iaHL2YtKeBz5vRmWFQ.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/W9iaHL2YtKeBz5vRmWFQ.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/W9iaHL2YtKeBz5vRmWFQ.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/W9iaHL2YtKeBz5vRmWFQ.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/W9iaHL2YtKeBz5vRmWFQ.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/W9iaHL2YtKeBz5vRmWFQ.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/W9iaHL2YtKeBz5vRmWFQ.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/W9iaHL2YtKeBz5vRmWFQ.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/W9iaHL2YtKeBz5vRmWFQ.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/W9iaHL2YtKeBz5vRmWFQ.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/W9iaHL2YtKeBz5vRmWFQ.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/W9iaHL2YtKeBz5vRmWFQ.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/W9iaHL2YtKeBz5vRmWFQ.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/W9iaHL2YtKeBz5vRmWFQ.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/W9iaHL2YtKeBz5vRmWFQ.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/W9iaHL2YtKeBz5vRmWFQ.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/W9iaHL2YtKeBz5vRmWFQ.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;To see how each type of code coverage calculates its percentage, consider the following code example for calculating coffee ingredients:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* coffee.js */&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calcCoffeeIngredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;coffeeName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cup &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; espresso&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; water&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;coffeeName &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;espresso&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    espresso &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; cup&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; espresso &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;coffeeName &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;americano&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    espresso &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; cup&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; water &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;70&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; cup&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; espresso&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; water &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;isValidCoffee&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;espresso&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;americano&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;mocha&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;includes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;The tests that verify the &lt;code&gt;calcCoffeeIngredient&lt;/code&gt; function are:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* coffee.test.js */&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; describe&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; expect&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; assert&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; it &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;vitest&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; calcCoffeeIngredient &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;../src/coffee-incomplete&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Coffee&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;should have espresso&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calcCoffeeIngredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;espresso&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;deep&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;espresso&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;should have nothing&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calcCoffeeIngredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;unknown&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;deep&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;You can run the code and tests on this &lt;a href=&quot;https://stackblitz.com/edit/vitest-coffee-coverage?file=README.md&quot; rel=&quot;noopener&quot;&gt;live demo&lt;/a&gt; or check out the &lt;a href=&quot;https://github.com/leichteckig/vitest-coffee-example&quot; rel=&quot;noopener&quot;&gt;repository&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;function-coverage&quot;&gt;Function coverage &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-code-coverage/#function-coverage&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Code coverage: 50%&lt;/strong&gt;&lt;/p&gt;
&lt;style&gt;del {text-decoration: none; !important}&lt;/style&gt;
&lt;div&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;/* coffee.js */&lt;/span&gt;&lt;br /&gt;&lt;ins class=&quot;highlight-line highlight-line-add&quot;&gt;&lt;/ins&gt;&lt;br /&gt;&lt;ins class=&quot;highlight-line highlight-line-add&quot;&gt;export function calcCoffeeIngredient(coffeeName, cup = 1) {&lt;/ins&gt;&lt;br /&gt;&lt;ins class=&quot;highlight-line highlight-line-add&quot;&gt;  // ...&lt;/ins&gt;&lt;br /&gt;&lt;ins class=&quot;highlight-line highlight-line-add&quot;&gt;}&lt;/ins&gt;&lt;br /&gt;&lt;del class=&quot;highlight-line highlight-line-remove&quot;&gt;&lt;/del&gt;&lt;br /&gt;&lt;del class=&quot;highlight-line highlight-line-remove&quot;&gt;function isValidCoffee(name) {&lt;/del&gt;&lt;br /&gt;&lt;del class=&quot;highlight-line highlight-line-remove&quot;&gt;  // ...&lt;/del&gt;&lt;br /&gt;&lt;del class=&quot;highlight-line highlight-line-remove&quot;&gt;}&lt;/del&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;&lt;em&gt;Function coverage&lt;/em&gt; is a straightforward metric. It captures the percentage of functions in your code that your tests call.&lt;/p&gt;
&lt;p&gt;In the code example, there are two functions: &lt;code&gt;calcCoffeeIngredient&lt;/code&gt; and &lt;code&gt;isValidCoffee&lt;/code&gt;. The tests only call the &lt;code&gt;calcCoffeeIngredient&lt;/code&gt; function, so the function coverage is 50%.&lt;/p&gt;
&lt;h3 id=&quot;line-coverage&quot;&gt;Line coverage &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-code-coverage/#line-coverage&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Code coverage: 62.5%&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;/* coffee.js */&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;export function calcCoffeeIngredient(coffeeName, cup = 1) {&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  let espresso, water;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;ins class=&quot;highlight-line highlight-line-add&quot;&gt;  if (coffeeName === &#39;espresso&#39;) {&lt;/ins&gt;&lt;br /&gt;&lt;ins class=&quot;highlight-line highlight-line-add&quot;&gt;    espresso = 30 * cup;&lt;/ins&gt;&lt;br /&gt;&lt;ins class=&quot;highlight-line highlight-line-add&quot;&gt;    return { espresso };&lt;/ins&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  }&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;ins class=&quot;highlight-line highlight-line-add&quot;&gt;  if (coffeeName === &#39;americano&#39;) {&lt;/ins&gt;&lt;br /&gt;&lt;del class=&quot;highlight-line highlight-line-remove&quot;&gt;    espresso = 30 * cup; water = 70 * cup;&lt;/del&gt;&lt;br /&gt;&lt;del class=&quot;highlight-line highlight-line-remove&quot;&gt;    return { espresso, water };&lt;/del&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  }&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;ins class=&quot;highlight-line highlight-line-add&quot;&gt;  return {};&lt;/ins&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;export function isValidCoffee(name) {&lt;/span&gt;&lt;br /&gt;&lt;del class=&quot;highlight-line highlight-line-remove&quot;&gt;  return [&#39;espresso&#39;, &#39;americano&#39;, &#39;mocha&#39;].includes(name);&lt;/del&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;&lt;em&gt;Line coverage&lt;/em&gt; measures the percentage of executable code lines that your test suite executed. If a line of code remains unexecuted, it means that some part of the code hasn&#39;t been tested.&lt;/p&gt;
&lt;p&gt;The code example has eight lines of executable code (highlighted in red and green)  but the tests don’t execute the &lt;code&gt;americano&lt;/code&gt; condition (two lines) and the &lt;code&gt;isValidCoffee&lt;/code&gt; function (one line). This results in a line coverage of 62.5%.&lt;/p&gt;
&lt;p&gt;Note that line coverage doesn’t take into account declaration statements, such as &lt;code&gt;function isValidCoffee(name)&lt;/code&gt; and &lt;code&gt;let espresso, water;&lt;/code&gt;, because they are not executable.&lt;/p&gt;
&lt;h3 id=&quot;branch-coverage&quot;&gt;Branch coverage &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-code-coverage/#branch-coverage&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Code coverage: 80%&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;/* coffee.js */&lt;/span&gt;&lt;br /&gt;&lt;ins class=&quot;highlight-line highlight-line-add&quot;&gt;&lt;/ins&gt;&lt;br /&gt;&lt;ins class=&quot;highlight-line highlight-line-add&quot;&gt;export function calcCoffeeIngredient(coffeeName, cup = 1) {&lt;/ins&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  // ...&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  if (coffeeName === &#39;espresso&#39;) {&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;    // ...&lt;/span&gt;&lt;br /&gt;&lt;ins class=&quot;highlight-line highlight-line-add&quot;&gt;    return { espresso };&lt;/ins&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  }&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  if (coffeeName === &#39;americano&#39;) {&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;    // ...&lt;/span&gt;&lt;br /&gt;&lt;del class=&quot;highlight-line highlight-line-remove&quot;&gt;    return { espresso, water };&lt;/del&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  }&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;ins class=&quot;highlight-line highlight-line-add&quot;&gt;  return {};&lt;/ins&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;…&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;&lt;em&gt;Branch coverage&lt;/em&gt; measures the percentage of executed branches or decision points in the code, such as if statements or loops. It determines whether tests examine both the true and false branches of conditional statements.&lt;/p&gt;
&lt;p&gt;There are five branches in the code example:&lt;/p&gt;
&lt;style type=&quot;text/css&quot;&gt;
  li img.custom-icon {
    margin-top:0 !important;
    display:inline;
  }
&lt;/style&gt;
&lt;ol&gt;
&lt;li&gt;Calling &lt;code&gt;calcCoffeeIngredient&lt;/code&gt; with just &lt;code&gt;coffeeName&lt;/code&gt; &lt;img alt=&quot;Chek mark.&quot; class=&quot;custom-icon&quot; decoding=&quot;async&quot; height=&quot;20&quot; loading=&quot;lazy&quot; src=&quot;https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/CpHz0pF9m750yTrbDveT.svg&quot; width=&quot;20&quot; /&gt;&lt;/li&gt;
&lt;li&gt;Calling &lt;code&gt;calcCoffeeIngredient&lt;/code&gt; with &lt;code&gt;coffeeName&lt;/code&gt; and &lt;code&gt;cup&lt;/code&gt; &lt;img alt=&quot;Chek mark.&quot; class=&quot;custom-icon&quot; decoding=&quot;async&quot; height=&quot;20&quot; loading=&quot;lazy&quot; src=&quot;https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/CpHz0pF9m750yTrbDveT.svg&quot; width=&quot;20&quot; /&gt;&lt;/li&gt;
&lt;li&gt;Coffee is Espresso &lt;img alt=&quot;Chek mark.&quot; class=&quot;custom-icon&quot; decoding=&quot;async&quot; height=&quot;20&quot; loading=&quot;lazy&quot; src=&quot;https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/CpHz0pF9m750yTrbDveT.svg&quot; width=&quot;20&quot; /&gt;&lt;/li&gt;
&lt;li&gt;Coffee is Americano &lt;img alt=&quot;X mark.&quot; class=&quot;custom-icon&quot; decoding=&quot;async&quot; height=&quot;20&quot; loading=&quot;lazy&quot; src=&quot;https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/ufOsI388YJ9gqjrXjZuQ.svg&quot; width=&quot;20&quot; /&gt;&lt;/li&gt;
&lt;li&gt;Other coffee &lt;img alt=&quot;Chek mark.&quot; class=&quot;custom-icon&quot; decoding=&quot;async&quot; height=&quot;20&quot; loading=&quot;lazy&quot; src=&quot;https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/CpHz0pF9m750yTrbDveT.svg&quot; width=&quot;20&quot; /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The tests cover all branches except the &lt;code&gt;Coffee is Americano&lt;/code&gt; condition. So branch coverage is 80%.&lt;/p&gt;
&lt;h3 id=&quot;statement-coverage&quot;&gt;Statement coverage &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-code-coverage/#statement-coverage&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Code coverage: 55.55%&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;/* coffee.js */&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;export function calcCoffeeIngredient(coffeeName, cup = 1) {&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  let espresso, water;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;ins class=&quot;highlight-line highlight-line-add&quot;&gt;  if (coffeeName === &#39;espresso&#39;) {&lt;/ins&gt;&lt;br /&gt;&lt;ins class=&quot;highlight-line highlight-line-add&quot;&gt;    espresso = 30 * cup;&lt;/ins&gt;&lt;br /&gt;&lt;ins class=&quot;highlight-line highlight-line-add&quot;&gt;    return { espresso };&lt;/ins&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  }&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;ins class=&quot;highlight-line highlight-line-add&quot;&gt;  if (coffeeName === &#39;americano&#39;) {&lt;/ins&gt;&lt;br /&gt;&lt;del class=&quot;highlight-line highlight-line-remove&quot;&gt;    espresso = 30 * cup; water = 70 * cup;&lt;/del&gt;&lt;br /&gt;&lt;del class=&quot;highlight-line highlight-line-remove&quot;&gt;    return { espresso, water };&lt;/del&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  }&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;ins class=&quot;highlight-line highlight-line-add&quot;&gt;  return {};&lt;/ins&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;export function isValidCoffee(name) {&lt;/span&gt;&lt;br /&gt;&lt;del class=&quot;highlight-line highlight-line-remove&quot;&gt;  return [&#39;espresso&#39;, &#39;americano&#39;, &#39;mocha&#39;].includes(name);&lt;/del&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;&lt;em&gt;Statement coverage&lt;/em&gt; measures the percentage of statements in your code that your tests execute. At first glance, you might wonder, “isn’t this the same as line coverage?” Indeed, statement coverage is similar to line coverage but takes into account single lines of code that contain multiple statements.&lt;/p&gt;
&lt;p&gt;In the code example, there are eight lines of executable code, but there are nine statements. Can you spot the line containing two statements?&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;
  Check your answer
&lt;/summary&gt;
It&#39;s the following line: `espresso = 30 * cup; water = 70 * cup;`
&lt;/details&gt;
&lt;p&gt;The tests cover only five of the nine statements, therefore the statement coverage is 55.55%.&lt;/p&gt;
&lt;p&gt;If you always write one statement per line, your line coverage will be similar to your statement coverage.&lt;/p&gt;
&lt;h2 id=&quot;what-type-of-code-coverage-should-you-choose&quot;&gt;What type of code coverage should you choose? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-code-coverage/#what-type-of-code-coverage-should-you-choose&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Most code coverage tools include these four types of common code coverage. Choosing which code coverage metric to prioritize depends on specific project requirements, development practices, and testing goals.&lt;/p&gt;
&lt;p&gt;In general, statement coverage is a good starting point because it is a simple and easy-to-understand metric. Unlike statement coverage, branch coverage and function coverage measure whether tests call a condition (branch) or a function. Therefore, they are a natural progression &lt;em&gt;after&lt;/em&gt; statement coverage.&lt;/p&gt;
&lt;p&gt;Once you have achieved high statement coverage, you can then move on to branch coverage and function coverage.&lt;/p&gt;
&lt;h2 id=&quot;is-test-coverage-the-same-as-code-coverage&quot;&gt;Is test coverage the same as code coverage? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-code-coverage/#is-test-coverage-the-same-as-code-coverage&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;No. Test coverage and code coverage are often confused but they are different:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Test coverage&lt;/strong&gt;: A qualitative metric that measures how well the test suite covers the features of the software. It helps determine the level of risk involved.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Code coverage&lt;/strong&gt;: A quantitative metric that measures the proportion of code executed during testing. It is about how much code the tests cover.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is a simplified analogy: imagine a web application as a house.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Test coverage measures how well the tests cover the rooms in the house.&lt;/li&gt;
&lt;li&gt;Code coverage measures how much of the house the tests have walked through.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;100percent-code-coverage-doesnt-mean-no-bugs&quot;&gt;100% code coverage doesn’t mean no bugs &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-code-coverage/#100percent-code-coverage-doesnt-mean-no-bugs&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;While it is certainly desirable to achieve high code coverage in testing, 100% code coverage doesn’t guarantee the absence of bugs or flaws in your code.&lt;/p&gt;
&lt;h3 id=&quot;a-meaningless-way-to-achieve-100percent-code-coverage&quot;&gt;A meaningless way to achieve 100% code coverage &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-code-coverage/#a-meaningless-way-to-achieve-100percent-code-coverage&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Consider the following test:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* coffee.test.js */&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Warning: Do not do this&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;is meaningless&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;calcCoffeeIngredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;espresso&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;calcCoffeeIngredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;americano&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;calcCoffeeIngredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;unknown&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;isValidCoffee&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;mocha&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toBe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// not meaningful assertion&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;This test achieves 100% function, line, branch, and statement coverage, but it doesn’t make sense because it doesn’t actually test the code. The &lt;code&gt;expect(true).toBe(true)&lt;/code&gt; assertion will always pass regardless of whether the code works correctly.&lt;/p&gt;
&lt;h3 id=&quot;a-bad-metric-is-worse-than-no-metric&quot;&gt;A bad metric is worse than no metric &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-code-coverage/#a-bad-metric-is-worse-than-no-metric&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A bad metric can give you a false sense of security, which is worse than having no metric at all. For example, if you have a test suite that achieves 100% code coverage but the tests are all meaningless, then you may get a false sense of security that your code is well tested. If you accidentally delete or break a part of the application code, the tests will still pass, even though the application no longer works correctly.&lt;/p&gt;
&lt;p&gt;To avoid this scenario:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Test review.&lt;/strong&gt; Write and review tests to make sure they are meaningful and test the code in a variety of different scenarios.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use code coverage as a guideline&lt;/strong&gt;, not as the only measure of test effectiveness or code quality.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;using-code-coverage-in-different-types-of-testing&quot;&gt;Using code coverage in different types of testing &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-code-coverage/#using-code-coverage-in-different-types-of-testing&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let’s take a closer look at how you can use code coverage with the &lt;a href=&quot;https://web.dev/ta-what-to-test/#test-specifics-dos-and-donts&quot;&gt;three common types of test&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Unit tests.&lt;/strong&gt; They are the best test type for gathering code coverage because they are designed to cover multiple small scenarios and testing paths.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Integration tests.&lt;/strong&gt; They can help collect code coverage for integration tests, but use them with caution. In this case, you calculate the coverage of a larger portion of the source code, and it can be difficult to determine which tests actually cover which parts of the code. Nonetheless, calculating code coverage of integration tests may be useful for legacy systems that don’t have well-isolated units.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;End-to-end (E2E) tests.&lt;/strong&gt; Measuring code coverage for E2E tests is difficult and challenging due to the intricate nature of these tests. Instead of using code coverage, requirement coverage might be the better way to go. This is because the focus of E2E tests is to cover the requirements of your test, not to focus on the source code.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-code-coverage/#conclusion&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Code coverage can be a useful metric for measuring the effectiveness of your tests. It can help you to improve the quality of your application by ensuring that the crucial logic in your code is well tested.&lt;/p&gt;
&lt;p&gt;However, remember that code coverage is just one metric. Make sure to also consider other factors, such as the quality of your tests and your application requirements.&lt;/p&gt;
&lt;p&gt;Aiming for 100% code coverage is not the goal. Instead, you should use code coverage along with a well-rounded testing plan that incorporates a variety of testing methods, including unit tests, integration tests, end-to-end tests, and manual tests.&lt;/p&gt;
&lt;p&gt;See the full code example and tests with good code coverage. You can also run the code and tests with this &lt;a href=&quot;https://stackblitz.com/edit/vitest-coffee-coverage?file=README.md&quot; rel=&quot;noopener&quot;&gt;live demo&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* coffee.js - a complete example */&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calcCoffeeIngredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;coffeeName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cup &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isValidCoffee&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;coffeeName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; espresso&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; water&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;coffeeName &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;espresso&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    espresso &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; cup&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; espresso &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;coffeeName &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;americano&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    espresso &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; cup&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; water &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;70&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; cup&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; espresso&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; water &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;coffeeName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; not found&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;isValidCoffee&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;espresso&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;americano&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;mocha&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;includes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* coffee.test.js - a complete test suite */&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; describe&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; expect&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; it &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;vitest&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; calcCoffeeIngredient &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;../src/coffee-complete&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Coffee&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;should have espresso&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calcCoffeeIngredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;espresso&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;deep&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;espresso&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;should have americano&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calcCoffeeIngredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;americano&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;espresso&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;water&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;should throw error&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calcCoffeeIngredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;mocha&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;func&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toThrowError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;mocha not found&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;should have nothing&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calcCoffeeIngredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;unknown&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;deep&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; This blog post was written by Ramona and &lt;a href=&quot;https://web.dev/authors/jecelynyeen/&quot;&gt;Jecelyn Yeen&lt;/a&gt; (&lt;a href=&quot;https://twitter.com/jecfish&quot;&gt;Twitter&lt;/a&gt;), with input and review from &lt;a href=&quot;https://www.linkedin.com/in/michael-hablich-2128646/&quot;&gt;Michael Hablich&lt;/a&gt; (&lt;a href=&quot;https://twitter.com/MHablich&quot;&gt;Twitter&lt;/a&gt;), &lt;a href=&quot;https://web.dev/authors/rachelandrew/&quot;&gt;Rachel Andrew&lt;/a&gt;, and &lt;a href=&quot;https://www.linkedin.com/in/sofia-yemelianova/&quot;&gt;Sofia Emelianova&lt;/a&gt;. &lt;/div&gt;&lt;/aside&gt;
</content>
    <author>
      <name>Ramona Schwering</name>
    </author><author>
      <name>Jecelyn Yeen</name>
    </author>
  </entry>
  
  <entry>
    <title>To test or not to test, a technical perspective</title>
    <link href="https://web.dev/ta-what-to-test/"/>
    <updated>2023-08-23T00:00:00Z</updated>
    <id>https://web.dev/ta-what-to-test/</id>
    <content type="html" mode="escaped">&lt;p&gt;The &lt;a href=&quot;https://web.dev/ta-types/&quot;&gt;previous article&lt;/a&gt; covered the basics of test cases and what they should contain. This article delves deeper into the creation of test cases from a technical perspective, detailing what should be included in each test and what to avoid. Essentially, you&#39;ll learn the answer to the age-old questions of &amp;quot;What to test&amp;quot; or &amp;quot;What not to test&amp;quot;.&lt;/p&gt;
&lt;img alt=&quot;What to test or not to test.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/lwKU8pzIWPZiDg8ss7ad.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/lwKU8pzIWPZiDg8ss7ad.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/lwKU8pzIWPZiDg8ss7ad.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/lwKU8pzIWPZiDg8ss7ad.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/lwKU8pzIWPZiDg8ss7ad.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/lwKU8pzIWPZiDg8ss7ad.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/lwKU8pzIWPZiDg8ss7ad.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/lwKU8pzIWPZiDg8ss7ad.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/lwKU8pzIWPZiDg8ss7ad.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/lwKU8pzIWPZiDg8ss7ad.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/lwKU8pzIWPZiDg8ss7ad.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/lwKU8pzIWPZiDg8ss7ad.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/lwKU8pzIWPZiDg8ss7ad.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/lwKU8pzIWPZiDg8ss7ad.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/lwKU8pzIWPZiDg8ss7ad.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/lwKU8pzIWPZiDg8ss7ad.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/lwKU8pzIWPZiDg8ss7ad.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/lwKU8pzIWPZiDg8ss7ad.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;h2 id=&quot;general-guidelines-and-patterns&quot;&gt;General guidelines and patterns &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-what-to-test/#general-guidelines-and-patterns&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It&#39;s worth noting that specific patterns and points are crucial, regardless of whether you&#39;re conducting unit, integration, or end-to-end tests. These principles can and should be applied to both types of testing, so they are a good place to start.&lt;/p&gt;
&lt;h3 id=&quot;keep-it-simple&quot;&gt;Keep it simple &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-what-to-test/#keep-it-simple&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;When it comes to writing tests, one of the most important things to remember is to keep it simple. It&#39;s important to consider the brain&#39;s capacity. The main production code takes up significant space, leaving little room for additional complexity. This is especially true for testing.&lt;/p&gt;
&lt;p&gt;If there&#39;s less headspace available, you may become more relaxed in your testing efforts. That&#39;s why it&#39;s crucial to prioritize simplicity in testing. In fact, Yoni Goldberg&#39;s &lt;a href=&quot;https://github.com/goldbergyoni/javascript-testing-best-practices#%EF%B8%8F-0-the-golden-rule-design-for-lean-testing&quot; rel=&quot;noopener&quot;&gt;JavaScript testing best practices&lt;/a&gt; emphasize the importance of the Golden Rule—your test should feel like an assistant and not like a complex mathematical formula. In other words, you should be able to understand your test&#39;s intent at first glance.&lt;/p&gt;
&lt;img alt=&quot;Don&amp;#x27;t make tests complex, they shouldn&amp;#x27;t feel this way.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/3r1qa9Ai1EMhb47Yiuuq.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/3r1qa9Ai1EMhb47Yiuuq.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/3r1qa9Ai1EMhb47Yiuuq.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/3r1qa9Ai1EMhb47Yiuuq.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/3r1qa9Ai1EMhb47Yiuuq.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/3r1qa9Ai1EMhb47Yiuuq.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/3r1qa9Ai1EMhb47Yiuuq.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/3r1qa9Ai1EMhb47Yiuuq.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/3r1qa9Ai1EMhb47Yiuuq.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/3r1qa9Ai1EMhb47Yiuuq.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/3r1qa9Ai1EMhb47Yiuuq.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/3r1qa9Ai1EMhb47Yiuuq.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/3r1qa9Ai1EMhb47Yiuuq.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/3r1qa9Ai1EMhb47Yiuuq.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/3r1qa9Ai1EMhb47Yiuuq.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/3r1qa9Ai1EMhb47Yiuuq.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/3r1qa9Ai1EMhb47Yiuuq.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/3r1qa9Ai1EMhb47Yiuuq.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;You should aim for simplicity in all types of tests, regardless of their complexity. In fact, the more complex a test is, the more critical it is to simplify it. One way to achieve this is through a flat test design, where tests are kept as simple as possible, and to only test what is necessary. This means each test should contain only one test case, and the test case should be focused on testing a single, specific functionality or feature.&lt;/p&gt;
&lt;p&gt;Think about it from this perspective: it should be easy to identify what went wrong when reading a failing test. This is why keeping tests simple and easy to understand is important. Doing so lets you quickly identify and fix issues when they arise.&lt;/p&gt;
&lt;h3 id=&quot;test-whats-worth-it&quot;&gt;Test what&#39;s worth it &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-what-to-test/#test-whats-worth-it&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The flat test design also encourages focus and helps ensure your tests are meaningful. Remember, you don&#39;t want to create tests just for the sake of coverage—they should always have a purpose.&lt;/p&gt;
&lt;img alt=&quot;Don&amp;#x27;t test all the things.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/halb4R8zvaEdr85qhIIT.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/halb4R8zvaEdr85qhIIT.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/halb4R8zvaEdr85qhIIT.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/halb4R8zvaEdr85qhIIT.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/halb4R8zvaEdr85qhIIT.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/halb4R8zvaEdr85qhIIT.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/halb4R8zvaEdr85qhIIT.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/halb4R8zvaEdr85qhIIT.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/halb4R8zvaEdr85qhIIT.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/halb4R8zvaEdr85qhIIT.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/halb4R8zvaEdr85qhIIT.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/halb4R8zvaEdr85qhIIT.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/halb4R8zvaEdr85qhIIT.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/halb4R8zvaEdr85qhIIT.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/halb4R8zvaEdr85qhIIT.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/halb4R8zvaEdr85qhIIT.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/halb4R8zvaEdr85qhIIT.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/halb4R8zvaEdr85qhIIT.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; In our &lt;a href=&quot;https://web.dev/ta-types/&quot;&gt;previous article&lt;/a&gt;, we discussed three key points to remember when prioritizing your testing efforts. These three priorities may help you decide whether the case in question should be included in your test. &lt;/div&gt;&lt;/aside&gt;
&lt;h3 id=&quot;dont-test-implementation-details&quot;&gt;Don&#39;t test implementation details &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-what-to-test/#dont-test-implementation-details&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;One common problem in testing is that tests are often designed to test implementation details, such as using selectors in components or end-to-end tests. Implementation details refer to things that users of your code will not typically use, see, or even know about. This can lead to two major problems in tests: false negatives and false positives.&lt;/p&gt;
&lt;p&gt;False negatives occur when a test fails, even though the tested code is correct. This can happen when the implementation details change due to a refactoring of the application code. On the other hand, false positives occur when a test passes, even though the code being tested is incorrect.&lt;/p&gt;
&lt;p&gt;One solution to this problem is to consider the different types of users you have. End users and developers can differ in their approach, and they may interact with the code differently. When planning tests, it is essential to consider what users will see or interact with, and make the tests dependent on those things instead of the implementation details.&lt;/p&gt;
&lt;p&gt;For example, choosing selectors that are less prone to change can make tests more reliable: data-attributes instead of CSS selectors. For more details, refer to &lt;a href=&quot;https://kentcdodds.com/blog/testing-implementation-details&quot; rel=&quot;noopener&quot;&gt;Kent C. Dodds&#39; article&lt;/a&gt; on this topic, or stay tuned—an article on this topic is coming later.&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; On the contrary, if you write tests well, this can also have positive implications on your source code structure, for example, when you consider the testability of your code. &lt;/div&gt;&lt;/aside&gt;
&lt;h3 id=&quot;mocking-dont-lose-control&quot;&gt;Mocking: Don&#39;t lose control &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-what-to-test/#mocking-dont-lose-control&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Mocking is a broad concept used in unit testing and sometimes in integration testing. It involves creating fake data or components to simulate dependencies that have complete control over the application. This allows for isolated testing.&lt;/p&gt;
&lt;p&gt;Using mocks in your tests can improve predictability, separation of concerns, and performance. And, if you need to conduct a test that requires human involvement (such as passport verification), you&#39;ll have to conceal it using a mock. For all these reasons, mocks are a valuable tool to consider.&lt;/p&gt;
&lt;p&gt;At the same time, mocking may affect the accuracy of the test because they are mocks, not the real user experiences. So you need to be mindful when using mocks and stubs.&lt;/p&gt;
&lt;h4 id=&quot;should-you-mock-in-end-to-end-tests&quot;&gt;Should you mock in end-to-end tests? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-what-to-test/#should-you-mock-in-end-to-end-tests&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;In general, no. However, mocking can be a lifesaver sometimes—so let&#39;s not rule it out completely.&lt;/p&gt;
&lt;p&gt;Imagine this scenario: you&#39;re writing a test for a feature involving a third-party payment provider service. You&#39;re in a sandbox environment that they have provided, meaning no real transactions are taking place. Unfortunately, the sandbox is malfunctioning, thereby causing your tests to fail. The fix needs to be done by the payment provider. All you can do is wait for the issue to be resolved by the provider.&lt;/p&gt;
&lt;p&gt;In this case, it might be more beneficial to lessen the dependency on services you cannot control.
It&#39;s still advisable to use mocking carefully in integration or end-to-end tests as it decreases the confidence level of your tests.&lt;/p&gt;
&lt;h2 id=&quot;test-specifics-dos-and-donts&quot;&gt;Test specifics: Dos and don&#39;ts &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-what-to-test/#test-specifics-dos-and-donts&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So, all in all, what does a test contain? And are there differences between the testing types? Let&#39;s take a closer look at some specific aspects tailored to the main testing types.&lt;/p&gt;
&lt;h3 id=&quot;what-belongs-to-a-good-unit-test&quot;&gt;What belongs to a good unit test? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-what-to-test/#what-belongs-to-a-good-unit-test&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;An ideal and effective unit test should:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Concentrate on specific aspects.&lt;/li&gt;
&lt;li&gt;Operate independently.&lt;/li&gt;
&lt;li&gt;Encompass small-scale scenarios.&lt;/li&gt;
&lt;li&gt;Use descriptive names.&lt;/li&gt;
&lt;li&gt;Follow the AAA pattern if applicable.&lt;/li&gt;
&lt;li&gt;Guarantee comprehensive test coverage.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;table-wrapper scrollbar&quot;&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Do ✅&lt;/th&gt;
&lt;th&gt;Don&#39;t ❌&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Keep the tests as small as possible. Test one thing per test case.&lt;/td&gt;
&lt;td&gt;Write tests over large units.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Always keep tests isolated and mock the things you need which are outside your unit.&lt;/td&gt;
&lt;td&gt;Include other components or services.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Keep tests independent.&lt;/td&gt;
&lt;td&gt;Rely on previous tests or share test data.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cover &lt;a href=&quot;https://web.dev/ta-test-cases/#test-paths-typical-kinds-of-test-cases&quot;&gt;different scenarios and paths&lt;/a&gt;.&lt;/td&gt;
&lt;td&gt;Limit yourself to the happy path or negative tests at maximum.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use descriptive test titles, so you can immediately see what your test is about.&lt;/td&gt;
&lt;td&gt;Test by function name only, not being descriptive enough as a result: &lt;code&gt;testBuildFoo()&lt;/code&gt; or &lt;code&gt;testGetId()&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aim for good code coverage or a broader range of test cases, especially at this stage.&lt;/td&gt;
&lt;td&gt;Test from every class down to database (I/O) level.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;h3 id=&quot;what-belongs-to-a-good-integration-test&quot;&gt;What belongs to a good integration test? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-what-to-test/#what-belongs-to-a-good-integration-test&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;An ideal integration test shares some criteria with unit tests, too. However, there are a couple of additional points that you need to consider. A great integration test should:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Simulate interactions between components.&lt;/li&gt;
&lt;li&gt;Cover real-world scenarios, and use mocks or stubs.&lt;/li&gt;
&lt;li&gt;Consider performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;table-wrapper scrollbar&quot;&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Do ✅&lt;/th&gt;
&lt;th&gt;Don&#39;t ❌&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Test the integration points: verify that each unit works together gracefully when integrated with each other.&lt;/td&gt;
&lt;td&gt;Test each unit in isolation—that&#39;s what unit tests are for.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test real-world scenarios: use test data derived from real-world data.&lt;/td&gt;
&lt;td&gt;Use repetitive auto-generated test data or other data which doesn&#39;t reflect real-world use cases.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use mocks and stubs for external dependencies to maintain control of your complete test.&lt;/td&gt;
&lt;td&gt;Create dependencies on third-party services, for example, network requests to outside services.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use a clean-up routine before and after each test.&lt;/td&gt;
&lt;td&gt;Forget to use clean-up measures inside your tests, otherwise this can lead to test failures or false positives, due to lack of proper test isolation.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;h3 id=&quot;what-belongs-to-a-good-end-to-end-test&quot;&gt;What belongs to a good end-to-end test? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-what-to-test/#what-belongs-to-a-good-end-to-end-test&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A comprehensive end-to-end test should:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Replicate user interactions.&lt;/li&gt;
&lt;li&gt;Encompass vital scenarios.&lt;/li&gt;
&lt;li&gt;Span multiple layers.&lt;/li&gt;
&lt;li&gt;Manage asynchronous operations.&lt;/li&gt;
&lt;li&gt;Verify results.&lt;/li&gt;
&lt;li&gt;Account for performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;table-wrapper scrollbar&quot;&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Do ✅&lt;/th&gt;
&lt;th&gt;Don&#39;t ❌&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Use API-driven shortcuts. &lt;a href=&quot;https://docs.cypress.io/guides/references/best-practices#Organizing-Tests-Logging-In-Controlling-State&quot; rel=&quot;noopener&quot;&gt;Learn more&lt;/a&gt;.&lt;/td&gt;
&lt;td&gt;Use UI interactions for every step, including the &lt;code&gt;beforeEach&lt;/code&gt; hook.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use a clean-up routine before each test. Take even more care of test isolation than you do in unit and integration tests because there&#39;s a higher risk of side effects here.&lt;/td&gt;
&lt;td&gt;Forget to clean up after each test. If you don&#39;t clean up the leftover state, data or side effects, they will affect other tests executed later.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Regard end-to-end tests as system tests. This means you need to test the whole application stack.&lt;/td&gt;
&lt;td&gt;Test each unit in isolation—that&#39;s what unit tests are for.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use minimal or no mocking inside the test. Consider carefully if you want to mock external dependencies.&lt;/td&gt;
&lt;td&gt;Rely heavily on mocks.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Consider performance and workload by, for example, not over-testing large scenarios in the same test.&lt;/td&gt;
&lt;td&gt;Cover large workflows without using shortcuts.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; This blog post was written by Ramona, with input and review from &lt;a href=&quot;https://web.dev/authors/jecelynyeen/&quot;&gt;Jecelyn Yeen&lt;/a&gt; (&lt;a href=&quot;https://twitter.com/jecfish&quot;&gt;Twitter&lt;/a&gt;), &lt;a href=&quot;https://www.linkedin.com/in/michael-hablich-2128646/&quot;&gt;Michael Hablich&lt;/a&gt; (&lt;a href=&quot;https://twitter.com/MHablich&quot;&gt;Twitter&lt;/a&gt;), &lt;a href=&quot;https://web.dev/authors/rachelandrew/&quot;&gt;Rachel Andrew&lt;/a&gt;, and &lt;a href=&quot;https://www.linkedin.com/in/sofia-yemelianova/&quot;&gt;Sofia Emelianova&lt;/a&gt;. &lt;/div&gt;&lt;/aside&gt;
</content>
    <author>
      <name>Ramona Schwering</name>
    </author>
  </entry>
  
  <entry>
    <title>Defining test cases and priorities</title>
    <link href="https://web.dev/ta-test-cases/"/>
    <updated>2023-08-09T00:00:00Z</updated>
    <id>https://web.dev/ta-test-cases/</id>
    <content type="html" mode="escaped">&lt;p&gt;In the &lt;a href=&quot;https://web.dev/ta-strategies/&quot;&gt;previous post&lt;/a&gt;, you learned about testing strategies, the number of tests needed to test an application, and how to find the best fit to gain the most confidence in the results while bearing in mind your resources. However, this only gives us an idea of how much to test. You still need to determine exactly what to test.
The following three criteria can be helpful in understanding what to expect in a test and to see what testing type and level of detail might fit best:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Take care of your happy path&lt;/strong&gt;. This is the most generic or primary user story of your application, where your user will notice an error very quickly.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Decide carefully on the level of detail&lt;/strong&gt;. Get into more detail if your use case is vulnerable or where an error would cause high damage.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prioritize lower-level tests&lt;/strong&gt;, such as unit and integration tests, over higher-level end-to-end tests whenever possible.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The rest of this article explores these criteria, and how they apply as you define test cases.&lt;/p&gt;
&lt;h2 id=&quot;what-is-a-test-case&quot;&gt;What is a test case? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-test-cases/#what-is-a-test-case&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In software development, a test case is a sequence of actions or circumstances that are devised to confirm the effectiveness of a software program or application.
A test case aims to ensure that the software operates as planned and that all its features and functions perform correctly. Software testers or developers typically create these test cases to guarantee that the software meets the specified requirements and specifications.&lt;/p&gt;
&lt;img alt=&quot;Test case is verifying.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/Am7IXUF5DVMprZQsSA5p.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/Am7IXUF5DVMprZQsSA5p.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/Am7IXUF5DVMprZQsSA5p.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/Am7IXUF5DVMprZQsSA5p.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/Am7IXUF5DVMprZQsSA5p.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/Am7IXUF5DVMprZQsSA5p.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/Am7IXUF5DVMprZQsSA5p.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/Am7IXUF5DVMprZQsSA5p.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/Am7IXUF5DVMprZQsSA5p.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/Am7IXUF5DVMprZQsSA5p.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/Am7IXUF5DVMprZQsSA5p.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/Am7IXUF5DVMprZQsSA5p.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/Am7IXUF5DVMprZQsSA5p.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/Am7IXUF5DVMprZQsSA5p.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/Am7IXUF5DVMprZQsSA5p.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/Am7IXUF5DVMprZQsSA5p.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/Am7IXUF5DVMprZQsSA5p.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/Am7IXUF5DVMprZQsSA5p.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;When a test case is run, the software performs a series of checks to ensure it produces the desired results. While doing that, a test fulfills the following tasks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Verification&lt;/strong&gt;. The process of thoroughly checking software to ensure it functions without errors. Determining whether the created product meets all the necessary non-functional requirements and successfully achieves its intended purpose is crucial. The question it answers is: “Are we building the product right?”&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Validation&lt;/strong&gt;. The process of ensuring that the software product meets the necessary standards or high-level requirements. It involves checking whether the actual product aligns with the expected product. Essentially, we’re answering the question: “Are we building the right product for the user’s requirements?”&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Suppose the program fails to deliver the expected outcome. In that case, the test case will be the messenger—thus reporting an unsuccessful result, and the developer or tester will need to investigate the issue and find a solution.
Think of the checks and actions as paths the computer follows, regardless of the testing type.  Groups of input data or conditions used for checking are called &amp;quot;equivalence classes&amp;quot;. They should get similar behavior or results from the system under test. The specific paths executed inside a test may vary but should match the activities and assertions done in your test.&lt;/p&gt;
&lt;h2 id=&quot;test-paths-typical-kinds-of-test-cases&quot;&gt;Test paths: Typical kinds of test cases &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-test-cases/#test-paths-typical-kinds-of-test-cases&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In software development, a &lt;a href=&quot;https://en.wikipedia.org/wiki/Happy_path&quot; rel=&quot;noopener&quot;&gt;test case&lt;/a&gt; is a code execution scenario from which a certain behavior is expected and tested. Typically, there are three scenarios to form test cases from.&lt;/p&gt;
&lt;img alt=&quot;The happy path.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/SyLaoC8VQymTbBwIUd11.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/SyLaoC8VQymTbBwIUd11.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/SyLaoC8VQymTbBwIUd11.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/SyLaoC8VQymTbBwIUd11.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/SyLaoC8VQymTbBwIUd11.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/SyLaoC8VQymTbBwIUd11.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/SyLaoC8VQymTbBwIUd11.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/SyLaoC8VQymTbBwIUd11.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/SyLaoC8VQymTbBwIUd11.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/SyLaoC8VQymTbBwIUd11.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/SyLaoC8VQymTbBwIUd11.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/SyLaoC8VQymTbBwIUd11.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/SyLaoC8VQymTbBwIUd11.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/SyLaoC8VQymTbBwIUd11.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/SyLaoC8VQymTbBwIUd11.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/SyLaoC8VQymTbBwIUd11.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/SyLaoC8VQymTbBwIUd11.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/SyLaoC8VQymTbBwIUd11.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;The first one is the most well known, which you are probably already using. It’s the &lt;em&gt;happy path&lt;/em&gt;, also known as the “happy day scenario” or “golden path”. It defines the most common use case of your feature, application, or change—the way it should work out for the customer.&lt;/p&gt;
&lt;img alt=&quot;The scary path.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/7F0MGozRfVyyi3vn65No.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/7F0MGozRfVyyi3vn65No.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/7F0MGozRfVyyi3vn65No.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/7F0MGozRfVyyi3vn65No.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/7F0MGozRfVyyi3vn65No.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/7F0MGozRfVyyi3vn65No.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/7F0MGozRfVyyi3vn65No.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/7F0MGozRfVyyi3vn65No.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/7F0MGozRfVyyi3vn65No.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/7F0MGozRfVyyi3vn65No.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/7F0MGozRfVyyi3vn65No.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/7F0MGozRfVyyi3vn65No.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/7F0MGozRfVyyi3vn65No.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/7F0MGozRfVyyi3vn65No.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/7F0MGozRfVyyi3vn65No.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/7F0MGozRfVyyi3vn65No.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/7F0MGozRfVyyi3vn65No.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/NJdAV9UgKuN8AhoaPBquL7giZQo1/7F0MGozRfVyyi3vn65No.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;The second most crucial test path to cover in your test cases is often left out as it’s uncomfortable—as its name may imply. It’s the “scary path” or, in other words, the &lt;em&gt;negative test&lt;/em&gt;. This path targets scenarios that cause the code to misbehave or enter an error state. Testing these scenarios is especially important if you have highly vulnerable use cases imposing a high risk on the stakeholders or users.&lt;/p&gt;
&lt;p&gt;There are some other paths you might want to know about and consider using, but typically they are less commonly used. The following table summarizes them:&lt;/p&gt;
&lt;div class=&quot;table-wrapper scrollbar&quot;&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Test path&lt;/th&gt;
&lt;th&gt;Explanation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Angry path&lt;/td&gt;
&lt;td&gt;This leads to an error, but an expected one; for example, if you want to ensure error handling works correctly.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delinquent path&lt;/td&gt;
&lt;td&gt;This path takes care of any security-related scenarios your application needs to fulfill.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Desolate path&lt;/td&gt;
&lt;td&gt;The path testing the scenario in your application doesn’t get enough data to function, for example, testing null values.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Forgetful path&lt;/td&gt;
&lt;td&gt;Testing the behavior of your application with insufficient resources, for example, triggering a data loss.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Indecisive path&lt;/td&gt;
&lt;td&gt;Testing with a user who is trying to do actions or following user stories in your application but hasn’t completed those workflows. This could be the case, for example, when the user interrupts their workflow.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Greedy path&lt;/td&gt;
&lt;td&gt;Trying to test using vast amounts of inputs or data.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stressful path&lt;/td&gt;
&lt;td&gt;Trying to put a load on your application by any means necessary until it no longer functions (similar to a load test).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;p&gt;There are several methods to categorize those paths. Two common approaches are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Equivalence partitioning&lt;/strong&gt;. A testing method that categorizes test cases into groups or partitions and, as a result, helps create equivalence classes. This is based on the idea that if one test case in a partition uncovers a defect, other test cases in the same partition will likely reveal similar defects. As all inputs within a specific equivalence class should exhibit identical behavior, you can decrease the number of test cases. &lt;a href=&quot;https://en.wikipedia.org/wiki/Equivalence_partitioning&quot; rel=&quot;noopener&quot;&gt;Learn more about equivalence partitioning&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Limit analysis&lt;/strong&gt;. A testing method, also known as &lt;a href=&quot;https://en.wikipedia.org/wiki/Boundary-value_analysis&quot; rel=&quot;noopener&quot;&gt;boundary-value analysis&lt;/a&gt;, that examines the limits or extremes of input values to find any potential issues or errors that might arise at the system&#39;s limits of capabilities or constraints.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;best-practice-writing-test-cases&quot;&gt;Best practice: Writing test cases &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-test-cases/#best-practice-writing-test-cases&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A classical test case written by a tester will contain specific data to help you grasp the content of the test you want to conduct and, of course, execute the test. A typical tester would document their testing efforts in a table. There are two patterns we can use at this stage, helping us to structure our test cases and later, our tests themselves, too:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Arrange, act, assert&lt;/strong&gt; pattern. The &amp;quot;arrange, act, assert&amp;quot; (also known as the &amp;quot;AAA&amp;quot; or &amp;quot;Triple A&amp;quot;) testing pattern is a way of organizing tests into three distinct steps: arranging the test, then performing the test, and last but not least, drawing conclusions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Given, when, then&lt;/strong&gt; pattern. This pattern is similar to the AAA pattern but has some roots in &lt;a href=&quot;https://en.wikipedia.org/wiki/Behavior-driven_development&quot; rel=&quot;noopener&quot;&gt;behavior-driven development&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Future articles will go into more details on these patterns, as soon as we cover the structure of a test itself. If you want to go deeper into these patterns at this stage, check out these two articles: &lt;a href=&quot;https://automationpanda.com/2020/07/07/arrange-act-assert-a-pattern-for-writing-good-tests/&quot; rel=&quot;noopener&quot;&gt;Arrange-Act-Assert: A pattern for writing good tests&lt;/a&gt; and &lt;a href=&quot;https://martinfowler.com/bliki/GivenWhenThen.html&quot; rel=&quot;noopener&quot;&gt;Given-When-Then&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;According to all the learnings from this article, the following table summarizes a classic example:&lt;/p&gt;
&lt;div class=&quot;table-wrapper scrollbar&quot;&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Information&lt;/th&gt;
&lt;th&gt;Explanation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Prerequisites&lt;/td&gt;
&lt;td&gt;Everything which needs to be done before writing the test.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Object under test&lt;/td&gt;
&lt;td&gt;What needs to be verified?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Input data&lt;/td&gt;
&lt;td&gt;Variables and their values.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Steps to be executed&lt;/td&gt;
&lt;td&gt;All the things you will do to bring your test to life: all actions or interactions you do in your tests.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Expected result&lt;/td&gt;
&lt;td&gt;What should happen and which expectations are to be fulfilled.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Actual result&lt;/td&gt;
&lt;td&gt;What actually happens.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;p&gt;In automated testing, you don’t need to document all these test cases in the way that a tester needs to, even though it’s undoubtedly helpful to do so. You can find all this information in your test if you pay attention. So let’s translate this classical test case into an automated test.&lt;/p&gt;
&lt;div class=&quot;table-wrapper scrollbar&quot;&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Information&lt;/th&gt;
&lt;th&gt;Translation into test automation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Prerequisites&lt;/td&gt;
&lt;td&gt;All the things you need, arranging the test, and thinking about what is given to make your test’s scenario happen.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Object under test&lt;/td&gt;
&lt;td&gt;This “object” can be various things: an application, flow, unit, or component under test.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Input data&lt;/td&gt;
&lt;td&gt;Parameter values.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Steps to be executed&lt;/td&gt;
&lt;td&gt;All the actions and commands executed inside your test, the things you act upon, and finding out what happens when you do certain things.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Expected result&lt;/td&gt;
&lt;td&gt;The assertion you use to validate your application, the things you assert upon in your application.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Actual result&lt;/td&gt;
&lt;td&gt;The result of your automated test.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; This blog post was written by Ramona, with input and review from &lt;a href=&quot;https://web.dev/authors/jecelynyeen/&quot;&gt;Jecelyn Yeen&lt;/a&gt; (&lt;a href=&quot;https://twitter.com/jecfish&quot;&gt;Twitter&lt;/a&gt;), &lt;a href=&quot;https://www.linkedin.com/in/michael-hablich-2128646/&quot;&gt;Michael Hablich&lt;/a&gt; (&lt;a href=&quot;https://twitter.com/MHablich&quot;&gt;Twitter&lt;/a&gt;), and &lt;a href=&quot;https://web.dev/authors/rachelandrew/&quot;&gt;Rachel Andrew&lt;/a&gt;. Special thanks to &lt;a href=&quot;https://www.linkedin.com/in/sofia-yemelianova/&quot;&gt;Sofia Emelianova&lt;/a&gt; for supporting the publication process. &lt;/div&gt;&lt;/aside&gt;
</content>
    <author>
      <name>Ramona Schwering</name>
    </author>
  </entry>
  
  <entry>
    <title>Pyramid or Crab? Find a testing strategy that fits</title>
    <link href="https://web.dev/ta-strategies/"/>
    <updated>2023-07-26T00:00:00Z</updated>
    <id>https://web.dev/ta-strategies/</id>
    <content type="html" mode="escaped">&lt;p&gt;Welcome back! The &lt;a href=&quot;https://web.dev/ta-types&quot;&gt;last article&lt;/a&gt; laid down lots of groundwork about how to approach the different testing types and what they contain, and clarified the testing type definitions. Remember this &lt;a href=&quot;https://web.dev/ta-types/#testing-in-all-shapes-how-does-this-all-work-together&quot;&gt;little meme image&lt;/a&gt;? You might have wondered how all those testing types you learned about could work together.&lt;/p&gt;
&lt;img alt=&quot;A cupboard with two drawers you can open at the same time.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;Next, you will learn exactly that. This article gives an introduction on how to combine these testing types into reasonable strategies and choose one that matches your project.&lt;/p&gt;
&lt;p&gt;You can compare the strategies to a number of shapes to better grasp their meaning. Here&#39;s a list of strategies with respective sizes and development scopes.&lt;/p&gt;
&lt;div class=&quot;table-wrapper scrollbar&quot;&gt;
  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th&gt;
          Application size
        &lt;/th&gt;
        &lt;th&gt;
          Team composition
        &lt;/th&gt;
        &lt;th&gt;
          Reliance on manual testing
        &lt;/th&gt;
        &lt;th&gt;
          Testing strategy
        &lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;Small&lt;/td&gt;
        &lt;td&gt;Developers only&lt;/td&gt;
        &lt;td&gt;High&lt;/td&gt;
        &lt;td&gt;Testing Ice Cone&lt;br /&gt;Testing Crab&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Small&lt;/td&gt;
        &lt;td&gt;Developers &amp; QA engineers&lt;/td&gt;
        &lt;td&gt;High&lt;/td&gt;
        &lt;td&gt;Testing Ice Cone&lt;br /&gt;Testing Crab&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Small&lt;/td&gt;
        &lt;td&gt;Developers only&lt;/td&gt;
        &lt;td&gt;Low&lt;/td&gt;
        &lt;td&gt;Test Pyramid&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Large&lt;/td&gt;
        &lt;td&gt;Developers only&lt;/td&gt;
        &lt;td&gt;High&lt;/td&gt;
        &lt;td&gt;Testing Trophy&lt;br /&gt;Testing Diamond&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Large&lt;/td&gt;
        &lt;td&gt;Developers &amp; QA engineers&lt;/td&gt;
        &lt;td&gt;High&lt;/td&gt;
        &lt;td&gt;Testing Trophy&lt;br /&gt;Testing Crab&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Large&lt;/td&gt;
        &lt;td&gt;Developers only&lt;/td&gt;
        &lt;td&gt;Low&lt;/td&gt;
        &lt;td&gt;Testing Trophy&lt;br /&gt;Testing Honeycomb&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Let&#39;s take a closer look at the strategies and learn the meaning behind their names.&lt;/p&gt;
&lt;h2 id=&quot;determine-testing-goals-what-do-you-want-to-achieve-with-these-tests&quot;&gt;Determine testing goals: What do you want to achieve with these tests? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-strategies/#determine-testing-goals-what-do-you-want-to-achieve-with-these-tests&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before you can start building a good strategy, figure out your testing goal. When do you consider that your application has been sufficiently tested?&lt;/p&gt;
&lt;p&gt;Achieving high test coverage is often viewed as the ultimate goal for developers when it comes to testing. But is it always the best approach? There might be another critical factor to consider when deciding on a testing strategy—serving your users&#39; needs.&lt;/p&gt;
&lt;p&gt;As a developer, you also use many other applications and devices. In this respect, you are the user who relies on all these systems to “just work”. In turn, you rely on countless developers to do their best to make their applications and devices work. To turn this back around, as a developer, you also strive to live up to this trust. So your first goal should always be to ship working software and serve your users. This extends to the tests you write to ensure application quality. &lt;a href=&quot;https://kentcdodds.com/about&quot; rel=&quot;noopener&quot;&gt;Kent C. Dodds&lt;/a&gt; sums it up very well in his &lt;a href=&quot;https://kentcdodds.com/blog/static-vs-unit-vs-integration-vs-e2e-tests&quot; rel=&quot;noopener&quot;&gt;Static vs Unit vs Integration vs E2E Testing for Frontend Apps&lt;/a&gt; post:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;
    The more your tests resemble the way your software is used, the more confidence they can give you.
  &lt;/p&gt;
  &lt;cite&gt;
    by Kent C. Dodds
  &lt;/cite&gt;
&lt;/blockquote&gt;
&lt;p&gt;Kent describes it as gaining confidence in tests. The closer you get to the users by choosing a testing type that fits, the more you can trust your tests to have valid results. In other words, the higher up you climb the pyramid, the more confident you get. But wait, what is the pyramid?&lt;/p&gt;
&lt;h2 id=&quot;determining-test-strategies-how-to-choose-a-testing-strategy&quot;&gt;Determining test strategies: How to choose a testing strategy &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-strategies/#determining-test-strategies-how-to-choose-a-testing-strategy&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As a first step, determine which parts of the requirements you need to check to make sure they are met. Find out what test types to use and at what level of detail you can achieve the most confidence while maintaining an efficient cost structure. Many developers approach this topic by using analogies. Here are the most common ones, starting with the well-known classic.&lt;/p&gt;
&lt;img alt=&quot;A lot of shapes like pyramid, diamonds, ice cone, honeycombs and a trophy; representing test strategies.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;h3 id=&quot;the-classic-the-test-pyramid&quot;&gt;The classic: The test pyramid &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-strategies/#the-classic-the-test-pyramid&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As soon as you start looking for test strategies, you will probably come across the test automation pyramid as the first analogy. Mike Cohn introduced this concept in his book &amp;quot;Succeeding with Agile&amp;quot;. Later, Martin Fowler expanded upon the concept in his &lt;a href=&quot;https://martinfowler.com/articles/practical-test-pyramid.html&quot; rel=&quot;noopener&quot;&gt;Practical Test Pyramid&lt;/a&gt; article. You can represent the pyramid visually as the following:&lt;/p&gt;
&lt;img alt=&quot;The test pyramid.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;As shown in this drawing, the test pyramid consists of three layers:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Unit&lt;/strong&gt;. You find these tests at the base layer of the pyramid because they are fast to execute and simple to maintain. They are isolated and target the most minor test units. For example, see a typical &lt;a href=&quot;https://github.com/leichteckig/phpmagazin-jest-example/blob/main/product.test.js&quot; rel=&quot;noopener&quot;&gt;unit test&lt;/a&gt; for a very small product.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Integration&lt;/strong&gt;. These tests are in the middle of the pyramid, because they have an acceptable execution speed but bring you closer to the user than the unit tests can. An example of an integration test is an &lt;a href=&quot;https://github.com/cypress-io/cypress-realworld-app/blob/develop/cypress/tests/api/api-users.spec.ts&quot; rel=&quot;noopener&quot;&gt;API test&lt;/a&gt;. You can also classify &lt;a href=&quot;https://github.com/leichteckig/nuxt-leichteckig/blob/main/test/components/MediaGrid.spec.js&quot; rel=&quot;noopener&quot;&gt;component tests&lt;/a&gt; as this type.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;E2E tests&lt;/strong&gt; (also called &lt;strong&gt;UI tests&lt;/strong&gt;). These tests simulate a genuine user and their interaction. Such tests need more time to execute and thus are more expensive. They are at at the top of the pyramid.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;confidence-versus-resources&quot;&gt;Confidence versus resources &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-strategies/#confidence-versus-resources&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As briefly covered before, the order of the layers is no coincidence. They show the priorities and the corresponding costs. This gives you a clear picture of how many tests you should write for each layer. You have already seen this in the definition of the testing types.&lt;/p&gt;
&lt;p&gt;Because E2E tests are closest to your users, they give you the most confidence that you application is working as intended. However, they require a complete application stack and a simulated user, therefore, they are also potentially the most expensive. So the confidence is in direct competition with the resources you need to execute the tests.&lt;/p&gt;
&lt;img alt=&quot;The test pyramid with arrows showing the direction of confidence and resources required for different testing types.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;The pyramid tries to solve this problem by making you focus more on unit tests and strictly prioritize the cases covered by E2E tests. For example, your most crucial user journeys or the places most vulnerable to defects. As Martin Fowler emphasizes, the two most essential points in Cohn&#39;s pyramid are as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Write tests with different granularity.&lt;/li&gt;
&lt;li&gt;The more high level you get, the fewer tests you should have.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;pyramid-evolved-adaptations-of-the-test-pyramids&quot;&gt;Pyramid evolved! Adaptations of the test pyramids &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-strategies/#pyramid-evolved-adaptations-of-the-test-pyramids&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For several years, discussions have revolved around the pyramid. The pyramid seems to oversimplify testing strategies, leaves out a lot of testing types, and no longer fits all the real-world projects. Therefore, it may be misleading. Has the pyramid fallen out of shape?
&lt;a href=&quot;https://rauchg.com/about&quot; rel=&quot;noopener&quot;&gt;Guillermo Rauch&lt;/a&gt; has an opinion about it:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;
    Write tests. Not too many. Mostly integration.
  &lt;/p&gt;
  &lt;cite&gt;
    by Guillermo Rauch
  &lt;/cite&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&#39;s one of the most commonly cited quotes on this subject, so let&#39;s break it down:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;Write tests&amp;quot;. Not only because it builds trust, but also because it saves time in maintenance.&lt;/li&gt;
&lt;li&gt;&amp;quot;Not too many&amp;quot;. 100% coverage is not always good because then your testing isn&#39;t prioritized and there will be a lot of maintenance.&lt;/li&gt;
&lt;li&gt;&amp;quot;Mostly integration&amp;quot;. Here again the emphasis is on integration tests: they have the most business value by giving you a daily high confidence level while maintaining a reasonable execution time.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This makes you think again about the testing pyramid and shift your focus to integration testing. Over the last few years, many adaptations have been proposed, so let&#39;s look at the most common ones.&lt;/p&gt;
&lt;h3 id=&quot;test-diamond&quot;&gt;Test diamond &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-strategies/#test-diamond&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The first adaptation removes the overemphasis on unit testing, as seen in the test pyramid. Imagine that you have reached 100% coverage on unit tests. However, the next time you refactor, you will have to update many of these unit tests and you might be tempted to skip them. So they erode.&lt;/p&gt;
&lt;p&gt;As a result, and together with the higher focus on integration testing, the following shape may arise:&lt;/p&gt;
&lt;img alt=&quot;The test diamond.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;A pyramid evolves into a diamond. You can see the previous three layers, but with a different size, and the unit layer has been cut:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Unit&lt;/strong&gt;. Write unit tests the way you defined them before. However, because they tend to erode, prioritize and cover only the most critical cases.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Integration&lt;/strong&gt;. The integration tests you know, testing the combination of single units.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;E2E&lt;/strong&gt;. This layer handles the UI tests similar to the test pyramid. Take care to only write E2E tests for the most critical test cases.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;testing-honeycomb&quot;&gt;Testing honeycomb &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-strategies/#testing-honeycomb&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;There is another adaptation, introduced by &lt;a href=&quot;https://engineering.atspotify.com/2018/01/testing-of-microservices/&quot; rel=&quot;noopener&quot;&gt;Spotify&lt;/a&gt;, that is similar to the test diamond but further specialized for microservices-based software systems. The testing honeycomb is another visual analogy for the granularity, scope, and number of tests to write for a &lt;a href=&quot;https://notes.paulswail.com/public/Testing+microservices&quot; rel=&quot;noopener&quot;&gt;microservices-based software system&lt;/a&gt;. Due to their small size, the most considerable complexity in a microservice is not within the service itself, but in how it interacts with others. So a testing strategy for a microservice should primarily focus on integration tests.&lt;/p&gt;
&lt;img alt=&quot;The testing honeycomb.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;This shape reminds us of a honeycomb, thus the name. It has the following layers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Integrated tests&lt;/strong&gt;. The article by Spotify uses a quote from &lt;a href=&quot;https://blog.thecodewhisperer.com/permalink/integrated-tests-are-a-scam&quot; rel=&quot;noopener&quot;&gt;J. B. Rainsberger&lt;/a&gt; to define this layer: “A test that will pass or fail based on the correctness of another system.” Such tests have external dependencies that you need to consider, and on the contrary, your system might be a dependency that breaks other systems. Similar to E2E tests in other analogies, use these tests carefully, only for the most essential cases.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Integration tests&lt;/strong&gt;. Similar to other adaptations, you should focus on this layer. It contains tests that verify the correctness of your service in a more isolated fashion, but still in combination with other services. That means the tests will include some other systems too and focus on the interaction points, for example, via API tests.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tests on implementation details&lt;/strong&gt;. These tests resemble unit tests—tests that focus on parts of the code that are naturally isolated and thus have their own internal complexity.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you want to find out more about this testing strategy, see the &lt;a href=&quot;https://martinfowler.com/articles/2021-test-shapes.html&quot; rel=&quot;noopener&quot;&gt;post that compares the test pyramid to the honeycomb&lt;/a&gt; by Martin Fowler and the &lt;a href=&quot;https://engineering.atspotify.com/2018/01/testing-of-microservices/&quot; rel=&quot;noopener&quot;&gt;original article from Spotify&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;testing-trophy&quot;&gt;Testing trophy &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-strategies/#testing-trophy&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You can already see a repeating focus on integration tests. However, another type you came across in the previous article is not testing in theory but is still an important aspect you should consider in a testing strategy. Static analysis is missing from the test pyramid and in most of the adaptations you have seen so far. There&#39;s the testing trophy adaptation that takes static analysis into account while maintaining the focus on integration tests. The testing trophy originated from the earlier quote by Guillermo Rauch and was developed by Kent C. Dodds:&lt;/p&gt;
&lt;img alt=&quot;The testing trophy.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;The testing trophy is an analogy depicting the granularity of tests in a slightly different way. It has four layers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Static analysis&lt;/strong&gt;. It plays a vital role in this analogy and lets you catch typos, style mistakes, and other bugs by merely running the debugging steps already outlined.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unit tests&lt;/strong&gt;. They ensure that your smallest unit is appropriately tested, but the testing trophy won&#39;t emphasize them to the same extent as the test pyramid.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Integration&lt;/strong&gt;. This is the main focus as it balances the cost and the higher confidence in the best way, as with other adaptations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UI tests&lt;/strong&gt;. Including E2E and visual tests, they are at the top of the testing trophy, similar to their role in the test pyramid.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To read more about the testing trophy, see the &lt;a href=&quot;https://kentcdodds.com/blog/static-vs-unit-vs-integration-vs-e2e-tests&quot; rel=&quot;noopener&quot;&gt;blog post by Kent C. Dodds&lt;/a&gt; on this subject.&lt;/p&gt;
&lt;h2 id=&quot;some-more-ui-focused-approaches&quot;&gt;Some more UI-focused approaches &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-strategies/#some-more-ui-focused-approaches&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;That&#39;s all well and good but no matter how you call your strategy, a “pyramid”, “honeycomb,” or “diamond”, there&#39;s still something missing. While test automation is valuable, it&#39;s important to remember that manual testing is still essential. Automated testing should alleviate routine tasks and free the quality assurance engineers to focus on crucial areas. Instead of replacing manual testing, automation should complement it. Is there a way to integrate manual testing with automation for optimal results?&lt;/p&gt;
&lt;h3 id=&quot;testing-ice-cone-and-testing-crab&quot;&gt;Testing ice cone and testing crab &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-strategies/#testing-ice-cone-and-testing-crab&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;There are indeed two adaptations of the testing pyramid that focus more on these UI-focused ways of testing. Both have the advantage of high confidence, but are naturally more costly due to slower test execution.&lt;/p&gt;
&lt;p&gt;The first one, the test ice cone, looks like the pyramid in reverse. Without the manual testing step, it is also known as the testing pizza.&lt;/p&gt;
&lt;img alt=&quot;The testing ice cone.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;The ice cone has bigger focus on manual or UI testing and the least focus on unit testing. It often takes shape in projects where developers started work with only a few thoughts on the testing strategy. The ice code is considered an anti-pattern and rightfully so. It is costly in terms of resources and manual work.&lt;/p&gt;
&lt;p&gt;The test crab is similar to the test ice cone, but with more emphasis on E2E and visual testing:&lt;/p&gt;
&lt;img alt=&quot;The testing crab.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;This testing strategy includes one more aspect: it verifies that your application functions and looks good. The testing crab highlights the importance of &lt;a href=&quot;https://docs.cypress.io/guides/tooling/visual-testing&quot; rel=&quot;noopener&quot;&gt;visual testing&lt;/a&gt;, defined in the &lt;a href=&quot;https://web.dev/ta-types/#visual-ui-testing&quot;&gt;previous article&lt;/a&gt;. Integration testing, divided into component and API testing, moves further into the background, and unit testing plays an even more secondary role here. You can find further details on this testing strategy in this &lt;a href=&quot;https://changelog.com/posts/the-testing-pyramid-should-look-more-like-a-crab&quot; rel=&quot;noopener&quot;&gt;article on the testing crab&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;While being more costly, these two testing strategies have their place: for example, in smaller projects where fewer tests are needed, or less complexity needs to be covered. In this case, a full-blown testing strategy focusing on integration testing might be over-engineered.&lt;/p&gt;
&lt;p&gt;Although these two testing strategies are more costly, they have their place, for example, in smaller projects that require fewer tests and don&#39;t need to cover a lot of complexity. In this case, a full scale testing strategy focused on integration testing may be unnecessarily complex.&lt;/p&gt;
&lt;h2 id=&quot;practical-advice-lets-strategize&quot;&gt;Practical advice: Let&#39;s strategize! &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-strategies/#practical-advice-lets-strategize&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You have now learned about the most common testing strategies. You started with the classic—the test pyramid—and got to know its many adaptations. Now you need to evaluate them for your product and decide which is be the best for your project. The answer to this question should start with everyone&#39;s favorite &amp;quot;&lt;strong&gt;It depends&lt;/strong&gt;&amp;quot;. That doesn&#39;t make it any less accurate though.&lt;/p&gt;
&lt;img alt=&quot;It depends.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;The choice of the most appropriate testing strategy from those described—and even the ones left out—depends on your application. It should fir your architecture, your requirements, and last but not least, your users and their requirements. All this might differ from application to application. That&#39;s completely normal. Remember that your most important goal is to serve your users, not a textbook definition.&lt;/p&gt;
&lt;p&gt;More often than not, real-world tests are difficult to separate and define individually. Even Martin Fowler himself emphasizes the &lt;a href=&quot;https://martinfowler.com/articles/2021-test-shapes.html&quot; rel=&quot;noopener&quot;&gt;positive aspect of differing definitions&lt;/a&gt;, such as in the case of unit tests. As &lt;a href=&quot;https://justin.searls.co/about/&quot; rel=&quot;noopener&quot;&gt;Justin Searls&lt;/a&gt; states correctly in &lt;a href=&quot;https://twitter.com/searls/status/1393385209089990659&quot; rel=&quot;noopener&quot;&gt;his tweet&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;
    […] write expressive tests that establish clear boundaries, run quickly &amp; reliably, and only fail for useful reasons.
  &lt;/p&gt;
  &lt;cite&gt;
    by Justin Searls
  &lt;/cite&gt;
&lt;/blockquote&gt;
&lt;p&gt;Focus on the tests that report actual errors that the users might encounter, and don&#39;t get distracted from your goal. Tests should be designed to benefit the user, not just provide 100% coverage or to debate which percentage of which testing type to write.&lt;/p&gt;
&lt;p&gt;Focus on tests that report real-life errors that your users might encounter and don&#39;t get distracted from your goal. Tests should be designed to benefit the user, not just provide 100% coverage or spark debates on what percentage of a particular testing type you should write.&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; This blog post was written by Ramona, with input and review from &lt;a href=&quot;https://web.dev/authors/jecelynyeen/&quot;&gt;Jecelyn Yeen&lt;/a&gt; (&lt;a href=&quot;https://twitter.com/jecfish&quot;&gt;Twitter&lt;/a&gt;), &lt;a href=&quot;https://www.linkedin.com/in/michael-hablich-2128646/&quot;&gt;Michael Hablich&lt;/a&gt; (&lt;a href=&quot;https://twitter.com/MHablich&quot;&gt;Twitter&lt;/a&gt;), and &lt;a href=&quot;https://www.linkedin.com/in/sofia-yemelianova/&quot;&gt;Sofia Emelianova&lt;/a&gt;. &lt;/div&gt;&lt;/aside&gt;
</content>
    <author>
      <name>Ramona Schwering</name>
    </author>
  </entry>
  
  <entry>
    <title>Three common types of test automation</title>
    <link href="https://web.dev/ta-types/"/>
    <updated>2023-07-12T00:00:00Z</updated>
    <id>https://web.dev/ta-types/</id>
    <content type="html" mode="escaped">&lt;p&gt;We&#39;ve all been there: what is a recurring coding meme that happens all too often in real life?
&lt;img alt=&quot;A cupboard with two drawers you cannot open at the same time.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This meme sums it up quite nicely: each drawer works perfectly well individually, but in combination with the other drawer, they block each other and fail to function. You want both drawers to work well with each other and be operable at the same time.&lt;/p&gt;
&lt;img alt=&quot;The same cupboard but with two drawers you can open at the same time.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;Apply this to web development: you wrote some tests, maybe even achieved 100% test coverage, but your application still needs to work once other parts fall into place. The units may work well on their own but not in relation to each other. Writing some tests is crucial but it&#39;s only one part of the ideal test setup for your project. As a very first step, you need to determine what parts of the application quality you need to ensure and how you can achieve that.&lt;/p&gt;
&lt;p&gt;Simply put, you need a plan before you start writing the actual test code. To approach the topic of how to test practically, let&#39;s start with a clean slate and answer two basic questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How do you want to test?&lt;/li&gt;
&lt;li&gt;What do you want to test?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This article focuses on the general things you need to know to answer the first question. To start from a common ground, let&#39;s first learn what testing modes exist and then focus on the common types of testing. In later articles, we will answer the second question, combine the answers, and find the testing strategy that works best for your project. Let&#39;s go! 🙌&lt;/p&gt;
&lt;h2 id=&quot;start-with-the-basics-general-testing-modes&quot;&gt;Start with the basics: General testing modes &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-types/#start-with-the-basics-general-testing-modes&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When answering the question of how to test, the first point to clarify is very abstract. Should you test manually or let a computer take over? It&#39;s important, however, not to fall into binary thinking here.&lt;/p&gt;
&lt;h3 id=&quot;manual-testing-versus-automated-testing&quot;&gt;Manual testing versus automated testing &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-types/#manual-testing-versus-automated-testing&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you ask quality assurance engineers to define testing, they will probably break it down into two &amp;quot;modes&amp;quot; first:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Manual testing&lt;/strong&gt;. This is a typical testing method conducted by actual people. A quality assurance engineer click through the application, check if it works and, at the same time, try to break it. The most common way is exploratory testing, where the engineer investigates the application using their knowledge of the application against a predefined path or checklist.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automated testing&lt;/strong&gt;. This is a type of testing conducted by a computer. Quality assurance engineers implement it to automate away repetitive and monotonous tests.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This series of guides will mostly focus on automated testing. However, you shouldn&#39;t focus on only one way of testing. Even if automation saves a lot of time and effort, humans and manual testing will always play a vital role. Rather, test automation should free up people to focus on exploratory testing and creative problem-solving. For example, ensuring the quality of user experiences or protecting the high-risk business logic. In other words, automation has your back. ❤️&lt;/p&gt;
&lt;h3 id=&quot;opaque-box-versus-clear-box&quot;&gt;Opaque box versus clear box &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-types/#opaque-box-versus-clear-box&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;So, you have defined the general modes of testing. However, that&#39;s not enough yet. To plan the testing strategy, there is one more question to answer: should you know how your application works under the hood or is it better to test without this knowledge? Depending on the answer, there are two procedures to choose from for deriving and selecting test cases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Opaque box testing&lt;/strong&gt; (or black box testing). It is based on analyzing a component or system&#39;s functional or non-functional requirements (specifications) without considering its internal structure.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Clear box testing&lt;/strong&gt; (or white box testing) is a procedure that takes into account the internal structure of said box. In other words, how your application works under the hood.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both procedures can be applied to manual and automated testing. However, some aspects of general testing modes may focus more on one of the two—we will cover that later. For now, let&#39;s further break down test automation into types.&lt;/p&gt;
&lt;h2 id=&quot;test-automation-types-how-do-you-want-to-test&quot;&gt;Test automation types: How do you want to test? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-types/#test-automation-types-how-do-you-want-to-test&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As you get closer to answering the &amp;quot;how&amp;quot; question, you have already decided to do some manual testing. However, choosing and applying test automation types is a bit more challenging. The types of automation testing are closely related to the metrics you want to create in your projects. So let&#39;s take a closer look at the most important ones.&lt;/p&gt;
&lt;p&gt;As illustrated in the meme mentioned earlier, you have already come across two types: unit testing and integration testing. End-to-end testing is the third important one to consider. But that isn&#39;t all of them still. Let&#39;s take a closer look.&lt;/p&gt;
&lt;h3 id=&quot;unit-testing&quot;&gt;Unit testing &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-types/#unit-testing&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Unit testing is a testing type in which minor testable parts or units of an application are individually and independently tested for proper operation. These units can vary in scope from functions, classes, or interfaces, to services or complete components. Their primary attributes are execution speed, isolation, and comfortable maintainability. If you want to dive deeper into unit testing, head over to this &lt;a href=&quot;https://en.wikipedia.org/wiki/Unit_testing&quot; rel=&quot;noopener&quot;&gt;guide on unit testing&lt;/a&gt;.&lt;/p&gt;
&lt;img alt=&quot;A simplified depiction of unit testing showing input and output.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; Possible tools include but aren&#39;t limited to &lt;a href=&quot;https://vitest.dev/&quot;&gt;Vitest&lt;/a&gt; and &lt;a href=&quot;https://jestjs.io/&quot;&gt;Jest&lt;/a&gt;. &lt;/div&gt;&lt;/aside&gt;
&lt;h3 id=&quot;integration-testing&quot;&gt;Integration testing &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-types/#integration-testing&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Integration testing focuses on interactions between components or systems. In other words, on how well they work together. Typical examples of integration tests are API or component tests.&lt;/p&gt;
&lt;img alt=&quot;A simplified depiction of integration testing showing how two unit working together.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; The tools you may consider using are often the same as those mentioned in the &lt;a href=&quot;https://web.dev/ta-types/#unit-testing&quot;&gt;unit testing section&lt;/a&gt; and can also include frameworks providing component testing, for example, &lt;a href=&quot;https://webdriver.io/&quot;&gt;WebdriverIO&lt;/a&gt; and &lt;a href=&quot;https://www.cypress.io/&quot;&gt;Cypress&lt;/a&gt;. &lt;/div&gt;&lt;/aside&gt;
&lt;h3 id=&quot;end-to-end-testing&quot;&gt;End-to-end testing &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-types/#end-to-end-testing&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;These tests are often called UI tests and this name explains their function even better. These tests interact with your application&#39;s UI, including the complete application stack, and test your application from one end to the other.&lt;/p&gt;
&lt;img alt=&quot;A simplified depiction of end-to-end testing showing a computer as a robot, looking at a workflow.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;They resemble a system test if you refer to the theory of quality assurance. These tests simulate a genuine user and their interactions. End-to-end tests take more runtime because they involve the whole system and more runtime requires more computing power. As a result, this additional effort results in higher maintenance costs.&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; The tools you might use for end-to-end testing include but aren&#39;t limited to &lt;a href=&quot;https://webdriver.io/&quot;&gt;WebdriverIO&lt;/a&gt;, &lt;a href=&quot;https://www.cypress.io/&quot;&gt;Cypress&lt;/a&gt;, &lt;a href=&quot;https://playwright.dev/&quot;&gt;Playwright&lt;/a&gt;, &lt;a href=&quot;https://www.selenium.dev/&quot;&gt;Selenium&lt;/a&gt;. &lt;/div&gt;&lt;/aside&gt;
&lt;h4 id=&quot;visual-ui-testing&quot;&gt;Visual UI testing &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-types/#visual-ui-testing&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;An interesting subcategory of UI tests is visual tests. These tests are extended end-to-end tests that provide a means to verify the visible output of an application. Such a test takes a screenshot after a change and another screenshot containing the “status quo” (or golden file), then provides those results to a human reviewer to inspect and check. In other words, it helps find “visual bugs” in the appearance of a page, beyond purely functional bugs and not explicitly written down into assertions.&lt;/p&gt;
&lt;h3 id=&quot;static-analysis&quot;&gt;Static analysis &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-types/#static-analysis&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;There&#39;s one more thing to introduce here: static analysis. It isn&#39;t a testing type in the textbook sense. However, it will be an essential aspect in quality assurance strategies later on. You can imagine it working like a spell check function: it scans your code for more significant defects and syntax errors without running the program, thus detecting code style issues. This simple measure can prevent many bugs. This is a good point to learn about Static Analysis if you want to get to know it in more detail.&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; The tools you might use for static analysis include but aren&#39;t limited to &lt;a href=&quot;https://eslint.org/&quot;&gt;Eslint&lt;/a&gt; and &lt;a href=&quot;https://stylelint.io/&quot;&gt;StyleLint&lt;/a&gt;.  &lt;/div&gt;&lt;/aside&gt;
&lt;h2 id=&quot;testing-in-all-shapes-how-does-this-all-work-together&quot;&gt;Testing in all shapes: How does this all work together? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/ta-types/#testing-in-all-shapes-how-does-this-all-work-together&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;While searching for answers to all these questions, you might find a possible solution in some analogies. In the web and testing communities specifically, developers tend to use these analogies to give you an idea of how many tests you should use of which type.&lt;/p&gt;
&lt;img alt=&quot;A lot of shapes like pyramid, diamonds, ice cone, honeycombs and a trophy; representing test strategies.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;The following five strategies depicted in this image are the most common ones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Test Pyramid&lt;/li&gt;
&lt;li&gt;Test Diamond&lt;/li&gt;
&lt;li&gt;Test Ice Cone (also known as Test Pizza)&lt;/li&gt;
&lt;li&gt;Test Honeycomb&lt;/li&gt;
&lt;li&gt;Test Trophy&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is truly a lot of information to process. How should you decide on a matching test strategy based on all this? Don&#39;t worry, we&#39;ve got you covered. In the next article, we will discuss these different strategies in more detail and explain how to choose the best fit for your project. Stay tuned! 🔥&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; This blog post was written by Ramona, with input and review from &lt;a href=&quot;https://web.dev/authors/jecelynyeen/&quot;&gt;Jecelyn Yeen&lt;/a&gt; (&lt;a href=&quot;https://twitter.com/jecfish&quot;&gt;Twitter&lt;/a&gt;), &lt;a href=&quot;https://www.linkedin.com/in/michael-hablich-2128646/&quot;&gt;Michael Hablich&lt;/a&gt; (&lt;a href=&quot;https://twitter.com/MHablich&quot;&gt;Twitter&lt;/a&gt;), and &lt;a href=&quot;https://www.linkedin.com/in/sofia-yemelianova/&quot;&gt;Sofia Emelianova&lt;/a&gt;. &lt;/div&gt;&lt;/aside&gt;
</content>
    <author>
      <name>Ramona Schwering</name>
    </author>
  </entry>
</feed>
