Testing framework for Hack.
Disclaimer: This is a "quick'n'dirty" project that I created while learning Hack and diving into PHP. There are A LOT of things to do before using it in a real production environment :)
- Install and run
- My first test
- More examples
- Testing lifecycle
- Extending HHUnit
- Contributing
- License
You should have hhvm running on your computer.
We will soon publish a beta version on composer. In the meantime, you should clone this repository and create an alias to the hhunit
file:
git clone [email protected]:vdurmont/hhunit.git ~/.hhunit
alias hhunit="hhvm ~/.hhunit/hhunit"
Run with:
hhunit [testPath]
testPath
is optional. If not provided, the current working directory will be used as a test path.
Let's say you have a class like this one:
<?hh // strict
class MyCalculator {
public static function add(int $a, int $b) : int {
return $a + $b;
}
}
Here is a simple test (the class must have the HHUnit
attribute):
<?hh // strict
use \HHUnit\Assert\Assert;
use \HHUnit\Core\ClassLoader;
<<HHUnit>>
class MyCalculatorTest {
<<SetUpClass>>
public static function setUpClass() : void {
ClassLoader::loadClass(__DIR__."/MyCalculator.hh");
}
<<Test>>
public function add_with_2_positive_integers() : void {
$result = MyCalculator::add(3, 4);
Assert::equals(7, $result);
}
}
Let's run it:
hhunit /path/to/MyCalculatorTest.hh
You can find examples in the examples folder.
Here is how HHUnit works:
- (1) HHUnit will search recursively in the
testPath
directory for files namedHHUnitSetUp.hh
. If some are found, they will be executed. - (2) For each TestSuite:
- (2.1) If your TestSuite has a method with a
<<SetUpClass>>
attribute, it will be executed. - (2.2) For each TestCase:
- (2.2.1) If your TestSuite has a method with a
<<SetUp>>
attribute, it will be executed. - (2.2.2) The TestCase method (with a
<<Test>>
attribute) will be executed. - (2.2.3) If your TestSuite has a method with a
<<TearDown>>
attribute, it will be executed.
- (2.2.1) If your TestSuite has a method with a
- (2.3) If your TestSuite has a method with a
<<TearDownClass>>
attribute, it will be executed.
- (2.1) If your TestSuite has a method with a
- (3) HHUnit will search recursively in the
testPath
directory for files namedHHUnitTearDown.hh
. If some are found, they will be executed.
If the file exists, it will be executed before all the tests. Here are a few examples of what you could do there:
- Change the internal configuration of HHUnit (Runners, IFileService...)
- Start your database server
- Create a directory to store temporary files
- Register your
spl_autoload
- // TODO other ideas?
If you defined this method, it will be executed before running the TestSuite. Here are a few examples of what you could do there:
- Create a new database
- Check if the database state is clean
- Load the classes you need for this TestSuite
- // TODO other ideas?
If you defined this method, it will be executed before running each TestCase. Here are a few examples of what you could do there:
- Check if the database state is clean
- Instantiate some common objects you use in the tests
- // TODO other ideas?
Just write your test :)
If you defined this method, it will be executed after running each TestCase. Here are a few examples of what you could do there:
- Clean the database
- Reset some common objects you use in the tests
- // TODO other ideas?
If you defined this method, it will be executed after running the TestSuite. Here are a few examples of what you could do there:
- Delete a database
- Unload classes
- // TODO other ideas?
If the file exists, it will be executed after all the tests. Here are a few examples of what you could do there:
- Stop your database server
- Clean some temporary directories
- // TODO other ideas?
If you have the following hierarchy:
<testPath>
|- HHUnitSetUp.hh
|- HHUnitTearDown.hh
|- MyFirstTest.hh
|- MySecondTest.hh
|- folder1
| |- HHUnitSetUp.hh
| |- HHUnitTearDown.hh
| |- MyFirstSubTest.hh
| \- MySecondSubTest.hh
|
\- folder2
\- MyThirdSubTest.hh
The execution flow will be:
<testPath>/HHUnitSetUp.hh
<testPath>/MyFirstTest.hh
<testPath>/MySecondTest.hh
<testPath>/folder1/HHUnitSetUp.hh
<testPath>/folder1/MyFirstSubTest.hh
<testPath>/folder1/MySecondSubTest.hh
<testPath>/folder1/HHUnitTearDown.hh
<testPath>/folder2/MyThirdSubTest.hh
<testPath>/HHUnitTearDown.hh
// TODO write me
// TODO write me
Check out LICENSE.md.