Introduction

For our basic usage introduction, we will be testing httpbin.org interface. If you have not yet installed Athena, refer to Athena project page.

Project Setup

To start using Athena, we'll need to setup a directory, where we will save our tests into.

myteam-tests/
├── HttpBinTest.php
├── Report
├── phpunit.xml
└── athena.json

athena.json is where Athena reads the configuration from. In this case we will contain only the necessary information for a simple API test run.

Report/ directory is where the HTML report, generated by Athena, will be output.

The report

One of our goals is to debug what actions were performed by the HTTP Client. We don't need too much detail, but enough to understand what happened, specially in case something goes wrong.

{
   "report" : {
      "format" : "html",
      "outputDirectory" : "./Report"
   }
}

Setting up a report is fairly easy, you just have to define the report.format, and report.outputDirectory. We will make use of our ./Report directory to keep things nice and tidy.

The Listeners

In order to have the Report working, we need to register Athena listeners, this can be done through phpunit.xml.

<?xml version="1.0" encoding="UTF-8"?>
<phpunit>
    <listeners>
        <listener class="\Athena\Event\Adapter\PhpUnitAdapter">
            <arguments>
                <object class="\Athena\Event\Dispatcher\DispatcherLocator"/>
            </arguments>
        </listener>
    </listeners>

    <testsuites>
        <testsuite name="api">
            <directory>./</directory>
        </testsuite>
    </testsuites>
</phpunit>

Writing a Test

namespace Tests;

use Athena\Test\AthenaAPITestCase;

class HttpBinTest extends AthenaAPITestCase
{
    public function testIpEndpoint_PerformGetRequest_ShouldContainOrigin()
    {

    }
}

At the first glance, it looks fairly standard: A namespace, a parent class and a big self-explanatory method name.

The Namespace

One of the caveats of writing a test in Athena, is the namespace. It should—always—start with—Tests\. Internally Athena will map Tests\ to your testing directory.

This behaviour gives you freedom to choose how you organise the directory, where you store your tests.

The Parent Class

Another close look to the code will make our parent class, AthenaAPITestCase stand-out, and you'll ask yourself what it does, if you didn't, you have now. When building our tests we should—always—include Athena's test cases.

Each type of test is wrapped with a Athena class of it's own, as you can imagine, this introduces custom behaviour when needed. I won't cover here all the types, as the focus is our Browser test case. After completing the guide, I recommend you giving them a—quick—look.

The Method Name Convention

Adopting conventions, in most situations, is a good idea. This keeps things consistent, making it easier to read.

We follow the MethodName_StateUnderTest_ExpectedBehavior convention. If you are interested in knowing more about it, refer to the Coding Standards page.

Food for though: If you have however spent a lifetime using a different convention, you can always use your own. At the end of the day, it doesn't matter, consistency for the reader is the key. Is what we strive for. Easy and understandable tests.

Performing HTTP Calls

Athena brings a client for HTTP calls, which can be accessed through Athena::api(). This client provides a fluent interface for not only performing these calls, but also to perform assertions on the response given by the server.

namespace Tests;

use Athena\Athena;
use Athena\Test\AthenaAPITestCase;

class HttpBinTest extends AthenaAPITestCase
{
    public function testIpEndpoint_PerformGetRequest_ShouldContainOrigin()
    {
        $result = Athena::api()
                            ->get('http://httpbin.org/ip')
                            ->then()
                            ->assertThat()
                            ->responseIsJson()
                            ->statusCodeIs(200)
                            ->retrieve()
                            ->fromJson();

        $this->assertArrayHasKey('origin', $result);
    }
}

The good thing about this fluent interface, is that it's self-explanatory what we want to retrieve and what assertions we are performing.

Execute The Test

Athena runs it's tests through the command line interface, so we'll need to navigate inside Athena's project directory, to access it's executable.

$ athena php api
...

