Why Meson and not make? Or, how are people doing testing in C++?

Viewed 27

I'm working through Learn C++ the Hard Way and largely having a good time. But right now, I'm in module 2, need to start automating my testing, and am running into headaches.

I've worked through parts of Learn C the Hard Way, so I'm used to using GNU make, which makes it trivial to define my own targets and make them run arbitrary shell commands, such as shell scripts that wrap testing—just as Zed demonstrates in the C book. I even cooked up a little Makefile to remind myself if it would work, and it does.

Here, though, I'm trying to figure out how to do something similar with Meson, and either I'm not understanding their documentation correctly or not understanding the design of the build system altogether and how to adapt to it.

I have a Bash script with a few simple functions that take the name of a utility and command-line args to pass to said utility and test either the system return codes or the behavior. I then create test cases by calling these functions with names and args. Run the script and bam, testing. Invoke it from a Makefile? Sure. make doesn't care. Try to do with Meson? Errors upon errors.

I looked into trying to use meson test, because it's built into Meson and offers reporting already, but I can't wrap my head around how to do it, based on the Meson docs, especially if it's a system test as opposed to a unit test. Tried run_command, but the builddir vs source dir thing is causing errors that don't happen when I run things by hand.

I also briefly looked at trying to pull in GTest, because there's a Meson wrap for it and apparently quite good docs, but in reading those docs, it looks like complete overkill for this level of project.

Any insight or hints would be greatly appreciated.

2 Answers

I finally figured out a way to do this properly using shell scripts, as I intended, and meson test.

Basically, I was struggling to figure out how to tell Meson about the shell scripts.

Process:

  1. Define a variable for each test script using the files() function in Meson, passing in the filepath for the script. Example:
    testdir = 'tests'
    # slash operator ( / ) does path concatenation
    test_basic = files(testdir / 'test-basic.sh')
    
  2. Write the test script
    • It lives in the source directory but needs to use paths relative to builddir; this was a serious pain point until I figured out why Meson kept complaining
    • I can define input filenames, options to pass, etc.
    • I use diff to do output diffing and process substitution so diff can properly compare the stdout of the GNU version of the util and my version, which aren't actually files, as diff would expect by default
  3. Use Meson's test() function, passing a test name and the variable defined in step 1. Example:
    test('basics', test_basic)
    

Yes, Meson has a testing feature, and looks like you figure it out, but I actually use a Makefile too. It's just too handy to be able to run arbitrary commands, especially when you come to start doing debugging. Look in the C++ starter project and you should see I have one. Go ahead and copy from that if you need ideas.