Unit tests running at build

I have a unit test, it compiles and I’ve added a “static MyTest myTest” at the bottom. So far so good.

How do I make my unit tests run when building.
I know there is a UnitTestRunner class but I don’t want to load up full environment to start whole plugin just to run at few tests.
I feel like I’m missing something obvious here.

I saw some other old thread of someone making a completely different jucer file connected to the same directory and build that separately but it seems like a hazzle.

1 Like

I’m b.t.w. still using JUCE4 if that makes any difference.

If ProJucer is unable to create test build target, how are you guys using the Unit Tests, separate jucer project, or trigger from within plugin or some other mechanism?
It feels like a basic thing and that I’ve probably missed something obvious but I can’t find it.

That’s what I am doing, and it’s quite some maintenance work to keep the files in sync.

It’d be great if it’d work like @KeytarHero requests here: Unit tests for classes in audio plugin - #5 by KeytarHero

JUCE team, any chance for this to happen?

2 Likes

I’d like to avoid that if possible, my main selling point of paying for JUCE in the first place is not to have to spend as much time with projects, dependencies and that kind of stuff “around” the code.
The issue is not the test classes in JUCE, it is ProJucer.
Since we are in the hands of ProJucer (unless we want to break out of the JUCE way) it would be best if it could add one more target.
Debug, Release and Test would be great.

Jules, Fabian… what do you guys think about this?

We simply run the UnitTestRunner project in JUCE/extras at the end of the build. We also do this for all ROLI apps (not only for JUCE). There isn’t that much syncing involved really. If your class is big enough that it needs a new unit test then you just need to add that source file to your plug-in project and the UnitTestRunner project.

An alternative is to store your code in a JUCE module and add the JUCE module to the UnitTestRunner. This way any new code is synced automatically.

1 Like

That’s a great idea! I’ll give this a try for all tests that need the full program code.

Yes running UnitTestRunner at the end of the build is of course the way to run unit tests.
I interpret it as that you are having a separate project (separate jucer file) to be able to run the unit tests. That’s exactly what I wanted to avoid. That means double maintenance.
The most common way of running unit tests are doing in the build normal process possibly with a specific build target (in the make world at least).
Now I know at least, I’ll figure out my path.

Sorry for the confusion. With UnitTestRunner, I meant the JUCE project located in JUCE/extras and not the UnitTestRunner class. I’ve edited my above post.

Yes I get that, thus separate project to maintain. It’s a bit awkward workaround to extend and maintain what is essentially library code to run our own unit tests. I can see it would fit while inside ROLI as long as the full test suite is quick to run though.
The best solution would be to have a test target that targets test target in xcode, make files, and visual studio.

I don’t quite understand what you think is missing… If you want to add a “test” target, then just add another target, call it “test” and set whatever flag you’ve used to enable your unit test code.

How would that help, I’d still need to start full plugin and DAW to run the tests right?

This is after all a plugin, not a standalone program. If it be standalone I could make an ifdef around main() to choose which version to run… one with real program one that just starts UnitTestRunner. Then a compiler flag in ProJucer would do.

Open xcode and long press the “play” button, you’ll see a few choices there, including test. Try running that and you’ll see a message that the scheme is not configured for testing. Since ProJucer is making the xcode-project ProJucer should be the one handling that.

I would go with the separate jucer project but keep all the source code in a juce module so that it doesn’t require syncing as mentioned above - this should require absolutely minimal synchronization. However another option is to create an entry point in your plugin that runs the unit tests and call this from some other command line application that you can make with JUCE. In the case of mac I believe you can just do it in main and call the executable from terminal - but I think Windows is a bit more of a pain.

How do you get the UnitTestRunner console app to see unit tests in a separate plugin project? Is it correct to add the unit test code to the plugins project? I tried that and couldn’t get it to work, by adding:

#pragma once

#include “…/JuceLibraryCode/JuceHeader.h”

#include “./myTailGun-UnitTests.h”

class MyTest : public UnitTest
{
public:
MyTest() : UnitTest (“Foobar testing”) {}

void runTest() override
{
    beginTest ("Part 1");
    
    expect (true, "Test one");
    expect (true, "Test two");
    
    beginTest ("Part 2");
    
    expect (true);
    expect (true);
}

};

// Creating a static instance will automatically add the instance to the array
// returned by UnitTest::getAllTests(), so the test will be included when you call
// UnitTestRunner::runAllTests()
static MyTest test;

I did get the above code to work when adding into the UnitTestRunner project. And was thinking I’d need to clone the UnitTestRunner for each different plugin. However, I can’t figure out how to make it only run my tests, as it runs a bunch of ‘system’ tests too.

And if supposed to add unit tests to UnitTestRunner, how do I get it to see the code I wrote in the actual plugin project?

After a few hours I figured this out. I posted the answer here on a related post. If there’s a better way, please let me know.