usage: athena php api <tests-directory> <config-file> [<options>...] [(<phpunit-options>|<paratest-options>)...]

    <tests-directory>                 This directory will be mounted inside the docker container. PHPUnit will be executed inside this directory
    <config-file>                     Athena config file, with proxy configurations, grid options, etc
    --parallel=<number>               Specify the number of jobs to be ran in parallel. In case this options is specified, Paratest will be ran, instead of PHPUnit
    --php-version=<version>           Switch between available PHP versions. E.g. --php-version=7.0
    --override-athena-dependencies    Override PHP plugin dependencies with the ones found inside the tests directory
    --restore-athena-dependencies     Restore PHP plugin original dependencies

Writing athena php api and hitting enter, will show you the basic usage, on the requirements to run a browser test case. Most likely by now you already know the next steps.

$ athena php api ../myteam-tests ../myteam-tests/athena.json

Once you run that command, if it is your first time running athena, you'll most likely see a lot of input. This is athena setting up it's docker images.

When it's all completed, or you are running the command a second time, after having everything installed, you should see the following:

...

PHPUnit 5.1.7 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 753 ms, Memory: 3.75Mb

OK (1 test, 1 assertion)

Reading The Report

In our configuration file, we've specified Report/ as our output directory for the report file, so that where we will be looking for it.

Open report.html in your browser, and you should see nice HTML report containing all the steps we took, together with HTTP conversation for each one.

Configure a Proxy

When athena php api is run, it will try to automatically link with a running Proxy Server (athena proxy start).

In case --skip-proxy exists, the link will not be performed.

For performing a link with another running container, you can optionally specify --link-proxy=<container_name>.

Parallel Tests

$ athena php api my-tests/ my-tests/athena.json --parallel=<number> [<paratest-options>...]
$ athena php api my-tests/ my-tests/athena.json --parallel=2

All Available Options

$ athena php api my-tests/ my-tests/athena.json --parallel --help
...

Usage:
  paratest [options] [--] [<path>]

Arguments:
  path                                   The path to a directory or file containing tests. (default: current directory)

Options:
  -p, --processes=PROCESSES              The number of test processes to run. [default: 5]
  -f, --functional                       Run methods instead of suites in separate processes.
      --no-test-tokens                   Disable TEST_TOKEN environment variables. (default: variable is set)
  -h, --help                             Display this help message.
      --coverage-clover=COVERAGE-CLOVER  Generate code coverage report in Clover XML format.
      --coverage-html=COVERAGE-HTML      Generate code coverage report in HTML format.
      --coverage-php=COVERAGE-PHP        Serialize PHP_CodeCoverage object to file.
  -m, --max-batch-size=MAX-BATCH-SIZE    Max batch size (only for functional mode). [default: 0]
      --filter=FILTER                    Filter (only for functional mode).
      --whitelist=WHITELIST              Directory to add to the coverage whitelist.
      --phpunit=PHPUNIT                  The PHPUnit binary to execute. (default: vendor/bin/phpunit)
      --runner=RUNNER                    Runner or WrapperRunner. (default: Runner)
      --bootstrap=BOOTSTRAP              The bootstrap file to be used by PHPUnit.
  -c, --configuration=CONFIGURATION      The PHPUnit configuration file to use.
  -g, --group=GROUP                      Only runs tests from the specified group(s).
      --exclude-group=EXCLUDE-GROUP      Don't run tests from the specified group(s).
      --stop-on-failure                  Don't start any more processes after a failure.
      --log-junit=LOG-JUNIT              Log test execution in JUnit XML format to file.
      --colors                           Displays a colored bar as a test result.
      --testsuite[=TESTSUITE]            Filter which testsuite to run
      --path=PATH                        An alias for the path argument.

Once the option --parallel is set, under hood paratest will replace phpunit.

Final Thoughts

If you are reading this tutorial is either because you want to use it or you are curious about it. Let—that—guide you into our community, make this project grow, make it better, iterate over it several times and share your ideas and your knowledge, so that you, us, who use this project benefit from it.

results matching ""

    No results matching ""