2017-12-17 19 views
1

私は現在、SpecFlowを使用することを学んでおり、ユーザーを登録するためのテストを含むFeatureを書きたいと考えています。SpecFlowのバックグラウンドステップを実装する正しい方法

私は最初のテストケース「有効なユーザーを登録する」を持っています。 これには、ユーザー名、電子メール、パスワード、および確認パスワードの入力が含まれます。提出をクリックすると、ユーザーを登録してDBに追加する必要があります。

私の次のテストケースでは、上記の手順を実行してから、同じユーザー名でユーザーを登録しようとすると、エラーが返されます。 私が見つけた例からわかるように、私の.featureファイルで "Background"を使用して、.featureファイルの各シナリオの前に実行したいステップを指定することができます。これには、「バックグラウンド」セクションにユーザーを登録し、「有効な登録ユーザー」のケースで作成されたメソッドを呼び出すためのステップを作成する必要があります。 このquestionは少し助けてくれましたが、利用可能なタグとフックの正しい使い方を理解できないため、私にはさらに多くの質問がありました。

私の質問は以下のとおりです。

  1. 有効なテストケースはシナリオの残りの部分と同じファイルにあるべきか?そのフィーチャファイル内のすべてのシナリオに対してバックグラウンドセクションが呼び出された場合、有効なテストが失敗する(本質的に有効なテストケースであるため)
  2. これはテストの構造を整える正しい方法ですか?私は[BeforeScenario]/[AfterScenario]などで使うことができるSpecFlowフックについて読んだことがありますが、これらが背景タグよりも考慮されるべきかどうかはわかりません。
  3. 避けることができる重複がたくさんあるような気がします。たとえば、有効なテストケースを別のテストのステップとして参照するだけで、テストケースとステップを作成するのではなく、 SpecFlowはどのように動作するはずですか?

これまでのところ、このテストケースでは私の.featureファイルに次のようなことがあります。

Feature: RegisterUser 
    In order to register a user successfully 
    A valid username, email, password (and confirmation password) must be entered 


@register 
Scenario: Valid Register User 
    Given I have entered a username "testing", an email "[email protected]", a password "123456" and a confirmation password "123456" 
    When I press submit 
    Then the response code should be 200 
    And the user should be added to the database with verfied set to False 

Background: 
    Given I have registered a user "testing", "[email protected]", "123456" and "123456" 

@register 
Scenario: Username Already Taken 
    Given I have entered a username "testing", an email "[email protected]", a password "123456" and a confirmation password "123456" 
    When I press submit 
    Then the response code should be 400 

そして、私の手順ファイルのようなものです:

using NUnit.Framework; 
using System; 
using System.Net.Http; 
using TechTalk.SpecFlow; 

namespace Tests.Specs 
{ 
[Binding] 
public class RegisterUserSteps 
{ 
    private RegisterUserModel userInfo = new RegisterUserModel(); 
    private RegisterUserController user = new RegisterUserController() 
    { 
     Request = new HttpRequestMessage(), 
     Configuration = new System.Web.Http.HttpConfiguration() 
    }; 
    private ApiResponse response = new ApiResponse(); 
    private static string userTableName = "usersTable"; 
    private static string userTablePartitionKey = "USER_INFO"; 
    private static string userTableRowKey = "[email protected]"; 


    [Given(@"I have entered a username ""(.*)"", an email ""(.*)"", a password ""(.*)"" and a confirmation password ""(.*)""")] 
    public void GivenIHaveEnteredAUsernameAnEmailAPasswordAndAConfirmationPassword(string p0, string p1, string p2, string p3) 
    { 
     userInfo.Username = p0; 
     userInfo.Email = p1; 
     userInfo.Password = p2; 
     userInfo.ConfirmPassword = p3; 
    } 

    [When(@"I press submit")] 
    public void WhenIPressSubmit() 
    { 
     response = user.Register(userInfo); 
    } 

    [Then(@"the response code should be (.*)")] 
    public void ThenTheResponseCodeShouldBe(int p0) 
    { 
     Assert.AreEqual(p0, response.Status); 
    } 


