<?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: Chadwick </title>
    <description>The latest articles on DEV Community by Chadwick  (@chdwck).</description>
    <link>https://dev.to/chdwck</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%2F745076%2F0051b0b8-65c1-4fb2-8855-eb149173f2bc.jpeg</url>
      <title>DEV Community: Chadwick </title>
      <link>https://dev.to/chdwck</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chdwck"/>
    <language>en</language>
    <item>
      <title>How to run integration tests using Github Actions</title>
      <dc:creator>Chadwick </dc:creator>
      <pubDate>Fri, 19 Nov 2021 21:50:27 +0000</pubDate>
      <link>https://dev.to/delphidigital/how-to-run-integration-tests-using-github-actions-5dok</link>
      <guid>https://dev.to/delphidigital/how-to-run-integration-tests-using-github-actions-5dok</guid>
      <description>&lt;p&gt;&lt;a href="https://docs.github.com/en/actions"&gt;GitHub Actions&lt;/a&gt; allow us to easily verify if a Pull Request is safe to merge into a main branch. &lt;/p&gt;

&lt;p&gt;This article assumes you have a basic functional understanding of &lt;a href="https://github.com/"&gt;Github&lt;/a&gt; and &lt;a href="https://www.tutorialspoint.com/software_testing_dictionary/integration_testing.htm"&gt;Integration Testing&lt;/a&gt; and will be covering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to run integration tests in a &lt;a href="https://www.atlassian.com/continuous-delivery/continuous-integration"&gt;CI&lt;/a&gt; environment using &lt;strong&gt;GitHub Actions&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;How to prevent failing Pull Requests from being merged&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🤖 Create the Workflow 🤖
&lt;/h2&gt;

&lt;p&gt;In your Github repository, navigate to the &lt;strong&gt;Actions&lt;/strong&gt; tab.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mjZNE6jO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/atn2n6f0qq3d5hhpeu8f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mjZNE6jO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/atn2n6f0qq3d5hhpeu8f.png" alt="Actions Tab" width="880" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Chose the workflow template that best suits your needs, commit the changes, and pull the new &lt;code&gt;.github/&lt;/code&gt; folder into your local environment.&lt;/p&gt;
&lt;h2&gt;
  
  
  🔧 Customize the Workflow 🔧
&lt;/h2&gt;

&lt;p&gt;Before making the following changes, create a new branch to edit your workflow to quickly iterate without jumping between editing and checking the workflow logs.&lt;/p&gt;

&lt;p&gt;To add a test database, add a services section to the &lt;code&gt;&amp;lt;project-root&amp;gt;/.github/workflow/workflow_name.yml&lt;/code&gt; file under the job name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .github/workflows/node.js.yml&lt;/span&gt;

&lt;span class="nn"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# name of the job&lt;/span&gt;
  &lt;span class="na"&gt;ci&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

    &lt;span class="c1"&gt;# The OS of the docker container&lt;/span&gt;
    &lt;span class="c1"&gt;# Github runs the workflows on&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;matrix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# node version(s) to run against&lt;/span&gt;
        &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;16.x'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

    &lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;# name of the service&lt;/span&gt;
      &lt;span class="na"&gt;postgresql&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# The software image the container&lt;/span&gt;
        &lt;span class="c1"&gt;# will download and start&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;postgres:14'&lt;/span&gt;
        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="c1"&gt;# map external port to container. This is&lt;/span&gt;
          &lt;span class="c1"&gt;# important because our app will run outside&lt;/span&gt;
          &lt;span class="c1"&gt;# our postgres container&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;54320:5432'&lt;/span&gt;

        &lt;span class="c1"&gt;# Environment Variables&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;example_app_test_db&lt;/span&gt;
          &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jamesbond&lt;/span&gt;
          &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;example_app_db_test_user&lt;/span&gt;
        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;-&lt;/span&gt;
          &lt;span class="s"&gt;--health-cmd pg_isready&lt;/span&gt;
          &lt;span class="s"&gt;--health-interval 10s&lt;/span&gt;
          &lt;span class="s"&gt;--health-timeout 5s&lt;/span&gt;
          &lt;span class="s"&gt;--health-retries 5&lt;/span&gt;

