{"id":2019,"date":"2017-11-17T18:01:40","date_gmt":"2017-11-17T18:01:40","guid":{"rendered":"https:\/\/ionic.io\/blog\/?p=2019"},"modified":"2017-11-17T18:01:40","modified_gmt":"2017-11-17T18:01:40","slug":"unit-testing-stencil-components","status":"publish","type":"post","link":"https:\/\/ionic.io\/blog\/unit-testing-stencil-components","title":{"rendered":"Unit Testing Stencil Components"},"content":{"rendered":"<p>We have added a unit testing framework to <a href=\"https:\/\/stenciljs.com\">Stencil<\/a>. Stencil is a tool for building modern Web Components. Stencil combines some of the best features from traditional frameworks, but outputs 100% standards-compliant Custom Elements, part of the Web Component spec.<\/p>\n<p>The goals we had when adding the testing framework were simple: make it easy to understand, and keep the API as small as possible. As a result of this, the testing API has a total of two methods: render() and flush().<\/p>\n<p><code>render()<\/code> &#8211; The render method takes an object containing a list of components that the Stencil compiler needs to know about and an HTML string. It returns the rendered element.<br \/>\n<code>flush()<\/code> &#8211; The flush method takes an element and causes it to rerender. This is typically done after properties on the element are changed.<\/p>\n<p><!--more--><\/p>\n<h3>Getting Started<\/h3>\n<p>In order to get started with unit testing Stencil components, clone the <a href=\"https:\/\/github.com\/ionic-team\/stencil-component-starter\">Stencil Component Starter<\/a> and run <code>npm install<\/code>. To run the unit tests, use one of the following commands:<\/p>\n<p><code>npm test<\/code> &#8211; performs a single run of the unit tests<br \/>\n<code>npm run test.watch<\/code> &#8211; runs the unit tests and watches for changes to the source, rerunning the unit test with each saved change<\/p>\n<p>In either case, <a href=\"https:\/\/facebook.github.io\/jest\/\">Jest<\/a> is used to run the unit tests.<\/p>\n<h3>Application Setup<\/h3>\n<p>In order to perform unit tests on the components in the a project, some minimal setup is required in the project\u2019s <code>package.json<\/code> file. The testing packages need to be installed as development dependencies, the npm scripts that run the tests need to be defined, and Jest needs to be configured to compile the sources and the tests properly.<\/p>\n<p>The only packages required in order to run the tests are <code>jest<\/code> and <code>@types\/jest<\/code>:<\/p>\n<pre><code>  &quot;devDependencies&quot;: {\n    ...\n    &quot;@types\/jest&quot;: &quot;^21.1.1&quot;,\n    &quot;jest&quot;: &quot;^21.2.1&quot;\n  },\n<\/code><\/pre>\n<p>The two testing related npm scripts are <code>test<\/code> and <code>test.watch<\/code>.<\/p>\n<pre><code>  &quot;scripts&quot;: {\n    ...\n    &quot;test&quot;: &quot;jest --no-cache&quot;,\n    &quot;test.watch&quot;: &quot;jest --watch --no-cache&quot;\n  },\n<\/code><\/pre>\n<p>The jest setup section specifies the <a href=\"http:\/\/facebook.github.io\/jest\/docs\/en\/configuration.html#modulefileextensions-array-string\">moduleFileExtensions<\/a>, <a href=\"http:\/\/facebook.github.io\/jest\/docs\/en\/configuration.html#testregex-string\">testRegex<\/a>, and <a href=\"http:\/\/facebook.github.io\/jest\/docs\/en\/configuration.html#transform-object-string-string\">transform<\/a>. The only part of the setup that is specific to Stencil is the <code>transform<\/code> section. Stencil provides a preprocessor script that uses the Stencil compiler to build the source and test files.<\/p>\n<pre><code>  &quot;jest&quot;: {\n    &quot;transform&quot;: {\n    &quot;^.+\\\\.(ts|tsx)$&quot;: &quot;&lt;rootDir&gt;\/node_modules\/@stencil\/core\/testing\/jest.preprocessor.js&quot;\n    },\n    &quot;testRegex&quot;: &quot;(\/__tests__\/.*|\\\\.(test|spec))\\\\.(tsx?|jsx?)$&quot;,\n    &quot;moduleFileExtensions&quot;: [\n    &quot;ts&quot;,\n    &quot;tsx&quot;,\n    &quot;js&quot;,\n    &quot;json&quot;,\n    &quot;jsx&quot;\n    ]\n  }\n<\/code><\/pre>\n<p>That is all of the setup that is required in order to run the unit tests. Since this has already been done in the <a href=\"https:\/\/github.com\/ionic-team\/stencil-component-starter\">Stencil Component Starter<\/a>, if you are using that as a starting point for your project you should not need to do any extra setup.<\/p>\n<h3>The Test File<\/h3>\n<p>The <a href=\"https:\/\/github.com\/ionic-team\/stencil-component-starter\">Stencil Component Starter<\/a> contains one test file: <code>src\/components\/my-name\/my-name.spec.ts<\/code>. This file contains one test that just ensures the component can be built, and a group of tests that verify the rendering of the component.<\/p>\n<h4>Testing the Component Class<\/h4>\n<p>The first test ensures that the component class can be built.<\/p>\n<pre><code> it(&#039;should build&#039;, () =&gt; {\n   expect(new MyName()).toBeTruthy();\n });\n<\/code><\/pre>\n<p>If the component had methods defined on it, the same technique could be used to obtain an object to use to test those methods. For example, if <code>MyName<\/code> contained a method <code>format()<\/code> that returned a formatted name, you could test it as such:<\/p>\n<pre><code> it(&#039;should build&#039;, () =&gt; {\n   const myName = new MyName();\n   myName.first = &#039;Peter&#039;\n   myName.last = &#039;Parker&#039;;\n   expect(myName).toEqual(&#039;Parker, Peter&#039;);\n });\n<\/code><\/pre>\n<h4>Testing the Component Rendering<\/h4>\n<p>Tests can also render the component so the structure of the component can be tested. This is accomplished via two functions: <code>render()<\/code> and <code>flush()<\/code>. The render() function takes a configuration object consisting of a list of components and and HTML snippet, returning an HTML Element. The <code>flush()<\/code> function takes an element and applies changes to it. Both functions perform their tasks asynchronously.<\/p>\n<p>Since both of these functions work with HTML elements, the standard HTML Element API is used to manipulate and query the structure of the element.<\/p>\n<pre><code> describe(&#039;rendering&#039;, () =&gt; {\n   let element;\n   beforeEach(async () =&gt; {\n     element = await render({\n       components: [MyName],\n       html: &#039;&lt;my-name&gt;&lt;\/my-name&gt;&#039;\n     });\n   });\n\n   ...\n\n   it(&#039;should work with both a first and a list name&#039;, async () =&gt; {\n     element.first = &#039;Peter&#039;\n     element.last = &#039;Parker&#039;;\n     await flush(element);\n     expect(element.textContent).toEqual(&#039;Hello, my name is Peter Parker (4)&#039;);\n   });\n });\n<\/code><\/pre>\n<h3>Next Steps<\/h3>\n<p>In this article we explained the Stencil unit testing framework API, consisting of two functions: <code>render()<\/code> and <code>flush()<\/code>. We showed the additions required to the <code>package.json<\/code> file in order to allow unit testing. Finally we walked through the small sample test that is included in the <a href=\"https:\/\/github.com\/ionic-team\/stencil-component-starter\">Stencil Component Starter<\/a>, and highlighted some of the functionality.<\/p>\n<p>In a future post, I will walk through using this test along with some basic <a href=\"https:\/\/en.wikipedia.org\/wiki\/Test-driven_development\">test-driven development<\/a> in order to extend our component to meet our customer\u2019s new requirements.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We have added a unit testing framework to Stencil. Stencil is a tool for building modern Web Components. Stencil combines some of the best features from traditional frameworks, but outputs 100% standards-compliant Custom Elements, part of the Web Component spec. The goals we had when adding the testing framework were simple: make it easy to [&hellip;]<\/p>\n","protected":false},"author":55,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"publish_to_discourse":"","publish_post_category":"","wpdc_auto_publish_overridden":"","wpdc_topic_tags":"","wpdc_pin_topic":"","wpdc_pin_until":"","discourse_post_id":"","discourse_permalink":"","wpdc_publishing_response":"","wpdc_publishing_error":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[39,7],"class_list":["post-2019","post","type-post","status-publish","format-standard","hentry","category-all","tag-testing","tag-tools"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v23.0 (Yoast SEO v23.0) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Unit Testing Stencil Components - Ionic Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/ionic.io\/blog\/unit-testing-stencil-components\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Unit Testing Stencil Components\" \/>\n<meta property=\"og:description\" content=\"We have added a unit testing framework to Stencil. Stencil is a tool for building modern Web Components. Stencil combines some of the best features from traditional frameworks, but outputs 100% standards-compliant Custom Elements, part of the Web Component spec. The goals we had when adding the testing framework were simple: make it easy to [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/ionic.io\/blog\/unit-testing-stencil-components\" \/>\n<meta property=\"og:site_name\" content=\"Ionic Blog\" \/>\n<meta property=\"article:published_time\" content=\"2017-11-17T18:01:40+00:00\" \/>\n<meta name=\"author\" content=\"Ken Sodemann\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@ionicframework\" \/>\n<meta name=\"twitter:site\" content=\"@ionicframework\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Ken Sodemann\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/ionic.io\/blog\/unit-testing-stencil-components#article\",\"isPartOf\":{\"@id\":\"https:\/\/ionic.io\/blog\/unit-testing-stencil-components\"},\"author\":{\"name\":\"Ken Sodemann\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/person\/00deec3725c91ec95772de89be49f5ca\"},\"headline\":\"Unit Testing Stencil Components\",\"datePublished\":\"2017-11-17T18:01:40+00:00\",\"dateModified\":\"2017-11-17T18:01:40+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/ionic.io\/blog\/unit-testing-stencil-components\"},\"wordCount\":639,\"commentCount\":4,\"publisher\":{\"@id\":\"https:\/\/ionic.io\/blog\/#organization\"},\"keywords\":[\"testing\",\"Tools\"],\"articleSection\":[\"All\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/ionic.io\/blog\/unit-testing-stencil-components#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/ionic.io\/blog\/unit-testing-stencil-components\",\"url\":\"https:\/\/ionic.io\/blog\/unit-testing-stencil-components\",\"name\":\"Unit Testing Stencil Components - Ionic Blog\",\"isPartOf\":{\"@id\":\"https:\/\/ionic.io\/blog\/#website\"},\"datePublished\":\"2017-11-17T18:01:40+00:00\",\"dateModified\":\"2017-11-17T18:01:40+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/ionic.io\/blog\/unit-testing-stencil-components#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/ionic.io\/blog\/unit-testing-stencil-components\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/ionic.io\/blog\/unit-testing-stencil-components#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/ionic.io\/blog\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Unit Testing Stencil Components\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/ionic.io\/blog\/#website\",\"url\":\"https:\/\/ionic.io\/blog\/\",\"name\":\"ionic.io\/blog\",\"description\":\"Build amazing native and progressive web apps with the web\",\"publisher\":{\"@id\":\"https:\/\/ionic.io\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/ionic.io\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/ionic.io\/blog\/#organization\",\"name\":\"Ionic\",\"url\":\"https:\/\/ionic.io\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png\",\"contentUrl\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png\",\"width\":1920,\"height\":854,\"caption\":\"Ionic\"},\"image\":{\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/ionicframework\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/person\/00deec3725c91ec95772de89be49f5ca\",\"name\":\"Ken Sodemann\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/a9bac28efdb8aadafd3c99d5a39a73a67712b5bd63aa6084c138ee7c157f31f1?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/a9bac28efdb8aadafd3c99d5a39a73a67712b5bd63aa6084c138ee7c157f31f1?s=96&d=mm&r=g\",\"caption\":\"Ken Sodemann\"},\"url\":\"https:\/\/ionic.io\/blog\/author\/ken_sodemann\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Unit Testing Stencil Components - Ionic Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/ionic.io\/blog\/unit-testing-stencil-components","og_locale":"en_US","og_type":"article","og_title":"Unit Testing Stencil Components","og_description":"We have added a unit testing framework to Stencil. Stencil is a tool for building modern Web Components. Stencil combines some of the best features from traditional frameworks, but outputs 100% standards-compliant Custom Elements, part of the Web Component spec. The goals we had when adding the testing framework were simple: make it easy to [&hellip;]","og_url":"https:\/\/ionic.io\/blog\/unit-testing-stencil-components","og_site_name":"Ionic Blog","article_published_time":"2017-11-17T18:01:40+00:00","author":"Ken Sodemann","twitter_card":"summary_large_image","twitter_creator":"@ionicframework","twitter_site":"@ionicframework","twitter_misc":{"Written by":"Ken Sodemann","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/ionic.io\/blog\/unit-testing-stencil-components#article","isPartOf":{"@id":"https:\/\/ionic.io\/blog\/unit-testing-stencil-components"},"author":{"name":"Ken Sodemann","@id":"https:\/\/ionic.io\/blog\/#\/schema\/person\/00deec3725c91ec95772de89be49f5ca"},"headline":"Unit Testing Stencil Components","datePublished":"2017-11-17T18:01:40+00:00","dateModified":"2017-11-17T18:01:40+00:00","mainEntityOfPage":{"@id":"https:\/\/ionic.io\/blog\/unit-testing-stencil-components"},"wordCount":639,"commentCount":4,"publisher":{"@id":"https:\/\/ionic.io\/blog\/#organization"},"keywords":["testing","Tools"],"articleSection":["All"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/ionic.io\/blog\/unit-testing-stencil-components#respond"]}]},{"@type":"WebPage","@id":"https:\/\/ionic.io\/blog\/unit-testing-stencil-components","url":"https:\/\/ionic.io\/blog\/unit-testing-stencil-components","name":"Unit Testing Stencil Components - Ionic Blog","isPartOf":{"@id":"https:\/\/ionic.io\/blog\/#website"},"datePublished":"2017-11-17T18:01:40+00:00","dateModified":"2017-11-17T18:01:40+00:00","breadcrumb":{"@id":"https:\/\/ionic.io\/blog\/unit-testing-stencil-components#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/ionic.io\/blog\/unit-testing-stencil-components"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/ionic.io\/blog\/unit-testing-stencil-components#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/ionic.io\/blog"},{"@type":"ListItem","position":2,"name":"Unit Testing Stencil Components"}]},{"@type":"WebSite","@id":"https:\/\/ionic.io\/blog\/#website","url":"https:\/\/ionic.io\/blog\/","name":"ionic.io\/blog","description":"Build amazing native and progressive web apps with the web","publisher":{"@id":"https:\/\/ionic.io\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/ionic.io\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/ionic.io\/blog\/#organization","name":"Ionic","url":"https:\/\/ionic.io\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png","contentUrl":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png","width":1920,"height":854,"caption":"Ionic"},"image":{"@id":"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/ionicframework"]},{"@type":"Person","@id":"https:\/\/ionic.io\/blog\/#\/schema\/person\/00deec3725c91ec95772de89be49f5ca","name":"Ken Sodemann","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ionic.io\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/a9bac28efdb8aadafd3c99d5a39a73a67712b5bd63aa6084c138ee7c157f31f1?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a9bac28efdb8aadafd3c99d5a39a73a67712b5bd63aa6084c138ee7c157f31f1?s=96&d=mm&r=g","caption":"Ken Sodemann"},"url":"https:\/\/ionic.io\/blog\/author\/ken_sodemann"}]}},"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/posts\/2019","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/users\/55"}],"replies":[{"embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/comments?post=2019"}],"version-history":[{"count":0,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/posts\/2019\/revisions"}],"wp:attachment":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/media?parent=2019"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/categories?post=2019"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/tags?post=2019"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}