Monday, 20 November 2017

Automated Testing packages in laravel5

1. Laravel.io portal

Recently re-launched Laravel.io has its source published on Github. And Dries Vints has done quite a good job on writing tests there.
Laravel.io is using both Feature testing and Component (more like Unit) testing. What’s interesting is that the same or similar behavior is tested in both cases.
Example 1 – tests/Feature/ReplyTest.php
 public function users_can_add_a_reply_to_a_thread()
    {
        factory(Thread::class)->create(['subject' => 'The first thread', 'slug' => 'the-first-thread']);
        $this->login();
        $this->visit('/forum/the-first-thread')
            ->type('The first reply', 'body')
            ->press('Reply')
            ->see('The first thread')
            ->see('The first reply')

            ->see('Reply successfully added!');
Example 2 – tests/Components/Jobs/CreateReplyTest.php

 public function we_can_create_a_reply()
    {
        $job = new CreateReply('Foo', '', $this->createUser(), factory(Thread::class)->create());
        $this->assertInstanceOf(Reply::class, $job->handle());

    }
This is actually quite a good thing: it tests both Jobs layer and actually clicking things and using it in the browser.
Also what I’ve noticed is that main Laravel.io has been upgraded to Laravel 5.4, but test suite remained in 5.3-style, with BrowserKitTestCase implementation. Nothing wrong with that, just a notice.
Finally, this project also uses continuous integration with Travis, and later I’ve noticed that most projects use it too.
Have you tried our tool to generate Laravel adminpanel without a line of code?
Go to QuickAdminPanel.com

2. Cachet – an open source status page system

Led by James Brooks and Graham Campbell, this project has a massive test suite. It’s even hard to understand by looking at the surface.
So, where do I start here… Actually, I won’t even dig deeper into the testing logic of this project, cause it is really deep. Here’s an example – tests/Models/ComponentTest.php:
use AltThree\TestBench\ValidationTrait;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Tests\Cachet\AbstractTestCase;
class ComponentTest extends AbstractTestCase
{
    use ValidationTrait;
    public function testValidation()
    {
        $this->checkRules(new Component());
    }
}
Ok, so there’s ValidationTrait being used, then some AbstractTestCase. And this logic is all over tests – some abstracted “magic” which is doing all the work.
And I’m not saying it is a bad thing – pretty sure it works damn well under the hood. It’s just not easy to learn and follow from this test suite. But if someone wants to dig deeper – good luck!

3. October CMS

No.1 Laravel-based CMS on the market, and it has pretty good testing suite.
First thing – tests folder has a really informative readme.md file, specifically for testing process.
All testing in October CMS consists of:
  • Unit testing
  • Functional testing
  • Plugin testing
And each of these “zones” has its own base class to extend – there’s TestCaseUiTestCaseand PluginTestCase.
The logic is also quite complicated and abstracted – here’s an example tests/unit/backend/models/ExportModelTest.php:
class ExportModelTest extends TestCase
{
    //
    // Helpers
    //
    protected static function callProtectedMethod($object, $name, $params = [])
    {
        $className = get_class($object);
        $class = new ReflectionClass($className);
        $method = $class->getMethod($name);
        $method->setAccessible(true);
        return $method->invokeArgs($object, $params);
    }
    //
    // Tests
    //
    public function testEncodeArrayValue()
    {
        $model = new ExampleExportModel;
        $data = ['foo', 'bar'];
        $result = self::callProtectedMethod($model, 'encodeArrayValue', [$data]);
        $this->assertEquals('foo|bar', $result);
        $data = ['dps | heals | tank', 'paladin', 'berserker', 'gunner'];
        $result = self::callProtectedMethod($model, 'encodeArrayValue', [$data]);
        $this->assertEquals('dps \| heals \| tank|paladin|berserker|gunner', $result);
        $data = ['art direction', 'roman empire', 'sci-fi'];
        $result = self::callProtectedMethod($model, 'encodeArrayValue', [$data, '-']);
        $this->assertEquals('art direction-roman empire-sci\-fi', $result);
    }
}
As you can see, there’s a static helper method (which is, by the way, repeating in other classes, too), then getting class/method and calling it. I’m sure that the creators understand this logic immediately, but it’s hard for outsiders.
What’s also interesting, OctoberCMS uses Selenium for some features: setup documentation is mentioned in tests/readme.md file.

4. Orgmanager – Invite System for GitHub Organizations

This is quite a simple project by Miguel Piedrafita, Orgmanager’s tests are also pretty simple and understandable. Also divided into Unit, Feature and API tests.
What I’ve seen here is an interesting case – calling Artisan commands from tests, like unit/JoinTest.php:
public function testJoinCommand()
    {
        $user = factory(User::class)->create();
        $org = factory(Org::class)->create([
          'userid' => $user->id,
        ]);
        Github::shouldReceive('authenticate')
                  ->once()
                  ->with($org->user->token, null, 'http_token')
                  ->andReturn();
        Artisan::call('orgmanager:joinorg', [
          'org'      => $org->id,
          'username' => $user->github_username,
        ]);
        $this->assertEquals($user->github_username.' was invited to '.$org->name."\n", Artisan::output());
    }
Calling artisan command and asserting its output – pretty interesting. I’m sure it works, but really non-standard way.

5. PHPMap

Created and maintained by Florian Wartner.
PHPMap has a tests suite which reminds of the standards shown by Laracasts or Test-Driven Laravel course. Here’s an example of Feature/FavoritesTest.php:

public function guests_can_not_favorite_anything()
    {
        $this->withExceptionHandling()
            ->post('forum/replies/1/favorites')
            ->assertRedirect('/login');
    }
    public function an_authenticated_user_can_favorite_any_reply()
    {
        $this->signIn();
        $reply = create('App\Models\Forum\Reply');
        $this->post('forum/replies/'.$reply->id.'/forum/favorites');
        $this->assertCount(1, $reply->favorites);
    }

PHPMap’s tests are divided into Unit, Feature and… wait for it… Laravel Dusk! Finally I’ve found the project which actually uses Dusk in production. Here’s how it looks – tests/Browser/MapTest.php:

public function testMap()
    {
        $this->browse(function ($browser) {
            $browser->visit('/map')
                    ->assertSee('PHPMap');
        });
    }
6. Timegrid – Free, open-source, online appointments platform
The biggest contributor to Timegrid is Ariel Vallese, and he’s done the pretty awesome job with tests here.
There are just a lot of tests here: Unit, Acceptance and Integration, and every folder have a few sub-folders deeper. Here’s an example – acceptance/scenarios/consulting/ConsultingScenarioTest.php:

public function it_fits_for_consulting_scenario()
    {
        $this->arrangeScenario();
        $this->the_business_publishes_a_consulting_service();
        $this->the_business_publishes_vacancies();
        $this->a_user_subscribes_to_business();
        $this->the_user_queries_vacancies();
        $this->it_provides_available_times_for_requested_service_date();
        $this->the_user_takes_a_reservation();
        $this->the_user_sees_the_reservation_ticket();
    }
    public function the_business_publishes_a_consulting_service()
    {
        $this->service = $this->makeService([
            'name'     => 'OnSite 4hs Support',
            'duration' => 60 * 4,
            ]);
        $this->actingAs($this->owner);
        $this->call('POST', route('manager.business.service.store', $this->business), $this->service->toArray());
        $this->assertCount(1, $this->business->fresh()->services);
    }

One all-in-one method and then some more test cases one by one.
The official stats in the repository look pretty good: 89% Tests Coverage.
Finally, what is interesting, an author is also testing migrations, here’s tests/unit/migration/MigrationTest.php:

 public function it_refreshes_rollbacks_and_seeds_the_database()
    {
        $database = env('DB_CONNECTION');
        $this->assertNotNull($database);
        $exitCode = Artisan::call('migrate:refresh', ['--database' => $database]);
        $this->assertEquals(0, $exitCode);
        $exitCode = Artisan::call('migrate:rollback', ['--database' => $database]);
        $this->assertEquals(0, $exitCode);
        $exitCode = Artisan::call('migrate', ['--database' => $database]);
        $this->assertEquals(0, $exitCode);
        $exitCode = Artisan::call('db:seed', ['--database' => $database]);
        $this->assertEquals(0, $exitCode);
    }
Using Artisan commands in tests might not be the greatest design pattern, but it simply tests one of the most important functions of any web app.

1 comment:

  1. vladislav kocomedy vladislav kocomedy vladislav kocomedy vladislav
    vladislav kocomedy vladislav kocomedy vladislav kocomedy vladislav kocomedy vladislav mp3 juice kocomedy vladislav kocomedy vladislav

    ReplyDelete

cURL error 60: SSL certificate problem: unable to get local issuer certificate (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) in Laravel

  WampServer: Download this file:  http://curl.haxx.se/ca/cacert.pem Place this file in the  C:\wamp64\bin\php\php7.1.9  folder Open  php.in...

Popular Articles