PHP Test Generator - A CLI tool which generates unit tests

Overview

PHP Test Generator

This project make usages of PHPStan and PHPParser to generate test cases for a given PHP File.

Why?

With static code analyzer it is possible to generate tests which where mostly forgotten. The target of the project is not to generate a whole test cases instead it should generate the most boilerplate code of the test case and tell which method for the class methods should be implemented.

So example if we have a method like the following:

public function setTitle(?string $title): void
{
    $this->title = $title;
}

public function getTitle(): void
{
    $this->title = $title;
}

If you are using code coverage you will get 100% when you are testing:

public function testSetTitle(): void
{
    $model = $this->createInstance();
    $model->setTitle('Test');
    $this->assertSame('Test', $model->getTitle());
}

But as ?string can be seen as an union type of string|null the testcase for null type is missing:

public function testSetTitleNull(): void
{
    $model = $this->createInstance();
    $model->setTitle(null);
    $this->assertNull($model->getTitle());
}

The project target is to already generate also the boilerplate for that test case.

Installation

composer require --dev schranz/test-generator

Config

Create a new tests/generator-config.php file:



use Schranz\TestGenerator\Domain\Model\Config;

$config = new Config();
// add following hooks if you want to use `rector` or `php-cs-fixer` directly on the created test files
// $config->hooks[] = 'vendor/bin/rector process %s';
// $config->hooks[] = 'vendor/bin/php-cs-fixer fix %s';

return $config;

See Config.php for all options.

Usage

vendor/bin/test-generator src/YourNameSpace/YourFile.php
Comments
  • Fix default namespace replace with for Application

    Fix default namespace replace with for Application

    Currently all App appearenace was replaced with App\Tests\Unit which did end in a strange namespace like: App\Context\Application -> App\Tests\Unit\Context\App\Tests\Unitlication. This is now fixed via checking for \\ or direct match of the namespace.

    bug 
    opened by alexander-schranz 0
  • Add basic getter test implementation

    Add basic getter test implementation

    This adds implementation for basic getter tests. Getter tests are test without a setter and need inject the parameter over constructor or manual adoption is required to set the value e.g.: using reflection. Currently the library will not provide a PrivatePropertyTrait to set getter value.

    opened by alexander-schranz 0
  • Add setter getter support for objects

    Add setter getter support for objects

    This will create a variable for setter getter tests when an object is used e.g.:

            $birthday = new DateTimeImmutable('2022-01-01');
            $model->setBirthday($birthday);
            $this->assertSame($birthday, $model->getBirthday());
    
    enhancement 
    opened by alexander-schranz 0
  • Add test for int and float arguments

    Add test for int and float arguments

    Add test cases for argument resolver creating also int and float types. Also make the test runs more user friendly by output the file path of the tested file.

    opened by alexander-schranz 0
  • Rewrite the workflow of parsing

    Rewrite the workflow of parsing

    The current implementation is just a prototype and is usable for basic model classes using common keywords like set, get, change and so on.

    https://github.com/alexander-schranz/test-generator/blob/615a74c58c06d0906f4e400bc53b845a4238db10/src/Application/Grouper/MethodGrouper.php#L45-L124

    This was used just as quick prototype to develop the generation. In future the parsing of the ast should return a object like the following for every method e.g.:

    class TestMethod {
        /** @var Property[] */
        public string $returnedProperties = [];
    
        /** @var Property[] */
        public string $modifiedProperties = [];
    
        /** @var TestMethod[] */
        public iterable $calledMethods = [];
    }
    

    Step 1: Matching modifiedProperties to returnedProperties

    This way it should be possible that something like:

    public function changeFullname(string $firstname, string $lastName): void
    {
        $this->firstname = $firstName;
        $this->lastName = $lastName;
    }
    
    public function getFullname(): string
    {
        return $this->firstname . ' ' . $this->lastName;
    }
    

    we know that changeFullname will manipulate firstName and lastName and getFullname will return firstName and lastName are generated into following test case:

    public function testChangeFullname(): void
    {
        $contact = $this->createInstance();
        $contact->changeFullname('FirstName', 'LastName');
        
        $this->assertSame('Firstname Lastname', $contact->getFullname());
    }
    

    Step 2: Matching external modified calls and external return values

    The ideal case would also be that it also analyse when required the external calls if there are no internal matching possible so example test case would be that following is generating same test case as above:

    public function changeFullname(string $firstname, string $lastName): void
    {
        $this->inner->changeFullname($firstName, $lastName);
    }
    
    public function getFullname(): string
    {
        return $this->inner->getFullname();
    }
    

    Step 3: Find expected changes also from multple public methods

    To the above example is there is no return value for both firstName and lastName possible it should search for methods which return both so the test case for a class with:

    public function changeFullname(string $firstname, string $lastName): void
    {
        $this->firstname = $firstName;
        $this->lastName = $lastName;
    }
    
    public function getFirstname(): string
    {
        return $this->firstname;
    }
    
    public function getLastname(): string
    {
        return $this->lastname;
    }
    

    Should be:

    public function testChangeFullname(): void
    {
        $contact = $this->createInstance();
        $contact->changeFullname('FirstName', 'LastName');
        
        $this->assertSame('Firstname', $contact->getFirstname());
        $this->assertSame('Lastname', $contact->getLastname());
    }
    

    Step 4: Create condition tree and so multiple possibilities

    If there are condition in it e.g.:

    public function changeSomething($name, $bool = true): void
    {
        if ($bool) {
            $this->firstName = $name;
    
            return;
        }
    
        $this->lastName = $name;
    }
    

    There should be a test case generated for every condition and we should parse it correctly so we know depending on bool firstname is changed or lastname is changed.

    opened by alexander-schranz 0