    [Then(@"the user should be added to the database with verfied set to False")] 
    public void ThenTheUserShouldBeAddedToTheDatabaseWithVerfiedSetToFalse() 
    { 
     UserEntity user = AzureUtilities.RetrieveEntity<UserEntity>(userTableName, userTablePartitionKey, userTableRowKey); 
     Assert.IsNotNull(user); 
     Assert.AreEqual(userInfo.Username, user.Username); 
     Assert.AreEqual(userInfo.Email, user.RowKey); 
     Assert.IsFalse(user.Verified); 
    } 

    [Given(@"I have registered a user ""(.*)"", ""(.*)"", ""(.*)"" and ""(.*)""")] 
    public void GivenIHaveRegisteredAUserAnd(string p0, string p1, string p2, string p3) 
    { 
     //Using methods here that have been defined in previous steps 
     GivenIHaveEnteredAUsernameAnEmailAPasswordAndAConfirmationPassword(p0, p1, p2, p3); 
     WhenIPressSubmit(); 
     ThenTheResponseCodeShouldBe(200); 
    } 

答えて

1

私はあなたが実際にあなたのシナリオに共通するものがなくても、バックグラウンドを使用してにジャンプしようとしていると思います。

SpecFlowは、ステップの一貫した構造を作成するだけで多くのステップを再利用できるという点でかなり堅牢です。

あなたの機能から始めましょう。この機能は、開発者スクリプトのように読み込まれます。機能は、いくつかのビジネス目標を表すはずです。私のためにクマ私はあなたのビジネス目標のいずれかが、今、私たちは、我々はこれを達成するためのシナリオのレイアウトを開始することができ、コードを書いている理由を知っていることを

Feature: Register New Users 
    In order to perform task that only registered users can do 
    As a web site user 
    I want to register for the site 

をしているのか分かりません。

Given I am not registered for the site 
And I have filled out the registration form as follows 
| Field     | Value    | 
| username    | testing   | 
| email     | [email protected] | 
| password    | 123456   | 
| password confirmation | 123456   | 
When I submit the registration 
Then the response code should be '200' 
And the database should have an unverified user 

これはsstepscenariosの数を作成しますが、あなたは今、登録フォームに記入し、応答コードをチェックするために、あなたの変数に渡しているので、すぐに再利用を得ようとしています。

だから今、あなたのユーザ名がすでにシナリオが

Scenario: Username taken 
Given a user has registered with the following information 
| Field     | Value    | 
| username    | testing   | 
| email     | [email protected] | 
| password    | 123456   | 
| password confirmation | 123456   | 
And I have filled out the registration form as follows 
| Field     | Value    | 
| username    | testing   | 
| email     | [email protected] | 
| password    | 123456   | 
| password confirmation | 123456   | 
When I submit the registration 
Then the response code should be '400' 

に変更することができ取らだから今、あなたが実装する必要がある唯一のステップは、ユーザーが次のような情報

に登録されている与えられた最初のステップ

です

とステップは単なるコードなので、このような最初のシナリオから既に定義されたステップを呼び出すことができます

[Given(@"a user has registered with the following information")] 
    public void GivenAUserHasRegisteredWithTheFollowingInformation(Table table) 
    { 
     GivenIHaveFilledOutTheRegistrationFormAsFollows(table); 
     WhenISubmitTheRegistration(); 
     ThenTheResponseCodeShouldBe(200) 
    } 

フックについては、より技術的な目的でこれらを使用します。私はセレンを使用してテストで多くの外部を行います。シナリオの前に実行されるフック@webを作成して、シナリオが完了した後にSeleniumを回転させて引き裂きます。私はシナリオの前にHttpClientをスピンアップさせ、後で涙が出ることを望むという点でAPIテストでも同じことをしました。また、実際にテストを開始する前に、データベースをクリアする、既知の状態にクリアしてシードするなどの作業を行うこともできます。

私はこれがあなたのすべての質問に答えることを願っています。

関連する問題