0

I'm doing my firsts acceptance tests for a Laravel 5 application using Behat 3 and Mink.

The application runs under a Homestead VM.

The test is straightforward and is located in the features/example.feature file. This is the test:

Feature: Sample

    In order to learn Behat
    As a programmer
    I need a simple url testing

    Scenario: Registration
        Given I am not logged in
        When I go to the registration form
        Then I will be automatically logged in

The FeatureContext.php has this class:

<?php

use Behat\Behat\Tester\Exception\PendingException;
use Behat\Behat\Context\Context;
use Behat\Behat\Context\SnippetAcceptingContext;
use Behat\Gherkin\Node\PyStringNode;
use Behat\Gherkin\Node\TableNode;
use Behat\MinkExtension\Context\MinkContext;

/**
 * Defines application features from the specific context.
 */
class FeatureContext extends MinkContext implements Context, SnippetAcceptingContext
{
    /**
     * Initializes context.
     *
     * Every scenario gets its own context instance.
     * You can also pass arbitrary arguments to the
     * context constructor through behat.yml.
     */
    public function __construct()
    {
    }

    /**
     * @Given I am not logged in
     */
    public function iAmNotLoggedIn()
    {
        Auth::guest();
    }

    /**
     * @When I go to the registration form
     */
    public function iGoToTheRegistrationForm()
    {
       $this->visit(url('my/url'));
    }

    /**
     * @Then I will be automatically logged in
     */
    public function iWillBeAutomaticallyLoggedIn()
    {
        Auth::check();
    }
}

Then, when I run behat from the command line, I expect the test to fail because there is no my/url route (the routes.php file only has a route for /).

However, the test returns green, and this is what I see:

Feature: Sample

    In order to learn Behat
    As a programmer
    I need a simple url testing

  Scenario: Registration                   # features/example.feature:7
    Given I am not logged in               # FeatureContext::iAmNotLoggedIn()
    When I go to the registration form     # FeatureContext::iGoToTheRegistrationForm()
    Then I will be automatically logged in # FeatureContext::iWillBeAutomaticallyLoggedIn()

1 scenario (1 passed)
3 steps (3 passed)
0m0.45s (22.82Mb)

Of course, I'm using the laracasts/behat-laravel-extension package and this is the content of the beat.yml file:

default:
    extensions:
        Laracasts\Behat: ~
        Behat\MinkExtension:
            default_session: laravel
            laravel: ~

Thank you very much for any help!

Marco Pallante
  • 3,923
  • 1
  • 21
  • 26

1 Answers1

1

Behat is very simple. It treats a step as failed if an exception is thrown while executing it. It treats a step as successful otherwise.

As far as I can tell from the docs, Auth::check() does not throw an exception if user is not authenticated. It simply returns a boolean value.

Your step should be rather implemented more like the following:

    /**
     * @Then I will be automatically logged in
     */
    public function iWillBeAutomaticallyLoggedIn()
    {
        if (!Auth::check()) {
            throw new \LogicException('User was not logged in');
        }
    }

Your "I go to the registration form" step succeeds since you don't really verify if the page you visited is the one you expected to load. Again, you should throw an exception if a page you visited is not the right one.

Jakub Zalas
  • 35,761
  • 9
  • 93
  • 125
  • I agree about the `Auth::check()`, no exception is thrown there, so Behat doesn't fail. I'm in trouble with the `iGoToTheRegistrationForm()` method, because Laravel actually _throws_ an exception when I visit the `my/url` page, since that page does not exists – Marco Pallante Mar 13 '15 at 15:33
  • Laravel might be throwing an exception, but that results in an error page being rendered. No exception is thrown withing you step. – Jakub Zalas Mar 13 '15 at 23:16
  • In other words you need to still make sure the page you actually visited is not an error page. – Jakub Zalas Mar 15 '15 at 12:37
  • 1
    So, I should use something like `PHPUnit::assertTrue(Auth::check())` to throw and exception when I'm not logged in? Similarly, when I visit the `my/url` page, I should do something like `if ($this->getStatusCode() == 404) { throw new Exception(); }`. Am I right? – Marco Pallante Mar 16 '15 at 11:11
  • 1
    Precisely. Assuming you have all those methods ;) – Jakub Zalas Mar 18 '15 at 15:10