Search code examples
behat

Is it ok to test repository with behat?


I want to test functionality of adding user.

I wrote the following scenario:

Feature: Add users
  In order to have users
  As an admin
  I need to be able to add users to database

  Rules:
  - User has a name

  Scenario: Adding user with name 'Jonas'
    Given There is no user 'Jonas'
    When I add the user with name 'Jonas'
    Then I should have user 'Jonas' in a system

And the following test:

<?php

use AppBundle\Repository\UserRepository;
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 AppBundle\Entity\User;
use Symfony\Component\Config\Definition\Exception\Exception;

/**
 * Defines application features from the specific context.
 */
class FeatureContext implements Context, SnippetAcceptingContext
{
    private $userRepository;

    /**
     * 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(UserRepository $userRepository)
    {
        $this->userRepository = $userRepository;
    }

    /**
     * @Given There is no user :arg1
     */
    public function thereIsNoUser($arg1)
    {
        $user = $this->userRepository->findOneBy(['name' => $arg1]);
        if ($user) {
            $this->userRepository->delete($user);
        }
    }

    /**
     * @When I add the user with name :arg1
     */
    public function iAddTheUserWithName($arg1)
    {
        $user = new User($arg1);
        $this->userRepository->add($user);
    }

    /**
     * @Then I should have user :arg1 in a system
     */
    public function iShouldHaveUserInASystem($arg1)
    {
        $user = $this->userRepository->findOneBy(['name' => $arg1]);

        if (!$user) {
            throw new Exception('User was not added');
        }

        $this->userRepository->delete($user);
    }
}

I am not sure if I do it in correct/quality way, so good programmers would think its good. Do I test the way I want? Or should I test this from end to end - call the controller method and check for response? Calling controller method would test more I believe, because we can break something in cotroller also, for example the status code returned, or json format.

But in behat documentation I saw an example of testing just specific class - basket and shelf:

http://docs.behat.org/en/v3.0/quick_intro_pt1.html

So I thought - I can also test specific class - repository.

And to call a controller method I also would need to use some fake browser - http://mink.behat.org/en/latest

which might be more work.


Solution

  • Yes, you can test what you want, however it is a good practice to define some features with scenarios/flows.

    If you want and need to test end to end then do it, else test what you need to be tested.

    Related to the controller method call you should do what is logical and bring value to your suite, all you need to keep in mind is handling the exception and throwing the appropriate exceptions that are meaningful to you.

    Try to make a quick plan, you can also discuss with the people from the team that can add some valuable input to the automation approach, of what you need to cover.

    Other things to keep in mind: take a look at Mink drivers and also to Page Objects.