Testng: λ©”μ†Œλ“œ μˆ˜μ€€μ—μ„œ λ§€κ°œλ³€μˆ˜λ₯Ό μ§€μ›ν•©λ‹ˆκΉŒ?

에 λ§Œλ“  2015λ…„ 10μ›” 12일  Β·  12μ½”λ©˜νŠΈ  Β·  좜처: cbeust/testng

λ©”μ†Œλ“œ μˆ˜μ€€μ—μ„œ 특수 λ§€κ°œλ³€μˆ˜λ₯Ό 지원할 수 μžˆμŠ΅λ‹ˆκΉŒ?
예λ₯Ό λ“€μ–΄,

<test name="Regression1">
<groups>
    <run>
      <exclude name="brokenTests"  />
      <include name="checkinTests"  />
    </run>
  </groups>

  <classes>
    <class name="test.IndividualMethodsTest">
      <methods>
        <include name="testMethod" param1="121" param2="1212"  />
      </methods>
    </class>
  </classes>
</test>

testng μ½”λ“œλ₯Ό μˆ˜μ •ν•˜μ—¬ 이λ₯Ό λ‹¬μ„±ν•˜λ €κ³  ν•©λ‹ˆλ‹€. 이에 λŒ€ν•œ 지침/μ‹œμž‘μ— κ°μ‚¬λ“œλ¦½λ‹ˆλ‹€.

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

μ‹€μ œλ‘œ λ©”μ„œλ“œ μˆ˜μ€€μ˜ 맀개 λ³€μˆ˜κ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€. λ‹€μŒμ€ μ˜ˆμž…λ‹ˆλ‹€.

<suite name="my-suite" verbose="1">
    <test name="my-test">
        <classes>
            <class name="testng.ex1.TestParams">
                <methods>
                    <include name="m1">
                        <parameter name="key1"  value="val1"/>
                        <parameter name="key2"  value="val2"/>
                    </include>
                    <include name="m2">
                        <parameter name="key1"  value="valA"/>
                        <parameter name="key2"  value="valB"/>
                    </include>
                </methods>
            </class>
        </classes>
    </test>
</suite>
package testng.ex1;

import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class TestParams {

    <strong i="8">@Test</strong>
    @Parameters({ "key1", "key2" })
    public void m1(String key1, String key2) throws Exception {
        System.out.println(key1 + ", " + key2);
    }

    <strong i="9">@Test</strong>
    @Parameters({ "key1", "key2" })
    public void m2(String key1, String key2) throws Exception {
        System.out.println(key1 + ", " + key2);
    }
}

λͺ¨λ“  12 λŒ“κΈ€

μ•„λ‹ˆμš”, @DataProvider λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.

@cbeust , @DataProvider 의 λ¬Έμ œλŠ” testng.xmlμ—μ„œ μ •μ˜ν•  수 μ—†λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. 이 λ§€κ°œλ³€μˆ˜λ₯Ό μ „λ‹¬ν•˜λŠ” μ΄μœ λŠ” λ©”μ†Œλ“œμ— λŒ€ν•œ 데이터가 λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ 제곡되고 이 λ§€κ°œλ³€μˆ˜κ°€ κΈ°λ³Έ 킀이기 λ•Œλ¬Έμž…λ‹ˆλ‹€. 이 ν‚€λ₯Ό μ‚¬μš©ν•˜κ³ , 데이터λ₯Ό κ°€μ Έμ˜€κ³ , λ¦¬ν”Œλ ‰μ…˜μ„ μ‚¬μš©ν•˜μ—¬ λŸ°νƒ€μž„μ— λ©”μ„œλ“œμ— λŒ€ν•œ 데이터 개체λ₯Ό λ§Œλ“€κ³  μ‹ΆμŠ΅λ‹ˆλ‹€. 즉, DataProviderλ₯Ό μ‚¬μš©ν•˜λ”λΌλ„ λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ 선택해야 ν•˜λŠ” ν–‰ 집합을 λ‚˜νƒ€λ‚΄κΈ° μœ„ν•΄ λŸ°νƒ€μž„μ— 값을 전달해야 ν•©λ‹ˆλ‹€. 이것은 testngλ₯Ό ν”„λ‘œκ·Έλž˜λ° λ°©μ‹μœΌλ‘œ μ‚¬μš©ν•˜λŠ” μ‹œλ‚˜λ¦¬μ˜€μ— λŒ€ν•œ κ²ƒμž…λ‹ˆλ‹€.

