TestNGのパラメトリックテスト


ソフトウェアテストでは、ソフトウェアの安定性とロバスト性を保証するために、多くのデータセットをテストする必要があります.JUnitはテストパラメータの伝達を容易にするメカニズムを提供していないため,テストデータセットごとにコードを単独で書いてテストする必要がある.このように多くの時間と精力を浪費してテストコードを繰り返し書くのは、パラメータが異なるだけで、テストロジックは完全に同じです.同時に、テストコードとテストデータは分離されず、今後のメンテナンスに隠れた危険を埋めている.
TestNGはパラメータ化テストにおいてJUnitよりも大きなメリットがある.パラメータを渡す方法は2つあります.testng.xml方式はコードとテストデータを分離し、拡張とメンテナンスを容易にする.@DataProviderは比較的複雑なパラメータを提供し、一定の規則を持つテストデータセットを容易に生成することができます.

1. testng.xml


タグでtestng.xmlでパラメータの値を定義します.同じパラメータについては、異なる場所で異なる値を定義ことができるのでtestngに注意する必要がある.xmlのテスト範囲の問題です.
タブとタブは、suiteとtestの2つのテスト範囲を定義します.1つのtestは一連のテスト方法を含み、1つのsuiteは複数の独立したtestを含むことができます.この2つのテスト範囲にはどんな違いがありますか?1つのtestのすべてのテストメソッドは、同じテストオブジェクトに対して、テストメソッド間で相互に影響を与えることができます.一方、suiteの各testは、2つのtestのテスト方法が相互に影響しない個別のテストオブジェクトに対して行われます.
この2つのテスト範囲で定義されたパラメータは、次の法則を満たします.
1)Suiteの範囲内であるパラメータの値を定義し、すべてのTestに対して有効とする.
2)Testの範囲内であるパラメータの値を定義し、そのTestに対してのみ有効である.
3)SuiteとTestで同時にパラメータを定義すると、Test範囲の値はSuiteの値をブロックします.
サンプルコードは次のとおりです.
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >

<suite name="Suite" verbose="1">
	<parameter name="username" value="root" />
	<parameter name="password" value="pwd" />
	<parameter name="param" value="param" />

	<test name="test1">
		<parameter name="username" value="root2" />
		<parameter name="password" value="pwd2" />
		<classes>
			<class name="HelloWorld" />
		</classes>
	</test>

	<test name="test2">
		<packages>
			<package name="com.ibm.testng.test"></package>
		</packages>
	</test>
<suite>
はsuiteでusernameとpasswordの2つのパラメータを定義し、test 1でも2つのパラメータを定義しているが、test 2では定義されていない.したがって、test 1のすべての試験方法のusernameおよびpasswordはそれぞれ「root 2」および「pwd 2」であり、test 2のすべての試験方法のusernameおよびpasswordはそれぞれ「root」および「pwd」である.
Javaコードでは、テストメソッドにパラメータを渡すサンプルコードは次のとおりです.
    @Parameters({"username"})
    @Test(groups = "login")
    public void inputUsername(String username) {
        System.out.println("Input Username: " + username); 
    }
    
    @Parameters({"password"})
    @Test(groups = "login")
    public void inputPassword(String password) {
        System.out.println("Input Password: " + password); 
    }
パラメータ付き関数が@Testでテスト関数としてマークされていますが、@Parametersでマークされていないか、@Parametersでマークされていますが、伝達パラメータの名前が指定されていないとTestNGExceptionが投げ出され、この関数はfailが落とされたとみなされます.
testng.xmlは単純なタイプのパラメータしか転送できず、Objectタイプは転送できません.Objectタイプのパラメータは間接的に渡すことができます.すべてのパラメータを1つのxmlファイルに配置し、そのxmlファイル名をパラメータとしてXML解析器に渡します.xml解析のパラメータを属性として、必要なObjectオブジェクトを作成し、これらのオブジェクトに対してテスト方法を実行します.

2. @DataProvider


@DataProviderを使用してパラメータを渡す例です.コードは次のとおりです.
    @DataProvider(name = "user")
    public Object [][] createUser(Method m) {
        System.out.println(m.getName());
        return new Object[][] { 
                {"root", "root"},
                {"test", "root"},
                };
    }
    
    @Test(groups = "login", dependsOnGroups = "launch", dataProvider = "user")
    public void verifyUser(String username, String password) {
        System.out.println("Verify User : " + username + ":" + password); 
        assert username.equals(password);
    }
サンプルコードの説明:
1)@DataProviderタグのcreateUser()はuserという名前のパラメータを提供し、パラメータを受け入れるテスト関数の名前を出力します.
2)@Testタグのテスト関数verifyUser()は,userという名前のパラメータを受け入れ,パラメータusernameとpasswordが等しいか否かを判断する.
@DataProviderタグは、テスト方法に特化したパラメータを提供する方法です.このようなメソッドは、Object[][]タイプの2次元配列を返さなければなりません.Object[]の各行は、テストメソッドのテストデータセットであり、テストメソッドはテストデータセットごとに1回実行されます.パラメータの名前が指定されていない場合は、デフォルトでメソッドの名前であり、メソッドの名前には制限はありません.
@DataProviderタグの方法は、一般的にはパラメータがありませんが、実際にはパラメータを持つこともできますが、これらのパラメータの伝達には次の2つの制限があります.
1)@DataProviderタグの方法はテスト関数ではないので@Parametersでパラメータを渡すことはできません.
2)@DataProviderタグのメソッドはTestNGによってのみ呼び出されるため,ユーザは呼び出しによってパラメータを渡すことができない.
上記の2つの制限に基づいて,@DataProviderタグの方法のパラメータ化は,TestNGがこの方法を呼び出す際に反射機構によって得ることができる特殊なタイプでなければならない.例えば、例で伝達するパラメータはjavaである.lang.reflect.Methodタイプ、TestNGは現在のテスト関数の名前をこのパラメータに渡します.この特殊なタイプのパラメータは、複数のテスト関数が同じ@DataProviderで提供されるパラメータを同時に使用する場合、テスト方法に従って異なるテストデータセットを提供する必要がある場合に便利です.