<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dr. Murray Hoggett</title>
    <description>The latest articles on DEV Community by Dr. Murray Hoggett (@murray2015).</description>
    <link>https://dev.to/murray2015</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F492604%2F630ebd7f-f713-4d28-97f3-5e43c1e087a2.jpeg</url>
      <title>DEV Community: Dr. Murray Hoggett</title>
      <link>https://dev.to/murray2015</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/murray2015"/>
    <language>en</language>
    <item>
      <title>Introduction to e2e testing in JavaScript with Cypress</title>
      <dc:creator>Dr. Murray Hoggett</dc:creator>
      <pubDate>Sat, 17 Oct 2020 09:56:26 +0000</pubDate>
      <link>https://dev.to/murray2015/introduction-to-e2e-testing-in-javascript-with-cypress-1lph</link>
      <guid>https://dev.to/murray2015/introduction-to-e2e-testing-in-javascript-with-cypress-1lph</guid>
      <description>&lt;h2&gt;
  
  
  What is e2e testing?
&lt;/h2&gt;

&lt;p&gt;End-to-end (e2e) testing is a common type of software application testing that replicates a whole user workflow rather than a single piece of functionality. An e2e test is essentially the opposite to a &lt;a href="https://www.martinfowler.com/bliki/UnitTest.html" rel="noopener noreferrer"&gt;unit test&lt;/a&gt; as described by the &lt;a href="https://www.loupetestware.com/post/testing-pyramid-2-0" rel="noopener noreferrer"&gt;testing pyramid&lt;/a&gt;. Philosophically, unit tests are about testing a single unit of functionality. In terms of code this is often a single function, or a class method, or similar. E2e tests do the opposite, and test a workflow rather than a function. A workflow might, for example, be a user logging in to an app, checking the balance of their account, and logging out. E2e tests have the major benefits of testing multiple functions and components, and the interaction between them. This makes end-to-end tests especially useful for regression testing. The downside, however, of e2e tests is that they are slower to run as many different parts of a code base are being tested. &lt;/p&gt;

&lt;p&gt;Typically, end-to-end tests should test the most common workflows, rather than every feature. With unit tests a team may aim for 100% code coverage, but with e2e tests this would likely result in a very slow runtime of the test suite. E2e tests commonly make API calls, render whole pages, or load resources, which make the slow and time consuming to run. This also means they can be flakier, and time out or crash for reasons outside of simply the correctness of the code base. &lt;/p&gt;

&lt;p&gt;Let’s give a few example of possible end-to-end tests for a typical front end example project, a to-do list app: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logging in, adding a todo item, and logging out&lt;/li&gt;
&lt;li&gt;Logging in, adding three todo items, re-ordering the todo items, editing the text of a todo item, marking a todo item as done, then logging out&lt;/li&gt;
&lt;li&gt;Checking data persistence by checking presence of a todo item after logging out and then back in again. &lt;/li&gt;
&lt;li&gt;And so on. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why is e2e testing useful
&lt;/h2&gt;

&lt;p&gt;End to end testing is highly complementary to unit and integration level testing. As already mentioned, by testing common user workflows e2e testing ties together multiple functions, components, and parts of the code base. This allows greater confidence in systems and functionality due to those systems being tested together. It also allows testing of interactions that can be difficult in a unit or integration testing framework.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Cypress
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgxf5jwvf13pr34bf0b2c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgxf5jwvf13pr34bf0b2c.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Common testing frameworks for e2e tests in JavaScript include &lt;a href="https://www.cypress.io/" rel="noopener noreferrer"&gt;Cypress&lt;/a&gt;, &lt;a href="https://www.selenium.dev/" rel="noopener noreferrer"&gt;Selenium&lt;/a&gt;, &lt;a href="https://nightwatchjs.org/" rel="noopener noreferrer"&gt;Nightwatch&lt;/a&gt;, &lt;a href="https://developers.google.com/web/tools/puppeteer" rel="noopener noreferrer"&gt;Puppeteer&lt;/a&gt; and &lt;a href="https://devexpress.github.io/testcafe/" rel="noopener noreferrer"&gt;Testcafe&lt;/a&gt;. Here, I’m going to give a quick overview of Cypress. Cypress is a modern, fast, next generation framework for e2e testing. It has a clean interface with good documentation, and has a very cool video rollback feature which gives a good idea of the cause when tests fail. Personally, I’ve found Cypress to be faster than some other frameworks (e.g. Selenium) but slower than others (e.g. Puppeteer). I haven’t spent time optimising any of the above for speed though, so take my opinion with a pinch of salt! Cypress also has a great selection features and a wide range of helper functions, making it a good choice for many different projects. &lt;/p&gt;

