Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
February 24, 2022 09:41 pm GMT

TDD with PestPHP

Test Driven Development (TDD) is a software development practice.

The typical flow is:

  • writing the test cases starting from the requirements;
  • writing the code that solves the tests;
  • refactoring the code to pass all tests.

Writing tests before the code, allows the developer to:

  • focus on requirements;
  • see if some requirements are missing or not detailed;
  • focus about the edge cases (empty params, invalid params etc). This is very useful for thinking outside the "happy path".

This approach helps and supports the developer for creating a "better and more maintainable code" because "forcing" the developer making the code/functions testable from the beginning:

  • splitting code in smaller and easier "pieces";
  • favoring the single responsibility approach;
  • favoring the code isolation (or encapsulation).

But, yes, fewer words and more code.

For our example, we are going to create a class with a static function for calculating the mean (the average).

Create your project from scratch

Create a new directory and jump into the new directory:

mkdir tddcd tdd

Install PestPHP

Now you can install the testing framework PestPHP.
PestPHP is built on top of the mature PHPUnit, and it aims to provide a nice and smooth interface for the developer that want to write tests.

composer require pestphp/pest --dev --with-all-dependenciesmkdir tests./vendor/bin/pest --init

I'm going to skip the right configuration for PSR-4 autoloading, so I will create a file and include that in the test file via require

Create Stat class

Create your "stat.php" file with the class "Stat":

<?phpclass Stat{}

Yes, I know, the class is empty. Before to write the method and the implementation, you need to create the new test file.
Create "StatTest.php" file in the "tests" directory. The convention to write tests in "tests" directory and naming the file with "Test.php" suffix, allows PestPHP to automatically find the right tests.

Create the test file

File "tests/StatTest.php":

<?phprequire('./stat.php');test('test mean', function () {    expect(Stat::mean([1,2,3]))->toEqual(2);});

Before implementing the "mean()" method, we are expecting (expect()) that calling "Stat::mean()" with an array [1,2,3] as input parameter, it returns a value equal "2".

This is the happy path.

But I want also to think about "bad scenarios" for example if the user will call the method "Stat::mean()" with an empty array, I expect to retrieve a "null" value

test('test mean with empty data', function () {    expect(Stat::mean([]))->toBeNull();});

Calling "Stat::mean()" with a non array parameter (for example an integer) I expect to have an exception:

test('test mean with not array', function () {    expect(        fn () => Stat::mean(42)    )->toThrow(TypeError::class);});

If you run the tests:

./vendor/bin/pest

You will receive errors like "undefined method" because the class Stat is still empty, and it doesn't implement any methods.

Call to undefined method Stat::mean()

So now, jump into "stat.php" file and implement the method mean() that for now will always return the value 0.0.

<?phpclass Stat{    public static function mean(array $data): ?float    {        return 0.0;    }}

If you run the test now, you will still receive errors.

Image description

The first one is about the assertion that expect to receive 2 as value. The current implementation is returning 0.0:

   Tests\StatTest > test mean() with array parameter  Failed asserting that 0.0 matches expected 2.

The second one is about the assertion that expect to receive "null" if the input parameter is an empty array. The current implementation is returning 0.0:

   Tests\StatTest > test mean() with empty array parameter  Failed asserting that 0.0 is null.

The test are failing, so now you need to focus on your implementation, on your code and implement the logic and making the test "green".

In your "stat.php" file in the "mean()" method, try to implement the mean:

  • count the elements in the array;
  • calculate the sum of the elements of the array;
  • divide the sum with the count.
<?phpclass Stat{    public static function mean(array $data): ?float    {        $count = count($data);        $sum = array_sum($data);        return $sum / $count;    }}

If you execute the tests, the only one that fails is the test that calls "mean()" method with empty array and raises a "Division by zero exception".

Image description

"Division by zero" is raised because the count is equal to 0. So, you need to check the length of the array, and if it is 0, you need to return "null".

<?phpclass Stat{    public static function mean(array $data): ?float    {        $count = count($data);        if ( ! $count) {            return null;        }        $sum = array_sum($data);        return $sum / $count;    }}

If you execute the tests ...

Image description

All GREEN for us!

So, we:

  • Wrote the test focusing on happy path and "bad scenarios";
  • Wrote the code iteratively until all test passes.

And you, are you applying TDD practice in your development process?


Original Link: https://dev.to/robertobutti/tdd-with-pestphp-13c3

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To