paq85
paq85

Reputation: 976

How to test Behat Context?

Behat is a very good tool, BDD/TDD/DDD is IMHO a foundation of SOLID coding but ...

I often see projects using Behat with quite complex Context classes that are NOT tested.

For example: Sylius/TaxonomyContext or Sylius/ProductContext

/**
 * @Given /^taxonomy "([^""]*)" has following taxons:$/
 */
public function taxonomyHasFollowingTaxons($taxonomyName, TableNode $taxonsTable)
{
    $taxonomy = $this->findOneByName('taxonomy', $taxonomyName);
    $manager = $this->getEntityManager();
    $taxons = array();
    foreach ($taxonsTable->getRows() as $node) {
        $taxonList = explode('>', $node[0]);
        $parent = null;
        foreach ($taxonList as $taxonName) {
            $taxonName = trim($taxonName);
            if (!isset($taxons[$taxonName])) {
                /* @var $taxon TaxonInterface */
                $taxon = $this->getRepository('taxon')->createNew();
                $taxon->setName($taxonName);
                $taxons[$taxonName] = $taxon;
            }
            $taxon = $taxons[$taxonName];
            if (null !== $parent) {
                $parent->addChild($taxon);
            } else {
                $taxonomy->addTaxon($taxon);
            }
            $parent = $taxon;
        }
    }
    $manager->persist($taxonomy);
    $manager->flush();
}

This example is not "a rocket science" but it has quite a lot of places it could not work. From my experience Behat Contexts can get quite complex.

Should I also "trust" my Contexts so much and assume they work 100% correct? Or is there any guide/tutorial how could I test Behat Contexts?

What do you do? How do you do it?

Upvotes: 4

Views: 312

Answers (1)

Eduard Sukharev
Eduard Sukharev

Reputation: 1311

I'd say it depends on the way you build your test suite.

As Behat is a framework to build your own test suite and since it's a software to be built, one should consider best software development practices. One among the others is and MVC concept. In Behat Contexts are "controllers" and should not contain much logic in them. Ideally they should call required methods in underlying services, which would provide main functionality.

Of course, for simple ready-made steps (like the ones provided by Mink extensions etc.) it's quite easy to create some tests, while for more complex logic I'd recommend creating a service which handles heavyweight logics, checks etc. Thus you could test isolated service from all sides, while keeping your "controller" context quite clean and simple.

On the other hand, if you can create your test without involving a lot of hidden logic (since tests should be as much open and clean as possible), then you shouldn't need any service and simple sentences should be enough. Then, if you really care about their quality you may create some minor tests.

For the complex cases as in provided example, i'd try to encapsulate some the code into service/manager and leave simple controller without any tests, while providing wide test coverage for underlying services.

Upvotes: 3

Related Questions