How to run integration tests using Github Actions
Tags: javascript, postgres, testing, github
Published: 2021-11-19 21:50:27

[GitHub Actions](https://docs.github.com/en/actions) allow us to easily verify if a Pull Request is safe to merge into a main branch. 

This article assumes you have a basic functional understanding of [Github](https://github.com/) and [Integration Testing](https://www.tutorialspoint.com/software_testing_dictionary/integration_testing.htm) and will be covering:
* How to run integration tests in a [CI](https://www.atlassian.com/continuous-delivery/continuous-integration) environment using **GitHub Actions**
* How to prevent failing Pull Requests from being merged

## :robot: Create the Workflow :robot:
In your Github repository, navigate to the **Actions** tab.
![Actions Tab](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/atn2n6f0qq3d5hhpeu8f.png)
 

Chose the workflow template that best suits your needs, commit the changes, and pull the new `.github/` folder into your local environment.



## :wrench: Customize the Workflow :wrench:
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.

To add a test database, add a services section to the `<project-root>/.github/workflow/workflow_name.yml` file under the job name.  

```yml
# .github/workflows/node.js.yml

...

jobs:
  # name of the job
  ci:

    # The OS of the docker container
    # Github runs the workflows on
    runs-on: ubuntu-latest

    strategy:
      matrix:
        # node version(s) to run against
        node-version: ['16.x']

    services:
      # name of the service
      postgresql:
        # The software image the container
        # will download and start
        image: 'postgres:14'
        ports:
          # map external port to container. This is
          # important because our app will run outside
          # our postgres container
          - '54320:5432'
        
        # Environment Variables
        env:
          POSTGRES_DB: example_app_test_db
          POSTGRES_PASSWORD: jamesbond
          POSTGRES_USER: example_app_db_test_user
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

...

```

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. **e.g** `postgresql://example_app_db_test_user:jamesbond@localhost:54320/example_app_test_db`

Update the steps section to set up and test your code.

```yml
# .github/workflows/node.js.yml
...
    steps:
    # Checkout our branch in the container
    - name: Checkout 🛎
      uses: actions/checkout@v2

    # Download and setup nodejs
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v2
      with:
        node-version: ${{ matrix.node-version }}
        cache: 'npm'
    
    - name: Install dependencies 👨🏻‍💻
      run: npm ci

    - name: Migrate Database 🏗️
      run: npm run migrate

    - name: Seed Test Data 🌱
      run: npm run db:seed

    - name: run end-to-end tests 🧪
      run: npm run test
...
```

Go ahead and push those changes.

Inspect the logs by clicking the **details** link under the checks section near the merge button at the bottom of the page.![Pull request check details](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ojufwetrzljtn7t7an4p.png)

You can also see all workflow logs by navigating back to the actions tab.

Once your checks are coming back ✅, you're ready to merge that Pull Request and move on.
 
## 🥋 Respect the Workflow 🥋
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.

Navigate to the repository branches settings and click the **Add Rule** button.![Add Rule Button](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v83grooms9at7xnlgtp7.png)

### Configuration
1. Set **Branch Name Pattern** to `*` to match all branches (or whatever regex pattern you need to target certain branches)
2. Check **Require status checks to pass before merging** and search for the job name used in your `.github/workflow/workflow_name.yml` file. I used the name `ci`
3. Check **Require branches to be up to date before merging**
```yml
# .github/workflows/node.js.yml

...

jobs:
  # name of the job
  ci:
...
```
![Branch rule config p1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/err601vnyudnrm5dq70g.png)
 
4. ***(Optional)*** Check **Include Administrators** to keep yourself from pushing breaking changes
![Branch rule config p2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6dxkmhcqc2cistcccbeb.png)
 


## :tada: Enjoy the Workflow :tada:
You've done it! Your code is now guarded by a robot. 

Checkout my implementation and example pull requests in my [end-2-end-integration-test-article-example](https://github.com/chdwck/end-2-end-integration-test-article-example).

Happy Coding!