testng.xml μ—μ„œ μ œν•œλœ μ–‘μ˜ λ§€κ°œλ³€μˆ˜λ₯Ό μ •μ˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

http://testng.org/doc/documentation-main.html#parameters -testng-xml

μ„Έλ“œλ¦­

2015λ…„ 10μ›” 12일 μ›”μš”μΌ μ˜€ν›„ 9:03 JayVem [email protected] μ—μ„œ λ‹€μŒκ³Ό 같이 μΌμŠ΅λ‹ˆλ‹€.

@cbeust https://github.com/cbeust , @DataProvider 에 λŒ€ν•œ 도전은
testng.xmlμ—μ„œ μ •μ˜ν•  수 μ—†μŠ΅λ‹ˆκΉŒ? 이것을 ν†΅κ³Όν•œ 이유
λ§€κ°œλ³€μˆ˜λŠ” λ©”μ†Œλ“œμ— λŒ€ν•œ 데이터가 λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ μ œκ³΅λœλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.
λ§€κ°œλ³€μˆ˜λŠ” κΈ°λ³Έ ν‚€μž…λ‹ˆλ‹€. 이 ν‚€λ₯Ό μ‚¬μš©ν•˜κ³ , 데이터λ₯Ό κ°€μ Έμ˜€κ³ ,
λ¦¬ν”Œλ ‰μ…˜μ„ μ‚¬μš©ν•˜μ—¬ λŸ°νƒ€μž„μ— λ©”μ„œλ“œμ— λŒ€ν•œ 데이터 κ°œμ²΄μž…λ‹ˆλ‹€. κ·Έλž˜μ„œ μš”μ»¨λŒ€, 심지어
DataProviderλ₯Ό μ‚¬μš©ν•˜λŠ” 경우 λŸ°νƒ€μž„μ— 값을 전달해야 ν•©λ‹ˆλ‹€.
λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ 선택해야 ν•˜λŠ” ν–‰ 집합을 λ‚˜νƒ€λƒ…λ‹ˆλ‹€. 참고둜 이
testngλ₯Ό ν”„λ‘œκ·Έλž˜λ° λ°©μ‹μœΌλ‘œ μ‚¬μš©ν•˜λŠ” μ‹œλ‚˜λ¦¬μ˜€μš©μž…λ‹ˆλ‹€.

β€”
이 이메일에 직접 λ‹΅μž₯ν•˜κ±°λ‚˜ GitHubμ—μ„œ ν™•μΈν•˜μ„Έμš”.
https://github.com/cbeust/testng/issues/823#issuecomment -147592710.

@cbeust 이 λ§€κ°œλ³€μˆ˜λŠ” μ œν’ˆκ΅° μˆ˜μ€€μ΄ μ•„λ‹™λ‹ˆκΉŒ? λ©”μ„œλ“œ μˆ˜μ€€μ—μ„œ λ³΅μž‘ν•œ 데이터 ν˜•μ‹μ„ λ§Œλ“€κ³  μ‹Άλ‹€λ©΄ μ–΄λ–»κ²Œ ν•΄μ•Ό ν• κΉŒμš”? 예λ₯Ό λ“€μ–΄, 이 μ½”λ“œλ₯Ό κ³ λ €ν•˜μ‹­μ‹œμ˜€...

public class EmployeeBenefitsCalculator {

    <strong i="7">@Test</strong>
    public void calculateBenefits(Employee employee) {
        //do something with employee here.
    }
}

computeBenefits λ©”μ†Œλ“œλ‘œ μ „μ†‘λ˜λŠ” Employee λ§€κ°œλ³€μˆ˜λŠ” λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ μƒμ„±λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€. μ–΄λ–»κ²Œ ν•˜λ©΄ λ κΉŒμš”? κΈ°λ³Έ ν‚€λ₯Ό μ „λ‹¬ν•˜κ³  CalculateBenefits λ©”μ„œλ“œ λ‚΄μ—μ„œ 이 κΈ°λ³Έ ν‚€λ₯Ό 읽고 dbμ—μ„œ 데이터λ₯Ό κ°€μ Έμ˜€κ³  ν•΄λ‹Ή ν…ŒμŠ€νŠΈ 싀행을 μœ„ν•œ 직원 개체λ₯Ό λ§Œλ“€κ³  μ‹ΆμŠ΅λ‹ˆλ‹€. λ³΅μž‘ν•˜κ²Œ λ“€λ¦°λ‹€λŠ” 것을 μ•Œκ³  μžˆμŠ΅λ‹ˆλ‹€. 이것이 λ‚΄κ°€ μ°ΎλŠ” 것이라고 μƒκ°ν•©λ‹ˆλ‹€ -

