0
votes

What is the right approach for using FooContext classes in behat?

What it is by the docs:

A simple mnemonic for context classes is: “testing features in a context”. (...), the way you will test those features pretty much depends on the context you test them in.

In the docs FeatureContext seems for me only to be a dummy context file so that you can fast create a behat test.

The context class should be called FeatureContext. It’s a simple convention inside the Behat infrastructure. FeatureContext is the name of the context class for the default suite.

Its not saying me directly that it has to be a context file per feature.

The only real other examples in the docs are contexts like ApiContext or WebContext.

default:
    suites:
        web_features:
            paths:    [ %paths.base%/features/web ]
            contexts: [ WebContext ]
        api_features:
            paths:    [ %paths.base%/features/api ]
            contexts: [ ApiContext ]

What i also found was a CommandFeature and another CommandLineProcessContext.

So if i have many features to test, a context file would blow up very fast.

Then i see a more likely a context file per feature example by Marco Pivetta using an Aggregate as Context.

Is it a good idea to have a single context file per feature foo.feature? Or are context files thought to be environmental contexts like in the docs ApiContext or WebContext?

1

1 Answers

1
votes

Usually I prefer to divide context and features as follows:

  • One folder for each domain subject
  • One feature / context file for each action you can perform onto this subjects

That way you'll end up with a single suite using more than one context but with all context divided with a single responsibility.

Quick example

Features
|--- User
|----- login.feature
|----- change_password.feature
|----- impersonate.feature
|----- ban.feature
|----- ...
|--- ...
|--- Order
|----- checkout.feature
|----- cancel.feature
...
Context
|--- User
|---- LoginContext
|---- ChangePasswordContext
|---- ImpersonateContext
|---- BanContext
|---- ...
|--- Order
|---- CheckoutContext
|---- CancelContext

Each suite is composed with many context (for example, every time you need to login to check a behavior, you'll include LoginContext in your suite).

default:
  suites:
    suite_name:
      paths:
        - '%paths.base%/Path/To/Feature/File'
      contexts:
        - Path\To\Context\LoginContext
        - Path\To\A\SecondContext
        - ...

This approach has many advantages in terms of maintainability, intuitiveness and so on.

If you would like to have a more generic panoramic on this subject, you can check slides from my talk at Symfony day 2017 in Milan