Categories
Dev Life

I Guess I Test Now

My favorite joke, or truth, is “We’ll test in Production.” Which is great when things work. I added a lot more features to ThiefMD. My test approach was “Hands on Functional Testing.” Which worked well until I tried to do a release blog post, and the images weren’t there.

So today, I learned how to enable GitHub Actions.

Hopefully it’ll prevent me from breaking anything major.

Downloading Strange Things on the Internet to Stranger’s Computers

One of the issues I ran into was GitHub Workflows run Ubuntu 20.04. I needed libhandy-1-dev, which isn’t included by default.

There’s some random libhandy-1 ppa for Focal, which I decided to use. Luckily, it’s on GitHub’s computers, so I don’t need to worry about anything bad happening on my laptop 😅. I also stole some of the Workflow from vala-langauge-server’s daily integration.

For my Vala project, I wound up with:

name: ThiefDaily  
on: [push]  
jobs:  
  build:  
    runs-on: ubuntu-latest  
    steps:  
      - name: Checkout  
        uses: actions/checkout@v2  
      - name: Add vala next  
        run: sudo add-apt-repository ppa:vala-team/daily  
      - name: Add libhandy-1 for focal  
        run: sudo add-apt-repository ppa:apandada1/libhandy-1  
      - name: Update Ubuntu  
        run: sudo apt-get update  
      - name: Install build essentials  
        run: sudo apt-get install build-essential meson ninja-build valac cmake libgtkspell3-3-dev libwebkit2gtk-4.0-dev libmarkdown2-dev libxml2-dev libclutter-1.0-dev libarchive-dev libgtk-3-dev libgee-0.8-dev libgtksourceview-4-dev libsecret-1-dev libhandy-1-dev  
      - name: Init submodules  
        run: git submodule init  
      - name: Update submodules  
        run: git submodule update --remote --recursive  
      - name: Setup Build  
        run: meson build  
      - name: Configure build  
        run: meson configure -Dbuild_tests=true build  
      - name: Run Build  
        run: ninja -C build  
      - name: Test  
        run: ./build/tests/tests  
Code language: YAML (yaml)

The first steps are adding package repositories and installing build requirements. Init submodules & Update submodules downloads source code dependencies.

Test is where the magic happens. This workflow lets me know when things aren’t working:

Test & Build Status

Testing with GLib.Test?

I couldn’t find anything too recent on GLib.Test testing. GNOME Documentation simplifies it to add_func and assert. I could make this work.

I created a main function for running the tests.

public class ThiefTests {  
    public static int main (string[] args) {  
        Test.init (ref args);  
        new ImageExtractionTests ();  
        new MarkdownTests ();  
        new FileManagerTests ();  
        return Test.run ();  
    }  
}  
Code language: Vala (vala)

ImageExtractionTests monitor what I broke. It’s all a bunch of complicated Regexes, so they’re worth monitoring still.

Test.init is required for setting up the test environment. Each new BoringTests(); adds a set of tests to run. Test.run () runs all the tests added and returns a status code for pass or fail.

For example, the MarkdownTests (which don’t test Markdown) look like:

using ThiefMD;  
using ThiefMD.Controllers;  

public class MarkdownTests {  
    public MarkdownTests () {  
        Test.add_func ("/thiefmd/file_extensions", () => {  
            assert (is_fountain ("screenplay.fou"));  
            assert (is_fountain ("screenplay.fountain"));  
            assert (is_fountain ("screenplay.spmd"));  
            assert (!is_fountain ("screenplay.markdown"));  
            assert (!is_fountain ("screenplay.fountain.markdown"));  
            assert (!is_fountain ("screenplay.docx"));  
            assert (!is_fountain ("screenplay.bib"));  
        });  

        Test.add_func ("/thiefmd/titles", () => {  
            assert (make_title ("this_cool_cat") == "This Cool Cat");  
            assert (make_title ("this-cool_cat") == "This Cool Cat");  
            assert (make_title ("this_cool-cat") == "This Cool Cat");  
            assert (make_title ("this cool-cat") == "This Cool Cat");  
            assert (make_title ("this_cool cat") == "This Cool Cat");  
        });  

        Test.add_func ("/thiefmd/find_file", () => {  
            assert (Pandoc.find_file ("README.md", Environment.get_current_dir ()) != "");  
            assert (Pandoc.find_file ("README.md", Environment.get_current_dir ()) != "README.md");  
        });  
    }  
}  
Code language: Vala (vala)

I can call Test.add_func as many times as I want. The first string has to be unique. assert will fail the tests if the condition is false. If all the asserts have true conditions, the tests are considered passed.

I added tests for resolving absolutio reference paths, and creating the list of images to upload. I also sprinkled in a few tests for other critical functionality.

So hopefully, I don’t break anything major again.