public class EmployeeBenefitsCalculator {

    <strong i="11">@Test</strong>
    public void calculateBenefits(Employee employee) {
        employee = DataStore.fetch("id_from_testng_xml");
    }
}

λŸ°νƒ€μž„μ— ν…ŒμŠ€νŠΈλ₯Ό μœ„ν•΄ 데이터 μ œκ³΅μžμ—κ²Œ λ§€κ°œλ³€μˆ˜λ₯Ό μ œκ³΅ν•˜λ €λ©΄ μ–΄λ–»κ²Œ ν•΄μ•Ό ν•©λ‹ˆκΉŒ? testng μ†ŒμŠ€λ₯Ό λ³€κ²½ν•˜μ—¬ 이 λ™μž‘μ„ μƒμ„±ν•˜λŠ” 것이 μ–Όλ§ˆλ‚˜ μ‰¬μš΄κ°€μš”?

데이터 κ³΅κΈ‰μž + λ§€κ°œλ³€μˆ˜λ₯Ό ν˜Όν•©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 데이터 κ³΅κΈ‰μžλŠ” λ§€κ°œλ³€μˆ˜μ—μ„œ κΈ°λ³Έ ν‚€λ₯Ό κ°€μ Έμ˜€κ³  직원 개체λ₯Ό λ§Œλ“€κ³  λ‹€λ₯Έ 속성을 μ „λ‹¬ν•©λ‹ˆλ‹€. 그런 λ‹€μŒ ν…ŒμŠ€νŠΈ 방법은 데이터 κ³΅κΈ‰μžμ™€ ν•΄λ‹Ή 속성을 μ‚¬μš©ν•©λ‹ˆλ‹€.
μ‰¬μš΄! ;)

@juherr 각각 데이터 제곡자 μ—κ²Œ κ°€λŠ” λ©”μ„œλ“œ μˆ˜μ€€μ—μ„œ μ—¬λŸ¬ λ§€κ°œλ³€μˆ˜λ₯Ό κ°€μ§ˆ 수 μžˆλŠ” 방법에 λŒ€ν•œ 예λ₯Ό λ“€μ–΄ μ£Όμ‹œκ² μŠ΅λ‹ˆκΉŒ?

@juherr λ‚΄ μ§ˆλ¬Έμ„ λ‹¨μˆœν™”ν•˜κΈ° μœ„ν•΄ ν”„λ‘œκ·Έλž˜λ° λ°©μ‹μœΌλ‘œ testng.xml을 μƒμ„±ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. 이제 modifyEmployee(Employee employee) λ©”μ„œλ“œκ°€ μžˆλ‹€κ³  κ°€μ •ν•΄ λ³΄κ² μŠ΅λ‹ˆλ‹€. 이 λ©”μ„œλ“œκ°€ 4번 ν˜ΈμΆœλ˜μ§€λ§Œ 맀번 λ‹€λ₯Έ Employeeλ₯Ό μ‚¬μš©ν•˜λŠ” λ°©μ‹μœΌλ‘œ xml을 λ§Œλ“€μ–΄μ•Ό ν•©λ‹ˆλ‹€. λ‚˜λŠ” testng.xml을 생성할 λ•Œ 이 직원듀 각각의 κΈ°λ³Έ ν‚€λ₯Ό μ•Œκ³  μžˆμ„ κ²ƒμž…λ‹ˆλ‹€. κ·Έλ ‡λ‹€λ©΄ λ‚΄κ°€ ν•˜λ €λŠ” 것을 μ„±μ·¨ν•˜λŠ” κ°€μž₯ 쒋은 방법은 λ¬΄μ—‡μž…λ‹ˆκΉŒ?

@DataProvider κ°€ @Parameters 와 ν•¨κ»˜ μž‘λ™ν•  수 μžˆλ‹€κ³  κ°€μ •ν–ˆμ§€λ§Œ ν™•μ‹€ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€(μ–Έμ  κ°€λŠ” ν…ŒμŠ€νŠΈν•΄μ•Ό 함).
BTW, μ›ν•˜λŠ” 것을 μ΄ν•΄ν•˜λ©΄ ν…ŒμŠ€νŠΈ μˆ˜μ€€μ—μ„œ 맀개 λ³€μˆ˜λ₯Ό μ‹œλ„ ν•  수 μžˆμŠ΅λ‹ˆλ‹€ (λ©”μ†Œλ“œ μˆ˜μ€€μ˜ 맀개 λ³€μˆ˜λŠ” μ‘΄μž¬ν•˜μ§€ μ•ŠμŒ).