&lt;h3&gt;
  
  
  Getting started with Cypress
&lt;/h3&gt;

&lt;p&gt;Here we’re going to make a toy React project, and write a couple of basic tests and assertions with Cypress. Let’s dive straight in! &lt;/p&gt;

&lt;h3&gt;
  
  
  Create the react starter project
&lt;/h3&gt;

&lt;p&gt;To keep things simple, let’s create a quick web app in React, and use Cypress to test that the React app renders correctly. We can create a configured starter project using &lt;code&gt;create-react-app&lt;/code&gt; at the command line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app test-cypress-project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Install Cypress
&lt;/h3&gt;

&lt;p&gt;Once we have created our test React app, next we need to install Cypress into the React app project. Luckily, installing cypress is a breeze. From the command line, navigate to the root folder of the React app project, and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i cypress --save-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we want to open Cypress for the first time, which will cause it to create a new folder of example tests and plugin support to be created. We can open Cypress from the command line by typing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx cypress open
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will cause the new “cypress” folder to be made in the project. &lt;/p&gt;

&lt;h3&gt;
  
  
  Explore Cypress
&lt;/h3&gt;

&lt;p&gt;Let’s now get a handle on how Cypress works and a little of its functionality. First, we’ll start by testing that our React app is running on localhost. We’ll then test that certain HTML elements can be found on the page and are visible, and finish by looking at testing the HTML elements have certain attributes. &lt;/p&gt;

&lt;h3&gt;
  
  
  Test that components have rendered
&lt;/h3&gt;

&lt;p&gt;First, create a new file in cypress/integration called react_tests.js&lt;/p&gt;

