How to Use Github Actions and Pytest For Your Python Project

Continuous Integration and Continuous Delivery and Deployment are essential principles in software
development cycle. It has become the standard for every source version control hosting platform such as GitLab, Github, Azure Devops,etc to offer CI/CD pipelines in their platform.

In this tutorial we will explore how to use Github Actions – a form of CI/CD workflow technology to automate your build,test, deploy process.

Let start.

The requirements for GitHub is to create a .github\workflows directory in your project or repository. Next you will need to add a .yml file where you will place your workflow instructions for the particular activity you want to do upon push or pull of your code.

Basic Workflow for Python

Inside our yaml file we will specify our jobs – build and test as below

name: myproject

on:
  push:
    branches: [master,develop]
  pull_request:

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.8", "3.9", "3.10", "3.11"]

    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install pytest
        run: python -m pip install pytest
      - name: Test with pytest
        run: pytest --junit-xml=test-results.xml
      - name: Publish Test Results
        uses: EnricoMi/publish-unit-test-result-action@v2
        if: always()
        with:
          files: |
            test-results.xml
            test-results/**/*.xml
            test-results/**/*.json

In our file we specify when to trigger our workflow either via a push or a pull request and on which branch we want it to be triggered.

name: myproject

on:
  push:
    branches: [master,develop]
  pull_request:

We then specify our build job and what python versions and OS to use

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.8", "3.9", "3.10", "3.11"]

    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}

Since we are just working with python we will install our dependencies as well as pytest – our testing framework. We can now add our .github\workflows\ci.yml to our repository and trigger our workflow with any push.

Publishing Test Result

In most cases the output in the stdout is okay, however we can do more by displaying the test results via tools like Junit, etc. These tools support several format such as .xml,json,etc. With pytest you can specify to pipe the result to a junit format using the`–junit` option as below

`pytest –junit-xml=test-results.xml`

Notice that the test-results.xml should match with the publish-unit-test files in order for your test to be discoverable and published.
We can now add another github actions to publish our test result in a nice UI as below

      - name: Publish Test Results
        uses: EnricoMi/publish-unit-test-result-action@v2
        if: always()
        with:
          files: |
            test-results.xml
            test-results/**/*.xml
            test-results/**/*.json

We have seen how we can add a form of CI/CD to our repository via Github actions for our python project. You can also use poetry and caching to speed up your builds for packages. However for now this is good to go.

You can also check out the video tutorial below

Thank you for your attention

Jesus Saves

By Jesse E.Agbe(JCharis)

Leave a Comment

Your email address will not be published. Required fields are marked *