dongyizhui0616
2015-08-10 13:54
浏览 30
已采纳

在Behat中分离测试套件

I'm trying to reproduce isolated test suites with Behat like I have with Cucumber. I've been trying to tweak the behat.yml file using suites and paths as well as moving files and folders around. Behat results make so little sense that I am starting to conclude that it was not designed with this in mind at all. And the documentation does not describe expected files & folder layouts

For each test suite I want:

  • a specific xxx.feature file
  • a specific xxxContext.php file, defining a its own xxxContext class

I don't want a monolithic FeatureContext.php file. My project is so huge that it would become a nightmare to maintain, not to mention the potential collateral damage between steps. It's OK to have a single behat.yml file if that helps.

I also read this post but I still haven't solved the problem. How I can create isolated test suites with Behat?

Note: I am using behat 3.0-dev


Edit: Here is the "best" I could achieve. I have two suites, one called "OAuth2" and another called "Achievements".

beyat.yml:

default:
    suites:
        OAuth2:
            contexts:
                - OAuth2Context
        Achievements:
            contexts:
                - AchievementsContext

File hierarchy:

├── behat.yml
└── features
    ├── Achievements.feature
    ├── OAuth2.feature
    └── bootstrap
        └── OAuth2Context.php  <-- Contains the OAuth2Context and AchievementsContext classes. Also, classes are found only if I name this file this way, I don't know why.

My main problem is that when I run behat, it complains that there are missing steps. Basically, the OAuth2Context class is missing steps that were defined in Achievements and the AchievementsContext is missing steps that were defined in OAuth2. This output completely baffles me:

--- OAuth2Context has missing steps. Define them with these snippets:

    /**
     * @When I say yes
     */
    public function iSayYes()
    {
        throw new PendingException();
    }

    /**
     * @Then you say no
     */
    public function youSayNo()
    {
        throw new PendingException();
    }

--- AchievementsContext has missing steps. Define them with these snippets:

    /**
     * @When I ask for an Access Token with my credentials
     */
    public function iAskForAnAccessTokenWithMyCredentials2()
    {
        throw new PendingException();
    }

    /**
     * @Then I receive an Access Token
     */
    public function iReceiveAnAccessToken2()
    {
        throw new PendingException();
    }

    /**
     * @When I ask for an Access Token with a Partner User grant type where:
     */
    public function iAskForAnAccessTokenWithAPartnerUserGrantTypeWhere(TableNode $table)
    {
        throw new PendingException();
    }

I believe that this is because I defined two separate classes in the php file. But I really don't want to make a single monolitic class. In fact, I'd even like two separate PHP files. The Classes are defined this way:

class OAuth2Context implements Context, SnippetAcceptingContext
{
...
    /**
     * @When I ask for an Access Token with my credentials
     */
    public function iAskForAnAccessTokenWithMyCredentials()
    {
    ...
    }
...
}

class AchievementsContext implements Context, SnippetAcceptingContext
{
...
    /**
     * @When I say yes
     */
    public function iSayYes()
    {
    ...
    }
...
}

Other (smaller) issue is that I have to name my php file OAuth2Context.php instead of FeatureContext.php, otherwise the classes are not found at all. I don't understand this, as it was my understanding that FeatureContext.php was behat's default name.


Edit: SOLUTION, thanks to Jakub Zalas :

Here is the file layout that works:

├── behat.yml
└── features
    ├── achievements
    │   └── Achievements.feature
    ├── bootstrap
    │   ├── AchievementsContext.php  <-- AchievementsContext class
    │   └── OAuth2Context.php        <-- OAuth2Context class
    └── oauth
        └── OAuth2.feature

With the following beyat.yml file:

default:
    suites:
        OAuth2:
            contexts:
                - OAuth2Context
            paths:    [ %paths.base%/features/oauth ]
        Achievements:
            contexts:
                - AchievementsContext
            paths:    [ %paths.base%/features/achievements ]

This way I have steps in separated PHP files, which was my main requirement, and separated suites with separated feature files. I am a happy camper!

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • du060334 2015-08-13 09:43
    已采纳

    With the way you currently organised your suites each feature file will be run for each suite.

    Use filters or paths to define which feature files should match a given suite:

    # behat.yml
    
    default:
        suites:
            OAuth2:
                contexts:
                    - OAuth2Context
                paths:    [ %paths.base%/features/oauth ]
            Achievements:
                contexts:
                    - AchievementsContext
                paths:    [ %paths.base%/features/achievements ]
    

    Having a single feature file per suite is probably not worth it, as you'll end up with lots of suites without a real benefit. Better group features in slightly bigger suites, and register multiple contexts per suite.

    打赏 评论

相关推荐 更多相似问题