&lt;p&gt;Next we need to check that our React app is running. In a terminal window, navigate to the project root directory and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cypress uses syntax that will be familiar if you have used Jest or Mocha for testing, in that it uses &lt;code&gt;describe()&lt;/code&gt; and &lt;code&gt;it()&lt;/code&gt; function to organise tests into logical groups. Let’s write our first test using &lt;code&gt;describe()&lt;/code&gt; and &lt;code&gt;it()&lt;/code&gt; function in our react_tests.js file. In that file, add the following snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;describe("visits the page", () =&amp;gt; {
 it("tests elements are visible", () =&amp;gt; {
 cy.visit("localhost:3000");
 cy.contains("Learn React");
 });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we start with a &lt;code&gt;describe()&lt;/code&gt; function, which takes a string and a callback function as first and second arguments. We pass an it() function as the callback argument. Similarly, the it() function also takes a string and call-back function as the first and second arguments. The two further lines of code are &lt;code&gt;cy.visit(“localhost:3000”)&lt;/code&gt; and &lt;code&gt;cy.contains("Learn React”)&lt;/code&gt;. &lt;code&gt;Cy.visit()&lt;/code&gt; visits a provided url, and asserts that an http response is received. The second interesting function is &lt;code&gt;cy.contains()&lt;/code&gt;, which will search for an element on the page the contains the text passed as an argument. This provides a nice API for selecting elements in cases where multiple elements won’t be matched with the passed string. Cypress will automatically assert that the element selected by the selector give to &lt;code&gt;cy.contains()&lt;/code&gt; is present in the DOM. &lt;/p&gt;

&lt;p&gt;Now we want to run our tests in cypress. In a new terminal window (leave the old terminal window open to keep running our react app) navigate to the project root directory, and run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx cypress open 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should once again open the cypress test runner window. In this window you should see the example tests that cypress autogenerates, as well as our react_tests.js file. In the cypress window, click the react_tests.js label to open and run our test. &lt;/p&gt;

&lt;p&gt;We should see the tests all pass! &lt;/p&gt;

&lt;p&gt;Let’s next look at how we can assert more information about selected elements. Elements selected by cypress (such as by &lt;code&gt;cy.contains()&lt;/code&gt; ) supports a &lt;code&gt;.should()&lt;/code&gt; method. The &lt;code&gt;.should()&lt;/code&gt; method can take many different types of assertion, for example &lt;code&gt;“have.css”&lt;/code&gt;. The &lt;code&gt;have.css&lt;/code&gt; method allows us to assert that a css property is attached to the selected element. We are already testing whether we can successfully select an element with the content “Learn React” from the DOM, let’s now test that the selected element has the Font Family css property. And while we are at it, let’s illustrate that the &lt;code&gt;cy.contains()&lt;/code&gt; function that we have already used has additional functionality - it can select elements based on partial text matches, rather than needing the complete text. Let’s select the element containing the text “Edit src/App.js and save to reload.” by just asking Cypress to select an element containing the word “Edit”. And we can do both the selecting of an element with the text “Edit”, and test for it’s css property in 1 line of code, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;describe("visits the page", () =&amp;gt; {
 it("tests elements are visible", () =&amp;gt; {
 cy.visit(“localhost:3000");
 cy.contains("Edit").should("have.css", "font-family");
 cy.contains("Learn React");
 });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you still have the cypress test runner window open then the tests should automatically re-run when you save the new code. If not, open the test runner again with npx cypress open, and click the react_tests.js file. &lt;/p&gt;

&lt;p&gt;Finally let’s wrap up with another method to select elements on the DOM in cypress, and how to assert elements are visible, and have html attributes and css classes. The additional method of selecting elements is the &lt;code&gt;cy.get()&lt;/code&gt; method. &lt;code&gt;cy.get()&lt;/code&gt; selects based on a css style selector. In this case, let’s select the spinning react image. As it is the only image on the page, we can simply select it with &lt;code&gt;cy.get(“img”)&lt;/code&gt;. We can then test for visibility, attributes and classes using a very similar chaining syntax to that already covered with the &lt;code&gt;.should()&lt;/code&gt; method. The only new addition compared to what we have already covered is that cypress supports a &lt;code&gt;.and()&lt;/code&gt; method when has the same functionality as a &lt;code&gt;.should()&lt;/code&gt; method; the &lt;code&gt;.and()&lt;/code&gt; is easier to read as it make the code more like written English. Add the following to our code for our final example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;describe("visits the page", () =&amp;gt; {
 it("tests elements are visible", () =&amp;gt; {
 cy.visit("localhost:3000");
 cy.contains("Edit").should("have.css", "font-family");
 cy.get("img")
 .should("be.visible")
 .and("have.class", "App-logo")
 .and("have.attr", "src");
 cy.contains("Learn React");
 });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, if the cypress test runner is still open you should see the test run automatically upon save. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fodcbmp4h6a7r2k0jz43n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fodcbmp4h6a7r2k0jz43n.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that concludes this as a first, very brief introduction to end to end testing in Cypress. We have covered installing Cypress, creating a test project, opening Cypress, making a new test file, structuring tests inside &lt;code&gt;describe()&lt;/code&gt; and &lt;code&gt;it()&lt;/code&gt; functions, looked at visiting a website with &lt;code&gt;cy.visit()&lt;/code&gt;, selecting elements from the DOM with &lt;code&gt;cy.contains()&lt;/code&gt; and &lt;code&gt;cy.get()&lt;/code&gt;, and asserting that elements have css properties, are visible, have certain classes and html attributes. This is just the tip of the iceberg, however, and there is a huge amount of learn. I refer you to the &lt;a href="https://docs.cypress.io/" rel="noopener noreferrer"&gt;Cypress documentation&lt;/a&gt; as a great source of information and some useful tutorials. Particularly good explanations can be found on &lt;a href="https://docs.cypress.io/guides/core-concepts/writing-and-organizing-tests.html" rel="noopener noreferrer"&gt;writing and organising tests&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;And that’s all! Thanks for reading. If you have any questions, get in touch at &lt;a href="mailto:murray@loupetestware.com"&gt;murray@loupetestware.com&lt;/a&gt; &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>testing</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Mocking API calls with Jest</title>
      <dc:creator>Dr. Murray Hoggett</dc:creator>
      <pubDate>Sat, 17 Oct 2020 09:42:49 +0000</pubDate>
      <link>https://dev.to/murray2015/mocking-api-calls-with-jest-3eph</link>
      <guid>https://dev.to/murray2015/mocking-api-calls-with-jest-3eph</guid>
      <description>&lt;h2&gt;
  
  
  Who needs mocks?
&lt;/h2&gt;

&lt;p&gt;The term “mock” or “mocking” in software testing is ubiquitous, but can have multiple meaning leading it to be confusing. Mocking can refer to functions, modules, servers… and what does it even mean? Do you need it?? Argh!?&lt;/p&gt;

&lt;p&gt;Relax, mocks aren’t that hard. “Mocks” are a type of test pattern that can be useful when testing web applications. At a high level, mocking is the idea of replacing a function or part of a function with something that we explicitly control. A common example of this is a remote API call. Imagine the situation: you have a test that calls a remote API and tests whether the data is correctly rendered to the page. This might be a core part of your application, so needs to be tested, but simply writing a test that calls the API and tests whether the data is rendered to the page can be problematic. What happens if the API goes down? This will break your test, but this isn’t smart, as your code isn’t broken, it’s the external API that is broken. And what happens if you lose internet connection? This would also cause your test to fail. Or what if the API changes the format of the data it sends back? Again the test fail, but this failure is not a sensible representation of your software. Your code isn’t broken, it’s the external API that has changed. This concept is called a test’s “brittleness” - essentially how likely the test is the fail even if your code isn’t wrong. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is mocking?
&lt;/h2&gt;

&lt;p&gt;Mocks help get around this problem by reducing a test’s brittleness when calling APIs. Mocks fall under the category of “test doubles” as defined by &lt;a href="https://martinfowler.com/bliki/TestDouble.html"&gt;Martin Fowler&lt;/a&gt;. Creating a mock function allows us to replace slow functions or API calls with something else, and gives us access to extra ways to test our code, such as capturing (and being able to assert against) how the function was called, how many times it was called, or what parameters the function was called with. &lt;/p&gt;

&lt;h2&gt;
  
  
  Mocking in Jest
&lt;/h2&gt;

&lt;p&gt;There are 3 main ways to create mock functions in Jest. These are &lt;br&gt;
*&lt;code&gt;jest.fn()&lt;/code&gt;&lt;br&gt;
*&lt;code&gt;jest.mock()&lt;/code&gt;&lt;br&gt;
*&lt;code&gt;jest.spyOn()&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Jest.fn() is used to mock a single function, while jest.mock() is used to mock a whole module. jest.spyOn() is slightly different in that it captures more information about how the function was called. All three are related and can be useful in their own ways. &lt;/p&gt;

&lt;p&gt;Let’s look at an example. Let’s say we have a function that makes a really slow api call, and then gives us a response based on what is returned:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export async function getStockValue() {
  const conversionRate = 0.91;
  const data = await fetch(“http://www.slow-url.com”); // For the purposes of this example imagine this returns a falsy value, or try using http://www.google.com
  if (!data || Object.keys(data).length &amp;lt; 1) {
    return false;
  } else {
    return data.payload * conversionRate;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function is obviously quite simple, but allows us to demonstrate the value in mocking. Let’s start with how we could write a test that isn’t very effective:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;describe("the getStockValue function", () =&amp;gt; {
  it("returns false if no data is returned by the API", async () =&amp;gt; {
    const value = await getStockValue();
    expect(value).toBe(false);
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(If you don’t understand this test, check out the &lt;a href="https://jestjs.io/en/"&gt;Jest docs&lt;/a&gt;. This simple test will test the functionality, but it is susceptible to all of the problems outlined previously - it will likely be slow and it will break if the internet connection or API itself is down. We can solve this while still testing the function with something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;describe("the getStockValue function", () =&amp;gt; {
  it("returns false if no data is returned by the API", async () =&amp;gt; {
    global.fetch = jest.fn(() =&amp;gt; {
      Promise.resolve();
    });
    const value = await getStockValue();
    expect(fetch).toHaveBeenCalledTimes(1);
    expect(value).toBe(false);
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we mock the global fetch function, and dictate that it resolves a promise but doesn’t return anything. This will trigger our function to return false, which we can assert against, thus testing that the function returns false if the API doesn’t return anything. However, here you can see that mocking has also given us access to other ways to check our code is working as we expect it to: in this case being able to assert against the fetch having only been called one time. &lt;/p&gt;

&lt;h2&gt;
  
  
  That’s all, folks!
&lt;/h2&gt;

&lt;p&gt;I hope this short article helped you with using Jest’s mocking capabilities. If you have any questions or want to reach out to me, drop me a line on &lt;a href="mailto:murray@loupetestware.com"&gt;murray@loupetestware.com&lt;/a&gt;. Best of luck in your mocking efforts! &lt;/p&gt;

</description>
      <category>testing</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
