Writing and running tests
Testing KPHP implies many scenarios.
1. Unit tests
They are placed in /tests/cpp/ folder, invoked with gtest, and use standard gtest macros like TEST(…), ASSERT_EQ and others. Take a look at existing tests to find out their structure.
To compile and run unit tests, invoke CMake with the default configuration:
mkdir build
cd build
cmake ..
  Then compile and run them:
make -j$(nproc) all
ctest -j$(nproc)
  2. Functional tests for runtime and server
They perform complex scenarios like: compile and start HTTP server, send requests, compare responses, check HTTP headers, and so on. They are placed in the /tests/python/tests/ folder, invoked with pytest.
Before running them, you should once perform a setup:
pip3 install --user -r PHP/tests/python/requirements.txt
  To run, use just one-line command:
python3 -m pytest --tb=native -n5 tests/python/tests
  To debug, use -s option and don't use -n
3. Running Zend tests (partially)
A list of KPHP-compatible Zend tests (from PHP sources) is maintained manually. To run them, clone php-src somewhere at first:
git clone https://github.com/php/php-src.git
cd php-src
git checkout 6326717dccf9e85dc41b3778692b790e2501fb2a
  The following command will do all other stuff:
./kphp/tests/kphp_tester.py -j32 -d ./php-src --from-list ./kphp/tests/zend-test-list
  4. Testing compiler and runtime: compare KPHP and PHP
This is the most important testing part, and typically you’ll write such tests when adding new KPHP features.
This scenario is the following:
- There is a .php file
- Run it with PHP
- Compile and run it with KPHP
- Compare results
All such tests are placed in the /tests/phpt folder. It's supposed that you have vkext installed and PHP 7.4 executable.
As a prerequisite, create a local copy of kphp-polyfills. This should be done only once:
git clone https://github.com/VKCOM/kphp-polyfills.git
cd kphp-polyfills
composer install
export KPHP_TESTS_POLYFILLS_REPO=$(pwd)
  To run all tests (assume that you are in kphp/ sources folder):
tests/kphp_tester.py
  To run a specific test / set of tests, use tags and parts of filenames or folders:
tests/kphp_tester.py tag1
tests/kphp_tester.py substring_of_filename
tests/kphp_tester.py dir
  To write such tests, examine how existing tests are made. For example:
@ok
<?php
require_once 'kphp_tester_include.php';
class Foo {
  var $v = 0;
  public function __construct(int $v) { $this->v = $v; }
}
/** @var tuple(Foo, string)[] */
$xs = [tuple(new Foo(5), "a"), tuple(new Foo(10), "b")];
foreach ($xs as [$foo, $s]) {
  var_dump($foo->v);
}
  - @okabove is a tag; there can be many tags, for example,- @ok access— you use them for filtering
- require_onceis to make polyfills be available for plain PHP (not needed if you don't use KPHP specifics)
- it's a regular PHP code, you can use #ifndefand others
After tags, you can optionally set ENV_VAR=value on the next lines, before <?php.
There is a special tag @kphp_should_fail — to declare, that code doesn't compile, but it's expected:
@kphp_should_fail
/mix class A with non-class/
<?php
class A { public $x = 1; }
$a = new A;
if (0) 
  $a = false;
  After @kphp_should_fail, an optional regexp can be present on the next line.
A special tag @kphp_should_warn is similar, indicating that KPHP compiles but produces a compilation warning.
Always write such tests when implementing new PHP syntax features or adding new functions.