Custom Unit Tests with Arcanist

Phabricator is a project management tool with integrated repository, bug tracker and many more tools. Arcanist is a command line client for many of Phabricators services. It supports developers to write good software in a way that conforms to modern standards.

Since good software is always tested and one good test is to write unit tests, Arcanist supports the user to use its unit test modules for some test frameworks. You just need to specify the default test engine.

In this article, I want to write down and show you how to set up Arcanist to execute custom unit tests with a custom unit test engine, because sometimes there are no standard engines that support your unit test workflow.

Let's go through it, step by step.

Setting Up For Unit Tests

I assume that you have already set up Arcanist to communicate with your Phabricator installation, so I will skip these steps here.

Your .arcconfig in the project root should look like this:

{ "phabricator.uri" : "", "repository.callsign" : "MYREPO", "unit.engine" : "MyUnitTestEngine", "load" : [ "lib" ] }

The unit.engine entry specifies what unit test engine class to call when executing unit tests. The entry load is collection of directories where libphutil can find the your custom PHP classes that also contain your MyUnitTestEngine class. The entry here will scan the directory ./lib for a libphutil library descriptor.

Writing a libphutil library descriptor

It's easy. Place this in a file called __phutil_library_init__.php in a subdirectory ./lib in your project repository. It will be read automatically whereever it is (this is just an example).

<?php phutil_register_library('my-unit-test-engine', __FILE__); ?>

Write a Unit Test Engine Class

This is a sample test engine. It shows how to return unit test results with such class, but of course it does not really run any real tests. Place this file in the subdirectory of ./lib in your project, for example ./lib/engine/MyUnitTestEngine.php.

<?php final class MyUnitTestEngine extends ArcanistUnitTestEngine { public function run() { $sample_results = array(); # example for a passed test result $result_success = new ArcanistUnitTestResult(); $result_success->setName("A successful test"); $result_success->setResult(ArcanistUnitTestResult::RESULT_PASS); $result_success->setDuration(1); # example for a failed test result $result_failure = new ArcanistUnitTestResult(); $result_failure->setName("A failed test"); $result_failure->setResult(ArcanistUnitTestResult::RESULT_FAIL); $result_failure->setUserData( "This test failed, because we wanted it to fail." ); # add both results $sample_results[] = $result_success; $sample_results[] = $result_failure; # return the result set return $sample_results; } }

Prepare the Unit Test Engine

The unit test engine classes and the descriptor are in place. Now, simply run these two commands in the project root directory.

# /usr/local/lib/php/libphutil/scripts/phutil_rebuild_map.php ./lib # arc liberate

This will prepare the class to be used by Arcanist later.

Problems with Arcanist on FreeBSD

On FreeBSD there is a problem with the Arcanist installation. To fix it, you should execute arc liberate in /usr/local/lib/php/arcanist/src itself.

After this, the arc liberate command in your own repository should work fine.

Test the Sample Engine

Now, everything is ready. The unit tests are started with:

# arc unit .

arc unit gets paths as parameters which can restrict the unit test to a subcomponent. You can access this path with the getPaths() function, but you need to handle the restriction yourself in your custom unit test engine.