Releases(0.4.4)
Owner
Alexander Schranz
Core Developer @sulu likes @php, @symfony, @elasticsearch, @redis, react js
Alexander Schranz
Mock HTTP requests on the server side in your PHP unit tests

HTTP Mock for PHP Mock HTTP requests on the server side in your PHP unit tests. HTTP Mock for PHP mocks the server side of an HTTP request to allow in

InterNations GmbH 386 Dec 27, 2022
To run time/IO related unit tests (e.g., sleep function calls, database queries, API calls, etc) faster using Swoole.

To run time/IO related unit tests (e.g., sleep function calls, database queries, API calls, etc) faster using Swoole.

Demin Yin 11 Sep 9, 2022
Magic Test allows you to write browser tests by simply clicking around on the application being tested, all without the slowness of constantly restarting the testing environment.

Magic Test for Laravel Magic Test allows you to write browser tests by simply clicking around on the application being tested, all without the slownes

null 400 Jan 5, 2023
Prevent none-test output in your Pest tests.

Pest Plugin Silence Often, when writing tests, we echo and dump test code to debug and check everything is working correctly. It can be easy to forget

Worksome 5 Feb 23, 2022
A tool to run migrations prior to running tests

cakephp-test-migrator A tool to run migrations prior to running tests The Migrator For CakePHP 3.x composer require --dev vierge-noire/cakephp-test-mi

Vierge Noire 11 Apr 29, 2022
The modern, simple and intuitive PHP unit testing framework.

atoum PHP version atoum version 5.3 -> 5.6 1.x -> 3.x 7.2 -> 8.x 4.x (current) A simple, modern and intuitive unit testing framework for PHP! Just lik

atoum 1.4k Nov 29, 2022
The PHP Unit Testing framework.

PHPUnit PHPUnit is a programmer-oriented testing framework for PHP. It is an instance of the xUnit architecture for unit testing frameworks. Installat

Sebastian Bergmann 18.8k Jan 4, 2023
PHP unit testing framework with built in mocks and stubs. Runs in the browser, or via the command line.

Enhance PHP A unit testing framework with mocks and stubs. Built for PHP, in PHP! Quick Start: Just add EnhanceTestFramework.php and you are ready to

Enhance PHP 67 Sep 12, 2022
Unit testing tips by examples in PHP

Unit testing tips by examples in PHP Introduction In these times, the benefits of writing unit tests are huge. I think that most of the recently start

Kamil RuczyƄski 894 Jan 4, 2023
SimpleTest is a framework for unit testing, web site testing and mock objects for PHP

SimpleTest SimpleTest is a framework for unit testing, web site testing and mock objects for PHP. Installation Downloads All downloads are stored on G

SimpleTest 147 Jun 20, 2022
Real-world Project to learning about Unit Testing/TDD with Laravel for everybody

KivaNote - a Laravel TDD Sample Project Let me introduce you to KivaNote, a simple real-world application using Laravel to show you how the TDD & Unit

(Seth) Phat Tran 10 Dec 31, 2022
Package for unit testing Laravel form request classes

Package for unit testing Laravel form request classes. Why Colin DeCarlo gave a talk on Laracon online 21 about unit testing Laravel form requests cla

null 18 Dec 11, 2022
Learn unit testing with PHPUnit.

PHPUnit Exercise Running PHPUnit ./vendor/bin/phpunit # with filter which tests to run ./vendor/bin/phpunit --filter <pattern> Running Pint ./vendor/

Nopal 2 Aug 23, 2022
Faker is a PHP library that generates fake data for you

Faker Faker is a PHP library that generates fake data for you. Whether you need to bootstrap your database, create good-looking XML documents, fill-in

FakerPHP 2.7k Dec 27, 2022
Faker is a PHP library that generates fake data for you

Faker is a PHP library that generates fake data for you. Whether you need to bootstrap your database, create good-looking XML documents, fill-in your persistence to stress test it, or anonymize data taken from a production service, Faker is for you.

FakerPHP 1.7k Aug 23, 2021
A PHP library for mocking date and time in tests

ClockMock Slope s.r.l. ClockMock provides a way for mocking the current timestamp used by PHP for \DateTime(Immutable) objects and date/time related f

Slope 44 Dec 7, 2022
Extension to use built-in PHP server on Behat tests

Extension to use built-in PHP server on Behat tests Instalation composer require libresign/behat-builtin-extension Configuration Add the extension to

LibreSign 2 Feb 21, 2022
Enforce consistent styling for your Pest PHP tests

A set of PHP CS rules for formatting Pest PHP tests.

Worksome 2 Mar 15, 2022