Test time in php

How to «Mock» Time in PHPunit

I recently came up with another solution that is great if you are using PHP 5.3 namespaces. You can implement a new time() function inside your current namespace and create a shared resource where you set the return value in your tests. Then any unqualified call to time() will use your new function.

For further reading I described it in detail in my blog

How to mock date in php unit test?

Unit testing works best by avoiding side effects. Both date and strtotime are depending on an external state defined on your host system, namely the current time.

One way to deal with that is to make current time an injectable property allowing you to «freeze» it or to set it to a specific value.

If you look at at the definition to strtotime it allows setting current time:

strtotime ( string $time [, int $now = time() ] ) : int
date ( string $format [, int $timestamp = time() ] ) : string

So always inject that value from your function to decouple the results of your code from your host’s state.

function changeStartEndDate($now)  
if (date('j', strtotime("now", $now), $now) === '1') .
$this->startDate = date("Y-n-j", strtotime(date("Y-m-01", $now), $now));
$this->endDate = date("Y-n-j", strtotime("yesterday", $now), $now);
>

Is your function part of a class? I would then make the $now part of the constructor, and have it default to time() . In your test cases, you can always inject a fixed number, and it will always return the same output.

class MyClassDealingWithTime private $now;

public function __construct($now = time()) $this->now = $now;
>

private customDate($format) return date($format, $this->now);
>

private customStringToTime($timeSring) return strtotime($timeStrimg, $this->now);
>
>

In your test cases you then set $now to the value you need, e.g. via

$firstDayOfAMonth = (new DateTime('2017-06-01'))->getTimestamp();
$testInstance = new MyClassDealingWithTime(firstDayOfAMonth);

$actual = $testInstance->publicMethodYouWantTotest();

.

How to fake DateTime in a phpunit test?

Following the link you included in your post, the first paragraph says:

The ClockMock class provided by this bridge allows you to mock the
PHP’s built-in time functions time(), microtime(), sleep() and
usleep(). Additionally the function date() is mocked so it uses the
mocked time if no timestamp is specified. Other functions with an
optional timestamp parameter that defaults to time() will still use
the system time instead of the mocked time
.
(Emphasis added.)

This means that your call of

echo (new DateTime())->format('Y-m-d H:m:s');

is expected to give the system time, not the mocked time.

in order to match the requirements of ClockMock and get the mocked time.

Note: I’ve never used ClockMock myself, but just looking at the documentation this should be a first step to see if this resolves your problem.

How to mock time() function while testing in Laravel?

I think Carbon should be used instead of time() :

Carbon::now()->timestamp // Or just now()->timestamp in 5.5+

You can easily mock Carbon instances.

If you don’t use time() a lot, you could also create your own helper:

function timestamp()
if (app()->runningUnitTests()) return .
> else return time();
>
>

And use it instead of time() :

Mocking The Time used by all instances of DateTime for testing purposes

You should stub the DateTime methods you need in your tests to return expected values.

$stub = $this->getMock('DateTime');
$stub->expects($this->any())
->method('theMethodYouNeedToReturnACertainValue')
->will($this->returnValue('your certain value'));

If you cannot stub the methods because they are hardcoded into your code, have a look at

which explains how to invoke a callback whenever new is invoked. You could then replace the DateTime class with a custom DateTime class that has a fixed time. Another option would be to use http://antecedent.github.io/patchwork

PHPUnit mock return value and number of times called with specific argument for different methods same class

Here’s an example of a test that covers ToTest :


use PHPUnit\Framework\TestCase;

class ToTestTest extends TestCase
/**
* @dataProvider providerTimeBetween0And100
*
* @param int $time
*/
public function testFeedMeWhenTimeIsBetween0And100($time)
$toMock = $this->createMock(ToMock::class);

$toMock
->expects($this->exactly(2))
->method('iReturn')
->willReturn($time);

$toMock
->expects($this->never())
->method('callMe1');

