vaene
vaene

Reputation: 189

Behat Drupal: accessing features outside the %paths.base%

I am tasked with improving the behat testing in our existing distribution based Drupal system. The problem is I want to run behat tests from different directories that reference each other. We support multiple D7 sites and base them on our internal distribution so all the sites can share modules that create the same kind of functionality. Examples of distribution modules would be: dist_news and dist_events and for behat the distribution based tests would live in the dist_test module. These modules would create news and events content types across separate sites like dentist.oursite.org or radio.oursite.org and each module has its own repo in git. The specific sites are housed in a repo called dentist_builder or radio_builder both of which are based on a dist_builder which lives in its own repo and builds itself from the individual module repos via composer, grunt, yarn etc. The site specific tests live in a module called dentist_test which lives in the dentist builder. The problem arises when I want to test functionality that is on one site but not another. For instance. The dentist site has news and events, the radio site has news but not events, and the news on dentist has an In The News Section whereas the radio site does not. The various tests for news and events live in dist_test, so if I want to test them I can run something like:

vendor/bin/behat -c build/html/profiles/dist/modules/dist/dist_test/tests/behat.yml  build/html/profiles/dist/modules/dist/dist_test/tests/features/news/news.feature
vendor/bin/behat -c build/html/profiles/dist/modules/dist/dist_test/tests/behat.yml  build/html/profiles/dist/modules/dist/dist_test/tests/features/events/events.feature

and for radio I could run:

vendor/bin/behat -c build/html/profiles/dist/modules/dist/dist_test/tests/behat.yml  build/html/profiles/dist/modules/dist/dist_test/tests/features/news/news.feature

but the scenario testing the In The News part of news would fail, cause it ain't there on Radio.

So what I am trying to set up is having the tests run through the dentist_test's behat.yml or the radio_test's behat.yml so I can only test the stuff I want to test per site:

vendor/bin/behat -c build/html/src/modules/dentist_test/tests/behat.yml  --suite=news

vendor/bin/behat -c build/html/src/modules/radio_test/tests/behat.yml  --suite=news

where the respective suites would run ALL the tests, via tag filter or path, for dentist site and ONLY the tests we need for the radio site.

Dentist_builder, including the tests that work so far, has the relevant directory structure of:

vendor/
    bin/
        behat
build/
    html/
        profiles/
            dist/
                modules/
                    dist/
                        dist_test/
                            tests/
                                behat.yml
                                contexts/
                                    /FeatureContext.php
                                features/
                                    /news
                                        /news.feature
        src/
            modules/
                dentist_test/
                    tests/
                        behat.yml
                        features/
                            /homepage.feature

behat.yml in dentist_test is set up like this:

default:
    suites:
        default:
            contexts:

              - Dist\Context\FeatureContext:
                - screenshotDirectory: '%paths.base%/screenshots'
              - Drupal\DrupalExtension\Context\DrupalContext
              - Drupal\DrupalExtension\Context\MinkContext
              - Drupal\DrupalExtension\Context\MessageContext
              - Drupal\DrupalExtension\Context\DrushContext

I have tried setting up another suite to use the feautures in dist_test, but it ain't working:

news:
          contexts:
            - Dist\Context\FeatureContext:
              - screenshotDirectory: '%paths.base%/screenshots'
            - Drupal\DrupalExtension\Context\DrupalContext
            - Drupal\DrupalExtension\Context\MinkContext
            - Drupal\DrupalExtension\Context\MessageContext
            - Drupal\DrupalExtension\Context\DrushContext
          filters:
            tags: "@news"
          paths:
            - %paths.base%/../../../../../../profiles/dist/modules/dist/dist_test/tests/features/news

dist_test/tests/contexts/FeatureContext.php looks like:

<?php
/**
 * @file
 * Default context class defining how behat should test our application.
 *
 * @see http://docs.behat.org/en/latest/guides/4.contexts.html
 */

namespace Dist\Context;
use Drupal\DrupalExtension\Context\RawDrupalContext;
use Behat\Behat\Context\SnippetAcceptingContext;
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
use Behat\Behat\Hook\Scope\AfterScenarioScope;
use Behat\Behat\Hook\Scope\AfterStepScope;
use Behat\Behat\Tester\Exception\PendingException;
use Behat\Gherkin\Node\PyStringNode;
use Behat\Gherkin\Node\TableNode;
use Behat\Mink\Exception\ExpectationException;
use Behat\Mink\Exception\ElementNotFoundException;
use Symfony\Component\DependencyInjection\Container;

/**
 * Defines application features from the specific context.
 */
class FeatureContext extends RawDrupalContext implements SnippetAcceptingContext {

  /**
   * Initializes context.
   *
   * Every scenario gets its own context instance.
   */
  public function __construct($parameters = array()) {
    foreach ($parameters as $key => $value) {
      $property = lcfirst(Container::camelize($key));
      $this->$property = $value;
    }
  }

  /**
   * Custom step to assert that username of user with uid is not listed.
   *
   * @Then I should not see user :uid
   */
  public function iShouldNotSeeUser($uid) {
    $user = \user_load($uid);
    $this->assertSession()->pageTextNotContains($user->name);
  }

  ... (a bunch more functions)
}

Once I figure out how to access news.feature in dist_tests from the behat.yml in dentist_test I can fix the rest with paths and tags I think, I just need to now how to get to those features. What I want to avoid is replicating and maintaining the same distribution based tests in both dentist_test and radio_test, because once we get into the hundreds of sites that will become rediculous. I am assuming that

paths:
      - %paths.base%/../../../../../../profiles/dist/modules/dist/dist_test/tests/features/news

is where I am going wrong, or can behat even do what I want it to do? First time diving into behat so let me know if I am missing something simple architecture wise.

Upvotes: 1

Views: 218

Answers (1)

vaene
vaene

Reputation: 189

Turns out it WAS the path, only took me typing all that up to figure it out. Changed:

paths:
  - %paths.base%/../../../../../../profiles/dist/modules/dist/dist_test/tests/features/news

to:

paths:
  - %paths.base%/../../../../profiles/dist/modules/dist/dist_test/tests/features/news

the thing I missed is that dental_test lives at src/modules/dentist_test but is symlinked to build/html/sites/all/modules/custom/dental_test during the build of the site. I needed to put in the path from the former rather than the latter. Now it works great! But if anyone has a better way of doing this, please let me know.

Upvotes: 1

Related Questions