PHP code example of alexskrypnyk / phpunit-helpers
1. Go to this page and download the library: Download alexskrypnyk/phpunit-helpers library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
alexskrypnyk / phpunit-helpers example snippets
use AlexSkrypnyk\PhpunitHelpers\UnitTestCase;
class MyTest extends UnitTestCase {
public function testExample(): void {
// Test implementation that benefits from the tring {
// Excluded from info() because the name contains "test".
return 'This will not appear in info()';
}
}
use AlexSkrypnyk\PhpunitHelpers\Traits\AssertArrayTrait;
use PHPUnit\Framework\TestCase;
class MyAssertArrayTest extends TestCase {
use AssertArrayTrait;
public function testCustomAssertions(): void {
$array = ['This is a test', 'Another value'];
// Assert that a string is present in one of the array values.
$this->assertArrayContainsString('test', $array);
// Assert with a custom failure message.
$this->assertArrayContainsString('test', $array, 'Not found');
// Assert that a string is absent from all array values.
$this->assertArrayNotContainsString('missing', $array);
// Assert that an array contains all elements of a sub-array.
// Nested arrays are searched recursively.
$this->assertArrayContainsArray(
['a', 'b', ['c', 'd']],
['a', ['c', 'd']]
);
// Assert that an array contains none of the sub-array elements.
$this->assertArrayNotContainsArray(['a', 'b'], ['z']);
}
}
use AlexSkrypnyk\PhpunitHelpers\Traits\ApplicationTrait;
use PHPUnit\Framework\TestCase;
class MyApplicationTest extends TestCase {
use ApplicationTrait;
protected function setUp(): void {
// Working directory, NULL for the current PHP process directory.
$this->applicationCwd = NULL;
// Whether to show the output during execution.
$this->applicationShowOutput = FALSE;
}
protected function tearDown(): void {
$this->applicationTearDown();
}
public function testConsoleApplication(): void {
// Initialize the application from a loader file that returns an
// Application instance.
$this->applicationInitFromLoader('/path/to/application_loader.php');
// Or initialize it from a command class or object. The second
// argument makes it the single default command.
$this->applicationInitFromCommand(MyCommand::class, TRUE);
// Both initializers return the ApplicationTester. The application
// and the tester are also available on demand.
$application = $this->applicationGet();
$tester = $this->applicationGetTester();
// Run the application with input arguments and options.
$output = $this->applicationRun(
// Input arguments and options.
['argument1', '--option1=value1'],
// Application tester options.
['capture_stderr_separately' => TRUE],
// Whether a failure is expected. Defaults to FALSE.
FALSE
);
// Assert on the exit code.
$this->assertApplicationSuccessful();
$this->assertApplicationFailed();
// Assert that the output contains string(s).
$this->assertApplicationOutputContains('Expected output');
$this->assertApplicationOutputContains(['String1', 'String2']);
$this->assertApplicationOutputContains('Expected', 'Not found');
// Assert that the output does not contain string(s).
$this->assertApplicationOutputNotContains('Unexpected output');
// The same assertions are available for the error output.
$this->assertApplicationErrorOutputContains('Expected error');
$this->assertApplicationErrorOutputNotContains('Unexpected error');
// And for the standard and error output combined.
$this->assertApplicationAnyOutputContains('In either output');
$this->assertApplicationAnyOutputNotContains('In neither output');
// Assert several conditions in one call using prefixes. See the
// StringTrait section for the full prefix reference.
// Shortcut mode: no prefixes, all must be present as substrings.
$this->assertApplicationOutputContainsOrNot(['Expected', 'Output']);
// Mixed mode: if any string has a prefix, all of them must.
$this->assertApplicationOutputContainsOrNot([
// Present as a substring.
'* Expected',
// Absent as a substring.
'! Unexpected',
]);
$this->assertApplicationErrorOutputContainsOrNot(['* Error']);
$this->assertApplicationAnyOutputContainsOrNot(['* Either', '! No']);
// '+' and '-' compare against the whole trimmed output, so they
// only make sense for a single-line output.
$this->assertApplicationOutputContainsOrNot([
// The whole output must equal this.
'+ Hello, World!',
]);
// Get debug info about the application (output, error output).
echo $this->applicationInfo();
}
}
use AlexSkrypnyk\PhpunitHelpers\Traits\EnvTrait;
use PHPUnit\Framework\TestCase;
class MyEnvTest extends TestCase {
use EnvTrait;
public function testEnvironmentVariables(): void {
// Set an environment variable.
self::envSet('MY_VAR', 'value');
// Set multiple environment variables.
self::envSetMultiple(['VAR1' => 'value1', 'VAR2' => 'value2']);
// Get an environment variable. Returns FALSE when it is not set.
$value = self::envGet('MY_VAR');
// Check whether an environment variable is set.
$is_set = self::envIsSet('MY_VAR');
$is_unset = self::envIsUnset('MY_VAR');
// Unset an environment variable.
self::envUnset('MY_VAR');
// Unset multiple environment variables.
self::envUnsetMultiple(['VAR1', 'VAR2']);
// Unset every environment variable with a given prefix.
self::envUnsetPrefix('MY_');
// Set environment variables from an input array. Matching entries
// are removed from the input array unless the third argument is
// FALSE.
$input = ['MY_VAR' => 'value', 'other' => 'kept'];
self::envFromInput($input, 'MY_');
// Unset every variable that was set through this trait.
self::envReset();
}
}
use AlexSkrypnyk\PhpunitHelpers\Traits\LocationsTrait;
use PHPUnit\Framework\TestCase;
class MyLocationsTest extends TestCase {
use LocationsTrait;
protected function setUp(): void {
// Create the test directories.
$this->locationsInit();
// Root directory of the project.
echo self::$root;
// Fixtures directory, or NULL when it does not exist.
echo self::$fixtures;
// Workspace directory holding the assets of a single test run.
echo self::$workspace;
// Source directory for operations.
echo self::$repo;
// System Under Test directory where the test runs.
echo self::$sut;
// Temporary files directory.
echo self::$tmp;
// The same paths are available through accessors.
echo self::locationsRoot();
echo self::locationsFixtures();
echo self::locationsWorkspace();
echo self::locationsRepo();
echo self::locationsSut();
echo self::locationsTmp();
// Print all locations at once.
echo self::locationsInfo();
}
protected function tearDown(): void {
// Remove the workspace directory and everything below it.
$this->locationsTearDown();
}
/**
* Override to point at a different fixtures directory.
*
* Defaults to 'tests/Fixtures', relative to the repository root.
*/
public static function locationsFixturesDir(): string {
return 'tests/Fixtures';
}
public function testFileOperations(): void {
// Get a named fixtures directory, creating it if needed.
$fixtures_dir = $this->locationsFixtureDir('my-fixture');
// Without a name, the directory is derived from the test name, and
// a named data set adds a further subdirectory. The data set named
// 'baseline' maps to the '_baseline' directory.
$fixtures_dir = $this->locationsFixtureDir();
// Copy files into the SUT directory. A random numeric suffix is
// appended to each name, so the created paths are returned rather
// than derived.
$files = self::locationsCopyFilesToSut(['file1.txt', 'file2.txt']);
$this->assertFileExists($files[0]);
// Pass FALSE as the third argument to keep the original names.
$files = self::locationsCopyFilesToSut(['file1.txt'], NULL, FALSE);
$this->assertFileExists(self::$sut . '/file1.txt');
// Copy between arbitrary directories. '.git', 'node_modules' and
// 'vendor' are always excluded.
$created = self::locationsCopy(self::$repo, self::$sut);
// Create a directory if needed and return its real path.
$path = self::locationsMkdir(self::$tmp . '/nested');
// Resolve a real path, throwing when it does not exist.
$real = self::locationsRealpath($path);
}
}
use AlexSkrypnyk\PhpunitHelpers\Traits\ProcessTrait;
use PHPUnit\Framework\TestCase;
class MyProcessTest extends TestCase {
use ProcessTrait;
protected function setUp(): void {
// Working directory, NULL for the current PHP process directory.
$this->processCwd = NULL;
// Whether to stream the output while the process runs.
$this->processStreamingOutput = FALSE;
}
protected function tearDown(): void {
// Stop the process if it is still running.
$this->processTearDown();
}
public function testCommandExecution(): void {
// Run a command with arguments, inputs, environment variables and
// timeouts. The command name is validated, and every argument must
// be scalar. An environment variable set to FALSE is removed from
// the inherited environment.
$process = $this->processRun(
// Command to execute, optionally with arguments.
'echo',
// Additional command arguments.
['Hello', 'World'],
// Inputs for an interactive process.
['Input1', 'Input2'],
// Additional environment variables.
['ENV_VAR' => 'value'],
// Process timeout in seconds.
60,
// Process idle timeout in seconds.
30
);
// The most recent process is also available on demand.
$process = $this->processGet();
// Assert on the exit code.
$this->assertProcessSuccessful();
$this->assertProcessFailed();
// Assert that the output contains string(s).
$this->assertProcessOutputContains('Hello World');
$this->assertProcessOutputContains(['Hello', 'World']);
$this->assertProcessOutputContains('Hello', 'Not found');
// Assert that the output does not contain string(s).
$this->assertProcessOutputNotContains('Error');
$this->assertProcessOutputNotContains(['Error1', 'Error2']);
// The same assertions are available for the error output.
$this->assertProcessErrorOutputContains('Warning');
$this->assertProcessErrorOutputNotContains('Critical');
// And for the standard and error output combined.
$this->assertProcessAnyOutputContains('In either output');
$this->assertProcessAnyOutputNotContains('In neither output');
// Assert several conditions in one call using prefixes. See the
// StringTrait section for the full prefix reference.
// Shortcut mode: no prefixes, all must be present as substrings.
$this->assertProcessOutputContainsOrNot(['Hello', 'World']);
// Mixed mode: if any string has a prefix, all of them must.
$this->assertProcessOutputContainsOrNot(['* Hello', '! Error']);
$this->assertProcessErrorOutputContainsOrNot(['* Warning']);
$this->assertProcessAnyOutputContainsOrNot(['* Hello', '! Error']);
// '+' and '-' compare against the whole trimmed output, so they
// only make sense for a single-line output.
$this->assertProcessOutputContainsOrNot([
// The whole output must equal this.
'+ Hello World',
]);
}
}
use AlexSkrypnyk\PhpunitHelpers\Traits\SerializableClosureTrait;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
class MyClosureTest extends TestCase {
use SerializableClosureTrait;
#[DataProvider('dataProviderWithClosure')]
public function testWithClosure($callback): void {
// Unwrap the closure before using it.
$callback = self::cu($callback);
$this->assertEquals('ARGUMENT', $callback('argument'));
}
public static function dataProviderWithClosure(): array {
return [
'traditional' => [
self::cw(function ($value) {
return strtoupper($value);
}),
],
'arrow_function' => [
self::cw(fn($value) => strtoupper($value)),
],
];
}
}
use AlexSkrypnyk\PhpunitHelpers\Traits\ReflectionTrait;
use PHPUnit\Framework\TestCase;
class MyReflectionTest extends TestCase {
use ReflectionTrait;
public function testProtectedMethod(): void {
$object = new SomeClass();
// Call a protected method. Pass a class name instead of an object
// to call a protected static method.
$result = self::callProtectedMethod($object, 'protectedMethod', [
'argument',
]);
// Set a protected property value.
self::setProtectedValue($object, 'protectedProperty', 'new value');
// Get a protected property value.
$value = self::getProtectedValue($object, 'protectedProperty');
}
}
use AlexSkrypnyk\PhpunitHelpers\Traits\TuiTrait;
use PHPUnit\Framework\TestCase;
class MyTuiTest extends TestCase {
use TuiTrait;
public function testTuiInteraction(): void {
// Define the default entries for all sets.
$default_entries = [
'answer1' => 'value1',
// Replaced with the default value, an empty string by default.
'answer2' => self::TUI_DEFAULT,
'answer3' => 'value3',
'answer4' => 'value4',
];
// First entry set: use the default for 'answer1'.
$entries_set1 = ['answer1' => self::TUI_DEFAULT] + $default_entries;
$processed_entries = self::tuiEntries($entries_set1);
// Process entries with a custom default value.
$processed_entries = self::tuiEntries($entries_set1, 'custom');
// Second entry set: skip 'answer2' so it is left out entirely.
$entries_set2 = ['answer2' => self::TUI_SKIP] + $default_entries;
$processed_entries = self::tuiEntries($entries_set2);
// Convert entries to keystrokes for character-by-character input.
$keystrokes = self::tuiKeystrokes($entries_set1);
// Keystroke conversion with options.
$keystrokes = self::tuiKeystrokes(
// Entries to convert.
$entries_set1,
// Number of characters to clear before entering new text.
3,
// Accept key. Defaults to the Enter key.
self::KEYS['TAB'],
// Clear key. Defaults to the Backspace key.
self::KEYS['BACKSPACE']
);
// Convert a single entry into its keystrokes.
$split = self::tuiEntryToKeystroke('ab' . self::KEYS['ENTER']);
// Special keys are available as constants.
$up_key = self::KEYS['UP'];
$enter_key = self::KEYS['ENTER'];
$tab_key = self::KEYS['TAB'];
$esc_key = self::KEYS['ESCAPE'];
$ctrl_c = self::KEYS['CTRL_C'];
$backspace = self::KEYS['BACKSPACE'];
// Arrow keys are supported in more than one format.
$up_arrow = self::KEYS['UP_ARROW'];
// Yes and No entries are predefined and can be overridden.
$yes = self::$tuiYes;
$no = self::$tuiNo;
// Check whether a value is, or contains, a special key.
$is_key = self::tuiIsKey($enter_key);
$has_key = self::tuiHasKey('abc' . $enter_key);
}
}
use AlexSkrypnyk\PhpunitHelpers\Traits\StringTrait;
use PHPUnit\Framework\TestCase;
class MyStringTest extends TestCase {
use StringTrait;
public function testSimpleStringMatching(): void {
$haystack = 'The quick brown fox jumps over the lazy dog';
// Shortcut mode: all values must be present as substrings.
$this->assertStringContainsOrNot($haystack, [
'quick',
'brown',
'fox',
]);
// Mixed mode: every value carries a prefix.
$this->assertStringContainsOrNot($haystack, [
// Present as a substring.
'* brown',
// Absent as an exact match of the whole haystack.
'- slow',
// Absent as a substring.
'! elephant',
]);
// '+' matches the whole haystack.
$this->assertStringContainsOrNot('Hello', ['+ Hello']);
// Matching is case-insensitive by default.
$this->assertStringContainsOrNot('Hello WORLD', ['* world']);
// Case-sensitive matching, with the defaults spelled out.
$this->assertStringContainsOrNot(
'Hello WORLD',
['* WORLD', '! world'],
'Expected exact match for "%s" in haystack',
'Expected substring "%s" in haystack',
'Expected no exact match for "%s" in haystack',
'Expected substring "%s" not in haystack',
// Prefixes: present exact, present contains, absent exact,
// absent contains.
'+', '*', '-', '!',
// Separator between the prefix and the value.
' ',
// Case-insensitive matching, turned off here.
FALSE
);
// Custom prefixes.
$this->assertStringContainsOrNot(
$haystack,
['~ brown', '_ slow', '? elephant'],
'Expected exact match for "%s" in haystack',
'Expected substring "%s" in haystack',
'Expected no exact match for "%s" in haystack',
'Expected substring "%s" not in haystack',
// Present exact.
'#',
// Present contains.
'~',
// Absent exact.
'_',
// Absent contains.
'?'
);
}
}
use AlexSkrypnyk\PhpunitHelpers\Traits\LoggerTrait;
use PHPUnit\Framework\TestCase;
class MyLoggerTest extends TestCase {
use LoggerTrait;
protected function setUp(): void {
static::logSetVerbose(TRUE);
}
public function testHierarchicalWorkflow(): void {
static::log('Basic debug message');
static::logSection('SECTION TITLE', 'Section content');
static::logFile('/path/to/file.txt', 'Optional description');
// Step tracking with automatic timing. The step name is taken from
// the calling method, so the argument is only a message.
static::logStepStart('Optional step message');
static::logSubstep('Processing data');
static::logNote('Additional context information');
// A step started inside another step nests below it.
$this->stepNested();
static::logStepFinish('Step completed successfully');
// logStepSummary() returns the table rather than printing it.
static::logSection('WORKFLOW SUMMARY', static::logStepSummary(), TRUE, 80);
}
protected function stepNested(): void {
static::logStepStart('Nested operation');
static::logStepFinish('Nested operation complete');
}
}
use AlexSkrypnyk\PhpunitHelpers\Traits\ApplicationTrait;
use AlexSkrypnyk\PhpunitHelpers\Traits\AssertArrayTrait;
use AlexSkrypnyk\PhpunitHelpers\Traits\EnvTrait;
use AlexSkrypnyk\PhpunitHelpers\Traits\LoggerTrait;
use AlexSkrypnyk\PhpunitHelpers\Traits\ProcessTrait;
use AlexSkrypnyk\PhpunitHelpers\Traits\ReflectionTrait;
use AlexSkrypnyk\PhpunitHelpers\Traits\TuiTrait;
use PHPUnit\Framework\TestCase;
class MyCombinedTest extends TestCase {
use ApplicationTrait;
use AssertArrayTrait;
use EnvTrait;
use LoggerTrait;
// ApplicationTrait and ProcessTrait both
use AlexSkrypnyk\PhpunitHelpers\Traits\EnvTrait;
use AlexSkrypnyk\PhpunitHelpers\UnitTestCase;
class MyTest extends UnitTestCase {
// Add further traits as needed.
use EnvTrait;
// Your test methods.
}
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.