$toMock
->expects($this->once())
->method('callMe2')
->with(
$this->identicalTo(15),
$this->identicalTo(20)
);

$toTest = new ToTest();

$toTest->feedMe($toMock);
>

public function providerTimeBetween0And100()
return $this->providerTimeBetween(0, 100);
>

/**
* @dataProvider providerTimeBetween101And199
*
* @param int $time
*/
public function testFeedMeWhenTimeIsBetween101And199($time)
$toMock = $this->createMock(ToMock::class);

$toMock
->expects($this->exactly(2))
->method('iReturn')
->willReturn($time);

$toMock
->expects($this->once())
->method('callMe1')
->with(
$this->identicalTo(5),
$this->identicalTo(10)
);

$toMock
->expects($this->once())
->method('callMe2')
->with(
$this->identicalTo(15),
$this->identicalTo(20)
);

$toTest = new ToTest();

$toTest->feedMe($toMock);
>

public function providerTimeBetween101And199()
return $this->providerTimeBetween(101, 199);
>
/**
* @dataProvider providerTimeGreaterThan199
*
* @param int $time
*/
public function testFeedMeWhenTimeIsGreaterThan199($time)
$toMock = $this->createMock(ToMock::class);

$toMock
->expects($this->exactly(2))
->method('iReturn')
->willReturn($time);

$toMock
->expects($this->once())
->method('callMe1')
->with(
$this->identicalTo(5),
$this->identicalTo(10)
);

$toMock
->expects($this->never())
->method('callMe2');

$toTest = new ToTest();

$toTest->feedMe($toMock);
>

public function providerTimeGreaterThan199()
return $this->providerTimeBetween(200, 300);
>

private function providerTimeBetween($min, $max)
for ($time = $min; $time < $max; ++$time) yield [
$time
];
>
>
>

Note how multiple expectations are set up using expects() and further constraints. All of these can be easily combined.

  • https://phpunit.de/manual/current/en/test-doubles.html#test-doubles.mock-objects
  • https://phpunit.de/manual/current/en/test-doubles.html#test-doubles.mock-objects.tables.matchers

Mocking a wrapper time function

You can create a Partial mock object of your tested class in order to modify the behaviour only of the selected method (the currentTime method). For this purpose you can use the setMethods of the Mock Builder API:

setMethods(array $methods) can be called on the Mock Builder object to
specify the methods that are to be replaced with a configurable test
double. The behavior of the other methods is not changed. If you call
setMethods(NULL), then no methods will be replaced.

So try this code (suppose the myFunction return the result of the isPending method):

class MyClassTest extends \PHPUnit_Framework_TestCase
/**
* @test
*/
public function itShouldReturnTrueIfPendingState()
$currentTime = (new \DateTime('now -1 year'))->getTimestamp();

/** @var MyClass|\PHPUnit_Framework_MockObject_MockObject $myClass */
$myClass = $this->getMockBuilder(MyClass::class)
->disableOriginalConstructor()
->setMethods(['currentTime'])
->getMock();

$myClass
->method('currentTime')
->willReturn($currentTime);

$this->assertTrue($myClass->myFunction(time()));
>

/**
* @test
*/
public function itShouldReturnFalseIfNotState()
$currentTime = (new \DateTime('now +1 year'))->getTimestamp();

/** @var MyClass|\PHPUnit_Framework_MockObject_MockObject $myClass */
$myClass = $this->getMockBuilder(MyClass::class)
->disableOriginalConstructor()
->setMethods(['currentTime'])
->getMock();

$myClass
->method('currentTime')
->willReturn($currentTime);

$this->assertFalse($myClass->myFunction(time()));
>

PHPUnit mocking — fail immediately when method called x times

I managed to find a solution in the end. I used a comination of $this->returnCallback() and passing the PHPUnit matcher to keep track of the invocation count. You can then throw a PHPUnit exception so that you get nice output too:

$matcher = $this->any();
$mock
->expects($matcher)
->method('execute')
->will($this->returnCallback(function() use($matcher) switch ($matcher->getInvocationCount())
case 0: return 'foo';
case 1: return 'bar';
case 2: return 'baz';
>

throw new PHPUnit_Framework_ExpectationFailedException('Called too many times.');
>))
;

Unit testing a function containing DateTime(now)

You could instead pass in the $date_start variable to the function, and when you call it in your test it would be the same every time ie

function testMymethod() $date_start = new DateTime('2011-01-01'); 
$class->getSomeInfo($id, $date_start);
//assertions
>

And your method signiture would change to:

 class myclass public function getSomeInfo($id, $date_start = new DateTime()) 
>

Источник

This website needs your consent to use cookies in order to customize ads and content.

If you give us your consent, data may be shared with Google.

Track Execution Time in PHP

Performing benchmark testing in PHP by tracking the execution time of pieces of code.

d

Track execution time, PHP

To track the execution time of a PHP script—or just a part of some PHP code—we should make a timestamp right before executing the relevant code, and then again right after the code finishes.

This is quite useful for performing simple benchmark testing of code. Often we will find that there is multiple ways to do the same thing when programming, and this is also true when we are coding in PHP. Some PHP functions are simply faster than others.

For the most part, the speed difference is not going to matter unless you are handling several thousands—or even millions—of requests. But, if we know something is faster, then why not use the most efficient method from the beginning? Very often, it is actually obvious what will be the fastest way.

A simple speed test can be performed like this:

$start_time = microtime(true); // Your code here $time_spent = microtime(true)-$start_time; echo $time_spent; 

When the parameter of microtime is set to true, the result will be returned in seconds. If you leave out the parameter, a string will be returned instead of a float, which can not be used easily in calculations; hence why microtime(true) is used instead of clean microtime().

Determining which is faster

In many cases, a single run is not to be enough for us to tell which piece of code is the fastest, since the difference is minuscule.

So, in order to notice a difference, we should combine this with a while or for loop, and then run the test at least a million times:

$start_time = microtime(true); for ($i = 0; $x  1000000; $i++)  // Your code here > $time_spent = microtime(true)-$start_time; echo $time_spent; 

Using the time command in Linux

There is also a command called time available on Linux systems that can be used to exemine the execution time of programs and scripts run from a terminal; to use the command you simply place it in front of whatever command and arguments that you wish to run:

time php name_of_script.php 

This should output the total time elapsed while executing a given program:

real 0m0.418s user 0m0.104s sys 0m0.314s

The real value represents the total execution time.

Источник

How to Measure Script Execution Time in PHP

The time that is required for executing a PHP script, is known as script execution time.

It is recommended to use a clock for calculating it. If you know the time before the script execution and after it, you will manage to get the execution time easily.

Let’s take a look at a script sample:

 for ($i = 1; $i 1000; $i++) < echo "Hello W3docs!"; > ?>

Getting the Clock Time with microtime()

The microtime() function is used for getting the clock time. First, it should be used before the script starts, then, at the end of it. Afterwards, the formula (End_time – Start_time) should be used.

With the help of the microtime() function, time is returned in seconds. The execution time is not fixed, it is decided by the processor.

To be more precise, let’s see an example:

 // Starting clock time in seconds $start_time = microtime(true); $a = 1; // Start loop for ($i = 1; $i 10000000; $i++) < $a++; > // End clock time in seconds $end_time = microtime(true); // Calculating the script execution time $execution_time = $end_time - $start_time; echo " Execution time of script = " . $execution_time . " sec"; ?>
Execution time of script = 1.4305651187897 sec

Describing the microtime() Function

The microtime() function of PHP is used for returning the current Unix timestamp. It returns a string in microseconds.

Passing a boolean value as a parameter of this method will return the current time in seconds.

Источник

Читайте также:  Php creating directory file
Оцените статью