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.