<suite>
<test name="Regression1">
<parameter name="param1" value="121" />
<parameter name="param2" value="1212" />
<groups>
    <run>
      <exclude name="brokenTests"  />
      <include name="checkinTests"  />
    </run>
  </groups>

  <classes>
    <class name="test.IndividualMethodsTest">
      <methods>
        <include name="testMethod"  />
      </methods>
    </class>
  </classes>
</test>

<test name="Regression2">
<parameter name="param1" value="454" />
<parameter name="param2" value="4545" />
<groups>
    <run>
      <exclude name="brokenTests"  />
      <include name="checkinTests"  />
    </run>
  </groups>

  <classes>
    <class name="test.IndividualMethodsTest">
      <methods>
        <include name="testMethod"  />
      </methods>
    </class>
  </classes>
</test>
<suite>

더 λ§Žμ€ 아이디어λ₯Ό μ›ν•˜μ‹œλ©΄ Staskoverflowλ‚˜ 메일링 λ¦¬μŠ€νŠΈμ— μ§ˆλ¬Έμ„ ν•˜μ„Έμš” ;)

μ‹€μ œλ‘œ λ©”μ„œλ“œ μˆ˜μ€€μ˜ 맀개 λ³€μˆ˜κ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€. λ‹€μŒμ€ μ˜ˆμž…λ‹ˆλ‹€.

<suite name="my-suite" verbose="1">
    <test name="my-test">
        <classes>
            <class name="testng.ex1.TestParams">
                <methods>
                    <include name="m1">
                        <parameter name="key1"  value="val1"/>
                        <parameter name="key2"  value="val2"/>
                    </include>
                    <include name="m2">
                        <parameter name="key1"  value="valA"/>
                        <parameter name="key2"  value="valB"/>
                    </include>
                </methods>
            </class>
        </classes>
    </test>
</suite>
package testng.ex1;

import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class TestParams {

    <strong i="8">@Test</strong>
    @Parameters({ "key1", "key2" })
    public void m1(String key1, String key2) throws Exception {
        System.out.println(key1 + ", " + key2);
    }

    <strong i="9">@Test</strong>
    @Parameters({ "key1", "key2" })
    public void m2(String key1, String key2) throws Exception {
        System.out.println(key1 + ", " + key2);
    }
}

:+1: 닀행이닀! λ‚˜λŠ” 그것을 전에 λ³Έ 적이 μ—†λ‹€.

@JayVem 이미 μ‘΄μž¬ν•˜λŠ” 문제λ₯Ό μ’…λ£Œν•©λ‹ˆλ‹€.

또 λ‹€λ₯Έ μ ‘κ·Ό 방식은 testng.xmlμ—μ„œ ν‚€λ₯Ό κ°€μ Έμ˜€λŠ” 데이터 κ³΅κΈ‰μžλ₯Ό μ‚¬μš©ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. 예λ₯Ό μ°Έμ‘°ν•˜μ‹­μ‹œμ˜€.

<suite name="my-suite" verbose="1">
    <test name="my-test">
        <classes>
            <parameter name="keys" value="key1,key2,key3,key4" />
            <class name="testng.ex2.TestParams" />
        </classes>
    </test>
</suite>
package testng.ex2;

import java.util.Arrays;
import java.util.List;

import org.testng.ITestContext;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class TestParams {

    @Test(dataProvider = "dp")
    public void m1(Employee e) throws Exception {
        System.out.println("name: " + e.getName() + ", age: " + e.getAge());
    }

    @DataProvider(name = "dp")
    @Parameters("keys")
    public Object[][] createData(ITestContext ctx) {
        String keysString = ctx.getCurrentXmlTest().getLocalParameters().get("keys");
        List<String> keys = Arrays.asList(keysString.split(","));

        Object[][] result = new Object[keys.size()][1];
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            result[i] = new Object[] { new Employee(key) };
        }
        return result;
    }
}

package testng.ex2;

public class Employee {

    private final String name;
    private final int age;

    public Employee(String key) {
        // use 'key' to lookup employee in database
        name = key + "_name"; // dummy value
        age = 41; // dummy value
    }

    String getName() {
        return name;
    }

    int getAge() {
        return age;
    }
}

@drapostolos μ—κ²Œ κ°μ‚¬λ“œλ¦½λ‹ˆλ‹€.

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