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
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:
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 ();
}
}
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");
});
}
}
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.