&lt;span class="s"&gt;...&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update your code to point at the containerized database when running in the CI environment. The connection string will be consistent with the given environment variables and ports. &lt;strong&gt;e.g&lt;/strong&gt; &lt;code&gt;postgresql://example_app_db_test_user:jamesbond@localhost:54320/example_app_test_db&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Update the steps section to set up and test your code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .github/workflows/node.js.yml&lt;/span&gt;
&lt;span class="nn"&gt;...&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Checkout our branch in the container&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout 🛎&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

    &lt;span class="c1"&gt;# Download and setup nodejs&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Use Node.js ${{ matrix.node-version }}&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v2&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ matrix.node-version }}&lt;/span&gt;
        &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;npm'&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies 👨🏻‍💻&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm ci&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Migrate Database 🏗️&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run migrate&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Seed Test Data 🌱&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run db:seed&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;run end-to-end tests 🧪&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run test&lt;/span&gt;
&lt;span class="nn"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go ahead and push those changes.&lt;/p&gt;

&lt;p&gt;Inspect the logs by clicking the &lt;strong&gt;details&lt;/strong&gt; link under the checks section near the merge button at the bottom of the page.&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6C5UPd77--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ojufwetrzljtn7t7an4p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6C5UPd77--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ojufwetrzljtn7t7an4p.png" alt="Pull request check details" width="880" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also see all workflow logs by navigating back to the actions tab.&lt;/p&gt;

&lt;p&gt;Once your checks are coming back ✅, you're ready to merge that Pull Request and move on.&lt;/p&gt;

&lt;h2&gt;
  
  
  🥋 Respect the Workflow 🥋
&lt;/h2&gt;

&lt;p&gt;If you want to protect your code from accidents or overconfidence, you can configure your repository to only allow merging Pull Requests that pass the checks.&lt;/p&gt;

&lt;p&gt;Navigate to the repository branches settings and click the &lt;strong&gt;Add Rule&lt;/strong&gt; button.&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ez9ZLpgh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v83grooms9at7xnlgtp7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ez9ZLpgh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v83grooms9at7xnlgtp7.png" alt="Add Rule Button" width="880" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Set &lt;strong&gt;Branch Name Pattern&lt;/strong&gt; to &lt;code&gt;*&lt;/code&gt; to match all branches (or whatever regex pattern you need to target certain branches)&lt;/li&gt;
&lt;li&gt;Check &lt;strong&gt;Require status checks to pass before merging&lt;/strong&gt; and search for the job name used in your &lt;code&gt;.github/workflow/workflow_name.yml&lt;/code&gt; file. I used the name &lt;code&gt;ci&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Check &lt;strong&gt;Require branches to be up to date before merging&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .github/workflows/node.js.yml&lt;/span&gt;

&lt;span class="nn"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# name of the job&lt;/span&gt;
  &lt;span class="na"&gt;ci&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="nn"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qkjB3FMA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/err601vnyudnrm5dq70g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qkjB3FMA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/err601vnyudnrm5dq70g.png" alt="Branch rule config p1" width="785" height="675"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;(Optional)&lt;/em&gt;&lt;/strong&gt; Check &lt;strong&gt;Include Administrators&lt;/strong&gt; to keep yourself from pushing breaking changes
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZQCBP5Qq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6dxkmhcqc2cistcccbeb.png" alt="Branch rule config p2" width="782" height="936"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🎉 Enjoy the Workflow 🎉
&lt;/h2&gt;

&lt;p&gt;You've done it! Your code is now guarded by a robot. &lt;/p&gt;

&lt;p&gt;Checkout my implementation and example pull requests in my &lt;a href="https://github.com/chdwck/end-2-end-integration-test-article-example"&gt;end-2-end-integration-test-article-example&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>postgres</category>
      <category>testing</category>
      <category>github</category>
    </item>
  </channel>
</rss>
