
確ãã«èª°ãããã¹ãé§åéçºïŒTDDïŒã®æŠå¿µã«ç²ŸéããŠããŸãã ããã«å ããŠã ããŒã¿é§åãã¹ãïŒDDTãShevchukãžã®éåãªãïŒãªã©ããããŸãããã¹ããèšè¿°ããããã®ææ³ã§ããã¹ãçšã®ããŒã¿ã¯ãã¹ãèªäœãšã¯å¥ã«ä¿åãããŸãã ãããã¯ããã¹ãã®å®è¡äžã«çæãããããŒã¿ããŒã¹ã§ãããã¡ã€ã«ã«ä¿åã§ããŸãã åãæ©èœãç°ãªãããŒã¿ã»ããã§ãã¹ãããããããããã¯éåžžã«äŸ¿å©ã§ããäžæ¹ããã®ããŒã¿ã®è¿œå ãåé€ããŸãã¯å€æŽã¯æ倧éã«ç°¡çŽ åãããŸãã
åã®èšäºã§ã JUnitã®æ©èœã調ã¹ãŸããã ãã©ã¡ãŒã¿ãŒåã©ã³ããŒãšçè«ã©ã³ããŒã¯ããã®çš®ã®ã¢ãããŒãã®äŸãšããŠæ©èœããŸããã©ã¡ãã®å Žåãã1ã€ã®ãã¹ãã¯ã©ã¹ã«ã¯ãã©ã¡ãŒã¿ãŒåããããã¹ãã1ã€ã ãå«ããããšãã§ããŸãïŒãã©ã¡ãŒã¿ãŒåãããè€æ°ã®å Žåã¯ããã¹ãŠåãããŒã¿ã䜿çšããŸãïŒã
ãã®èšäºã§ã¯ã TestNGãã¹ããã¬ãŒã ã¯ãŒã¯ã«çŠç¹ãåœãŠãŸãã å€ãã®äººã¯ãã§ã«ãã®ååãèããŠããããã®ååã«åãæ¿ããã®ã§ãJUnitã«æ»ããããããŸããïŒããã¯ä»®å®ã«ãããŸããïŒã
äž»ãªæ©èœ
ããã§ãäœããããŸããïŒ JUnit 4ãšåæ§ã«ããã¹ãã¯æ³šéã䜿çšããŠèšè¿°ãããJUnit 3ã§äœæããããã¹ãããµããŒããããŠããŸãã泚éã®ä»£ããã«ããã¯ã¬ããã䜿çšããããšãã§ããŸãã
ãŸãããã¹ãã®éå±€ãæ€èšããŸãã ãã¹ãŠã®ãã¹ãã¯ä»»æã®ãã¹ãã·ãŒã±ã³ã¹ïŒã¹ã€ãŒãïŒã«å±ããè€æ°ã®ã¯ã©ã¹ãå«ã¿ãŸããåã¯ã©ã¹ã¯è€æ°ã®ãã¹ãã¡ãœããã§æ§æã§ããŸãã ããã«ãã¯ã©ã¹ãšãã¹ãã¡ãœããã¯ç¹å®ã®ã°ã«ãŒãã«å±ããå ŽåããããŸãã ããã¯èŠèŠçã«æ¬¡ã®ããã«ãªããŸãã
+- suite/ +- test0/ | +- class0/ | | +- method0(integration group)/ | | +- method1(functional group)/ | | +- method2/ | +- class1 | +- method3(optional group)/ +- test1/ +- class3(optional group, integration group)/ +- method4/
ãã®éå±€ã®åã¡ã³ããŒã«ã¯ãã³ã³ãã£ã®ã¥ã¬ãŒã¿ãŒã®åãšåŸããããŸãã ãã¹ãŠãã®é åºã§å§ãŸããŸãïŒ
+- before suite/ +- before group/ +- before test/ +- before class/ +- before method/ +- test/ +- after method/ ... +- after class/ ... +- after test/ ... +- after group/ ... +- after suite/
次ã«ããã¹ãèªäœã«ã€ããŠè©³ãã説æããŸãã äŸãèããŠã¿ãŸãããã æååãã解æã§ãããã±ãŒã«ãæäœããåè£ãæ€çŽ¢ããããã®ãŠãŒãã£ãªãã£ïŒ en_US-> en_USãenãroot ïŒïŒ
public abstract class LocaleUtils { /** * Root locale fix for java 1.5 */ public static final Locale ROOT_LOCALE = new Locale(""); private static final String LOCALE_SEPARATOR = "_"; public static Locale parseLocale(final String value) { if (value != null) { final StringTokenizer tokens = new StringTokenizer(value, LOCALE_SEPARATOR); final String language = tokens.hasMoreTokens() ? tokens.nextToken() : ""; final String country = tokens.hasMoreTokens() ? tokens.nextToken() : ""; String variant = ""; String sep = ""; while (tokens.hasMoreTokens()) { variant += sep + tokens.nextToken(); sep = LOCALE_SEPARATOR; } return new Locale(language, country, variant); } return null; } public static List<Locale> getCandidateLocales(final Locale locale) { final List<Locale> locales = new ArrayList<Locale>(); if (locale != null) { final String language = locale.getLanguage(); final String country = locale.getCountry(); final String variant = locale.getVariant(); if (variant.length() > 0) { locales.add(locale); } if (country.length() > 0) { locales.add((locales.size() == 0) ? locale : new Locale(language, country)); } if (language.length() > 0) { locales.add((locales.size() == 0) ? locale : new Locale(language)); } } locales.add(ROOT_LOCALE); return locales; } }
JUnit-aã®ã¹ã¿ã€ã«ã§ãã¹ããäœæããŸãïŒãã®äŸãTestNGã§ãã¹ããäœæããããã®ã¬ã€ããšã¯èŠãªããªãã§ãã ããïŒã
public class LocaleUtilsOldStyleTest extends Assert { private final Map<String, Locale> parseLocaleData = new HashMap<String, Locale>(); @BeforeClass private void setUp() { parseLocaleData.put(null, null); parseLocaleData.put("", LocaleUtils.ROOT_LOCALE); parseLocaleData.put("en", Locale.ENGLISH); parseLocaleData.put("en_US", Locale.US); parseLocaleData.put("en_GB", Locale.UK); parseLocaleData.put("ru", new Locale("ru")); parseLocaleData.put("ru_RU_xxx", new Locale("ru", "RU", "xxx")); } @AfterTest void tearDown() { parseLocaleData.clear(); } @Test public void testParseLocale() { for (Map.Entry<String, Locale> entry : parseLocaleData.entrySet()) { final Locale actual = LocaleUtils.parseLocale(entry.getKey()); final Locale expected = entry.getValue(); assertEquals(actual, expected); } } }
äœããããŸããïŒ
- åã®èšäºã§æ¢ã«è¿°ã¹ãããã«ãç§ã¯Assertãããã¹ãã¯ã©ã¹ãç¶æ¿ããããšã奜ã¿ãŸããããã¯ãéçã€ã³ããŒãããŸãã¯ã¯ã©ã¹ãçŽæ¥äœ¿çšããããšã§çœ®ãæããããšãã§ããŸãïŒ Assert.assertEqualsïŒ...ïŒ ïŒã å®éã®ã·ã¹ãã ã§ã¯ãããã€ãã®åºæ¬ã¯ã©ã¹ãããã¹ããç¶æ¿ããã®ãæã䟿å©ã§ããããã¯ã Assertããç¶æ¿ãããããå¿ èŠãªã¡ãœããããªãŒããŒã©ã€ããŸãã¯è¿œå ã§ããŸãã 泚ïŒJUnitã®åãã¯ã©ã¹ãšã¯ç°ãªããããã§ã¯ããã¹ãŠã®ã¡ãœããã§ãçŸåšã®å€ãæåã«æž¡ããã2çªç®ã«æåŸ ãããŸãïŒJUnitã§ã¯ãã®éïŒã
- ã¢ãããŒã·ã§ã³@BeforeSuite ã @AfterSuiteã¯ããã¹ãŠã®ãã¹ããå®è¡ãããå/åŸã«1åå®è¡ãããã¡ãœããã瀺ããŸãã ãã¹ãŠã®ãã¹ãã«å ±éã®éãèšå®ãé 眮ãããšäŸ¿å©ã§ããããšãã°ãããã§ããŒã¿ããŒã¹ãžã®æ¥ç¶ã®ããŒã«ãäœæã§ããŸãã
- ã¢ãããŒã·ã§ã³@BeforeTest ã @AfterTestã¯ããã¹ãã®ååŸã«äžåºŠå®è¡ãããã¡ãœããã瀺ããŸãïŒãã¹ãã¯ã©ã¹ãå«ãã¡ãœããã¯ããã¹ãã¡ãœãããšæ··åããªãã§ãã ããïŒã ããã§ã¯ãçžäºæ¥ç¶ããããµãŒãã¹ã®ã°ã«ãŒãããŸãã¯è€æ°ã®ãã¹ãã¯ã©ã¹ã§ãã¹ããããŠããå Žåã¯1ã€ã®ãµãŒãã¹ã®èšå®ãä¿åã§ããŸãã
- ã¢ãããŒã·ã§ã³@BeforeClass ã @AfterClassã¯ãã¯ã©ã¹å ã®ãã¹ãŠã®ãã¹ããå®è¡ãããå/åŸã«1åå®è¡ãããã¡ãœããã瀺ãã以åã®ãã¹ããšåãã§ããããã¹ãã¯ã©ã¹ã«é©çšãããŸãã ãã¹ãã®çµæãšããŠç¶æ ãå€åããªãç¹å®ã®ãµãŒãã¹ã®ãã¹ãã«æãé©ããŠããŸãã
- ã¢ãããŒã·ã§ã³@BeforeMethod ã @AfterMethodã¯ããã¹ãã¡ãœãããå®è¡ãããååŸã«æ¯åå®è¡ãããã¡ãœããã瀺ããŸãã ããã§ããã¹ãã®çµæãšããŠç¹å®ã®BeanãŸãã¯ãµãŒãã¹ã®ç¶æ ãå€ãããªãå Žåããã®èšå®ãä¿åããŠãããšäŸ¿å©ã§ãã
- ã¢ãããŒã·ã§ã³@BeforeGroups ã @AfterGroupsã¯ãæå®ãããã°ã«ãŒãã«å±ããæå/æåŸã®ãã¹ãã®ååŸã«å®è¡ãããã¡ãœããã瀺ããŸãã
- @Testã¢ãããŒã·ã§ã³ã¯ããã¹ãèªäœãæããŸãã ãã§ãã¯ã¯ããã«é 眮ãããŸãã ã¯ã©ã¹ã«ãé©çšã§ããŸãã
ãããã®æ³šéã«ã¯ãã¹ãŠã次ã®ãªãã·ã§ã³ããããŸãã
- æå¹-å€ãfalseã«èšå®ããããšã§äžæçã«ç¡å¹ã«ã§ããŸã
- groups-å®è¡ãããã°ã«ãŒãã瀺ããŸã
- inheritGroups-trueã®å ŽåïŒããã©ã«ãã§ã¯ãã®ããã«ïŒãã¡ãœããã¯ãã¹ãã¯ã©ã¹ããã°ã«ãŒããç¶æ¿ããŸã
- timeOut-ã¡ãœããããè±èœãããããã«äŸåãããã¹ãŠã®ãã¹ãããã«ããããŸã§ã®æé
- 説æ-ã¬ããŒãã§äœ¿çšãããåå
- dependOnMethods-äŸåããã¡ãœãããæåã«å®è¡ããã次ã«ãã®ã¡ãœãã
- dependOnGroups-äŸåããã°ã«ãŒã
- alwaysRun-trueã«èšå®ãããšãæå±ããã°ã«ãŒãã«é¢ä¿ãªãåžžã«åŒã³åºããã @ BeforeGroups ã @AfterGroupsã«ã¯é©çšãããŸãã
ãã©ã¡ãŒã¿åããããã¹ã
åããã¹ããå¥ã®æ¹æ³ã§æžããŸãããã
public class LocaleUtilsTest extends Assert { @DataProvider public Object[][] parseLocaleData() { return new Object[][]{ {null, null}, {"", LocaleUtils.ROOT_LOCALE}, {"en", Locale.ENGLISH}, {"en_US", Locale.US}, {"en_GB", Locale.UK}, {"ru", new Locale("ru")}, {"ru_RU_some_variant", new Locale("ru", "RU", "some_variant")}, }; } @Test(dataProvider = "parseLocaleData") public void testParseLocale(String locale, Locale expected) { final Locale actual = LocaleUtils.parseLocale(locale); assertEquals(actual, expected); } }
ãã£ãšç°¡åïŒ ãã¡ãããããŒã¿ã¯ãã¹ãèªäœãšã¯å¥ã«ä¿åãããŸãã 䟿å©ã§ããïŒ ãã¡ãããparseLocaleDataã¡ãœããã«è¡ãè¿œå ããã ãã§ãã¹ããè¿œå ã§ããŸãã
ããã§ã¯ãã©ã®ããã«æ©èœããŸããïŒ
- å ¥åããŒã¿ãæåŸ ãããããŒã¿ãªã©ãå¿ èŠãªãã¹ãŠã®ãã©ã¡ãŒã¿ãŒã䜿çšããŠãã¹ãã¡ãœããã宣èšããŸãã ç§ãã¡ã®å Žåãããã¯ãã±ãŒã«ãšçµæãšããŠäºæããããã±ãŒã«ã«è§£æããå¿ èŠãããæååã§ãã
- ãã¹ãã®ããŒã¿ãŠã§ã¢ããŠã¹ã§ãããããã€ããŒã®æ¥ä»ãçºè¡šããŸãã ããã¯éåžžãç¹å®ã®ãã¹ãã®ãã©ã¡ãŒã¿ãŒã®ãªã¹ããå«ãObject [] []ãŸãã¯Iterator <Object []>ãè¿ãã¡ãœããã§ãïŒäŸïŒ {"en_US"ãLocale.US}ïŒ ã ãã®ã¡ãœããã«ã¯ã @DataProviderã䜿çšããŠæ³šéãä»ããå¿ èŠããããŸãããã¹ãèªäœã§ã¯ã @Test泚éã®dataProviderãã©ã¡ãŒã¿ãŒã䜿çšããŠå®£èšããŸãã ãŸããååïŒãã©ã¡ãŒã¿ãŒå ïŒãæå®ããããšãã§ããŸããã¡ãœããã®ååãæå®ããªãå Žåãã¡ãœããåã䜿çšãããŸãã
å¥ã®äŸã§ã¯ããã¹ãã®ããŒã¿ãšããžãã¯ãç°ãªãã¯ã©ã¹ã«åæ£ããŸãã
public class LocaleUtilsTestData { @DataProvider(name = "getCandidateLocalesData") public static Object[][] getCandidateLocalesData() { return new Object[][]{ {null, Arrays.asList(LocaleUtils.ROOT_LOCALE)}, {LocaleUtils.ROOT_LOCALE, Arrays.asList(LocaleUtils.ROOT_LOCALE)}, {Locale.ENGLISH, Arrays.asList(Locale.ENGLISH, LocaleUtils.ROOT_LOCALE)}, {Locale.US, Arrays.asList(Locale.US, Locale.ENGLISH, LocaleUtils.ROOT_LOCALE)}, {new Locale("en", "US", "xxx"), Arrays.asList( new Locale("en", "US", "xxx"), Locale.US, Locale.ENGLISH, LocaleUtils.ROOT_LOCALE) }, }; } } public class LocaleUtilsTest extends Assert { // other tests @Test(dataProvider = "getCandidateLocalesData", dataProviderClass = LocaleUtilsTestData.class) public void testGetCandidateLocales(Locale locale, List<Locale> expected) { final List<Locale> actual = LocaleUtils.getCandidateLocales(locale); assertEquals(actual, expected); } }
ãã®å Žåããã©ã¡ãŒã¿ãŒdataProviderClassããã³dataProviderãèšå®ãããŸãã ãã¹ãããŒã¿ãè¿ãã¡ãœããã¯éçã§ããå¿ èŠããããŸã ã
äžèšã«å ããŠããã¹ãããã©ã¡ãŒã¿åããå¥ã®æ¹æ³ããããŸãã å¿ èŠãªã¡ãœããã«ã¯ã @Parametersã䜿çšããŠæ³šéãä»ããããå¿ èŠãªãã¹ãŠã®ãã©ã¡ãŒã¿ãŒã®ååã瀺ãããŸãã äžéšã®ãã©ã¡ãŒã¿ãŒã¯ã @ Optionalã䜿çšããŠããã©ã«ãå€ã§æ³šéãä»ããããšãã§ããŸãïŒæå®ããªãå Žåãããªããã£ãã®ããã©ã«ãå€ã䜿çšãããããä»ã®ãã¹ãŠã®ã¿ã€ãã§ã¯nullã«ãªããŸãïŒã ãã©ã¡ãŒã¿ãŒå€ã¯TestNGæ§æã«æ ŒçŽãããŸãïŒããã«ã€ããŠã¯åŸã§èª¬æããŸãïŒã äŸïŒ
public class ParameterizedTest extends Assert { private DataSource dataSource; @Parameters({"driver", "url", "username", "password"}) @BeforeClass public void setUpDataSource(String driver, String url, @Optional("sa") String username, @Optional String password) { // create datasource dataSource = ... } @Test public void testOptionalData() throws SQLException { dataSource.getConnection(); // do some staff } }
ãã®å Žåã setUpDataSourceã¡ãœããã¯ãã©ã¡ãŒã¿ãŒãšããŠããŒã¿ããŒã¹æ¥ç¶èšå®ãåãå ¥ãã ãŠãŒã¶ãŒåãšãã¹ã¯ãŒãã®ãã©ã¡ãŒã¿ãŒã¯ãªãã·ã§ã³ã§ãããæå®ãããããã©ã«ãå€ã䜿çšããŸãã ããšãã°ãããŒã¿ããŒã¹æ¥ç¶ã®ã»ããã¢ããã®äŸã®ããã«ããã¹ãŠã®ãã¹ãïŒãŸãããŸãã¯ã»ãšãã©ãã¹ãŠïŒã«å ±éã®ããŒã¿ã䜿çšãããšéåžžã«äŸ¿å©ã§ãã
ããŠãçµè«ãšããŠããã¹ããåçã«äœæã§ããå·¥å Žã«ã€ããŠãããã€ãã®èšèãèšãå¿ èŠããããŸãã ãã¹ãèªäœãšåæ§ã«ã @DataProviderãŸãã¯@Parametersã䜿çšããŠãã©ã¡ãŒã¿ãŒåã§ããŸãã
public class FactoryTest { @DataProvider public Object[][] tablesData() { return new Object[][] { {"FIRST_TABLE"}, {"SECOND_TABLE"}, {"THIRD_TABLE"}, }; } @Factory(dataProvider = "tablesData") public Object[] createTest(String table) { return new Object[] { new GenericTableTest(table) }; } } public class GenericTableTest extends Assert { private final String table; public GenericTableTest(final String table) { this.table = table; } @Test public void testTable() { System.out.println(table); // do some testing staff here } }
@Parametersã䜿çšãããªãã·ã§ã³ïŒ
public class FactoryTest { @Parameters("table") @Factory public Object[] createParameterizedTest(@Optional("SOME_TABLE") String table) { return new Object[] { new GenericTableTest(table) }; } }
ãã«ãã¹ã¬ãã
ãã«ãã¹ã¬ããç°å¢ã§ã®ã¢ããªã±ãŒã·ã§ã³ã®åäœã確èªããå¿ èŠããããŸããïŒ è€æ°ã®ã¹ã¬ãããããã¹ããåæã«å®è¡ã§ããŸãã
public class ConcurrencyTest extends Assert { private Map<String, String> data; @BeforeClass void setUp() throws Exception { data = new HashMap<String, String>(); } @AfterClass void tearDown() throws Exception { data = null; } @Test(threadPoolSize = 30, invocationCount = 100, invocationTimeOut = 10000) public void testMapOperations() throws Exception { data.put("1", "111"); data.put("2", "111"); data.put("3", "111"); data.put("4", "111"); data.put("5", "111"); data.put("6", "111"); data.put("7", "111"); for (Map.Entry<String, String> entry : data.entrySet()) { System.out.println(entry); } data.clear(); } @Test(singleThreaded = true, invocationCount = 100, invocationTimeOut = 10000) public void testMapOperationsSafe() throws Exception { data.put("1", "111"); data.put("2", "111"); data.put("3", "111"); data.put("4", "111"); data.put("5", "111"); data.put("6", "111"); data.put("7", "111"); for (Map.Entry<String, String> entry : data.entrySet()) { System.out.println(entry); } data.clear(); } }
- threadPoolSizeã¯ããã¹ãã«äœ¿çšãããã¹ã¬ããã®æ倧æ°ã決å®ããŸãã
- singleThreadedãtrueã«èšå®ãããšããã¹ãŠã®ãã¹ããåãã¹ã¬ããã§å®è¡ãããŸãã
- invocationCountã¯ããã¹ãã®å®è¡åæ°ã決å®ããŸãã
- invocationTimeOutã¯ããã¹ãã倱æãããšèŠãªããããŸã§ã®ãã¹ãŠã®ãã¹ãå®è¡ã®åèšæéã決å®ããŸãã
ãããã€ããŒã®æ¥ä»ã®parallelãã©ã¡ãŒã¿ãŒãtrueã«èšå®ãããšãåããŒã¿ã»ããã®ãã¹ããåå¥ã®ã¹ã¬ããã§äžŠè¡ããŠèµ·åãããŸãã
public class ConcurrencyTest extends Assert { // some staff here @DataProvider(parallel = true) public Object[][] concurrencyData() { return new Object[][] { {"1", "2"}, {"3", "4"}, {"5", "6"}, {"7", "8"}, {"9", "10"}, {"11", "12"}, {"13", "14"}, {"15", "16"}, {"17", "18"}, {"19", "20"}, }; } @Test(dataProvider = "concurrencyData") public void testParallelData(String first, String second) { final Thread thread = Thread.currentThread(); System.out.printf("#%d %s: %s : %s", thread.getId(), thread.getName(), first, second); System.out.println(); } }
ãã®ãã¹ãã¯æ¬¡ã®ãããªãã®ãåºåããŸãïŒ
#16 pool-1-thread-3: 5 : 6 #19 pool-1-thread-6: 11 : 12 #14 pool-1-thread-1: 1 : 2 #22 pool-1-thread-9: 17 : 18 #20 pool-1-thread-7: 13 : 14 #18 pool-1-thread-5: 9 : 10 #15 pool-1-thread-2: 3 : 4 #17 pool-1-thread-4: 7 : 8 #21 pool-1-thread-8: 15 : 16 #23 pool-1-thread-10: 19 : 20
ãã®ãã©ã¡ãŒã¿ãŒããªããã°ã次ã®ãããªãã®ã«ãªããŸãã
#1 main: 1 : 2 #1 main: 3 : 4 #1 main: 5 : 6 #1 main: 7 : 8 #1 main: 9 : 10 #1 main: 11 : 12 #1 main: 13 : 14 #1 main: 15 : 16 #1 main: 17 : 18 #1 main: 19 : 20
è¿œå æ©èœ
説æãããŠãããã¹ãŠã«å ããŠãããšãã°ãäŸå€ã®ã¹ããŒããã§ãã¯ãããªã©ãä»ã®å¯èœæ§ããããŸãïŒäžæ£ãªããŒã¿ã®ãã¹ãã«äœ¿çšãããšéåžžã«äŸ¿å©ã§ãïŒã
public class ExceptionTest { @DataProvider public Object[][] wrongData() { return new Object[][] { {"Hello, World!!!"}, {"0x245"}, {"1798237199878129387197238"}, }; } @Test(dataProvider = "wrongData", expectedExceptions = NumberFormatException.class, expectedExceptionsMessageRegExp = "^For input string: \"(.*)\"$") public void testParse(String data) { Integer.parseInt(data); } }
- expectedExceptionsã¯ãäºæãããäŸå€ã®ãªãã·ã§ã³ãèšå®ããŸã;ããããã¹ããŒãããªãå Žåããã¹ãã¯å€±æãããšèŠãªãããŸãã
- expectedExceptionsMessageRegExpã¯åã®ãã©ã¡ãŒã¿ãŒãšåãã§ããããšã©ãŒã¡ãã»ãŒãžã«regexpãèšå®ããŸãã
public class PrioritiesTest extends Assert { private boolean firstTestExecuted; @BeforeClass public void setUp() throws Exception { firstTestExecuted = false; } @Test(priority = 0) public void first() { assertFalse(firstTestExecuted); firstTestExecuted = true; } @Test(priority = 1) public void second() { assertTrue(firstTestExecuted); } }
- åªå 床ã¯ãã¯ã©ã¹å ã®ãã¹ãã®åªå 床ã決å®ããå®è¡ãæ©ãã»ã©å°ãããªããŸãã
ãã¹ãã®äŸåé¢ä¿ãæå®ããå Žåãããšãã°ãã¹ãã«è¿œå ããå Žåããåæ§ã®åäœã芳å¯ãããŸãã
public class PrioritiesTest extends Assert { // some staff @Test(dependsOnMethods = {"first"}) public void third() { assertTrue(firstTestExecuted); } // some staff }
ããã¯éåžžããããã¹ããå¥ã®ãã¹ãã«äŸåããŠããå Žåã«äŸ¿å©ã§ããããšãã°ã Utility1ã¯Utility0ã䜿çšãã Utility0ãæ£ããåäœããªãå Žåã¯Utility1ããã¹ãããæå³ããããŸããã äžæ¹ã @ Before ã @Afterã¡ãœããã§äŸåé¢ä¿ã䜿çšããããšã䟿å©ã§ããç¹ã«ãåºæ¬çãªãã¹ããšç¶æ¿ããããã¹ãããªã³ã¯ããã«ã¯ãã¡ãœããAã倱æãã¡ãœããBãäŸåããŠããå Žåã§ããã¡ãœããBãåŒã³åºãããããšã確èªããå¿ èŠããããŸãã ãã®å Žåã alwaysRunãã©ã¡ãŒã¿ãŒãtrueã«èšå®ããŸãã
äŸåæ§æ³šå ¥
ãè¯ãæ³äººã Guiceã®ãã¬ãŒã ã¯ãŒã¯ã®ãã¡ã³ãåã°ãããã TestNGã«ã¯åŸè ã®ãµããŒããçµã¿èŸŒãŸããŠããŸãã 次ã®ããã«ãªããŸãã
public class GuiceModule extends AbstractModule { @Override protected void configure() { bind(String.class).annotatedWith(Names.named("guice-string-0")).toInstance("Hello, "); } @Named("guice-string-1") @Inject @Singleton @Provides public String provideGuiceString() { return "World!!!"; } } @Guice(modules = {GuiceModule.class}) public class GuiceTest extends Assert { @Inject @Named("guice-string-0") private String word0; @Inject @Named("guice-string-1") private String word1; @Test public void testService() { final String actual = word0 + word1; assertEquals(actual, "Hello, World!!!"); } }
å¿ èŠãªã®ã¯ã @ Guiceã䜿çšããŠå¿ èŠãªã¯ã©ã¹ã«æ³šéãä»ããmodulesãã©ã¡ãŒã¿ãŒã§ãã¹ãŠã®å¿ èŠãªguiceã¢ãžã¥ãŒã«ãæå®ããããšã§ãã ããã«ãã¹ãã¯ã©ã¹ã§ã¯ã @ Injectã䜿çšããŠäŸåé¢ä¿æ³šå ¥ãæ¢ã«äœ¿çšã§ããŸãã
ãŸããä»ã®åæ§ã®ãã¬ãŒã ã¯ãŒã¯ã®ãã¡ã³ã¯åæºããŠã¯ãããªãããšãä»ãå ããŸãã圌ãã¯éåžžãSpringãªã©ã®TestNGãç¬èªã«ãµããŒãããŠããããã§ãã
æ©èœæ¡åŒµ
æ©èœæ¡åŒµã¯ããªã¹ããŒã¡ã«ããºã ã䜿çšããŠå®è£ ã§ããŸãã 次ã®ãªã¹ããŒã¿ã€ãããµããŒããããŠããŸãã
- IAnnotationTransformerãIAnnotationTransformer2-ãã¹ãèšå®ãããšãã°ããã¹ããå®è¡ããã¹ã¬ããã®æ°ãã¿ã€ã ã¢ãŠããäºæãããäŸå€ããªãŒããŒã©ã€ãã§ããŸãã
public class ExpectTransformer implements IAnnotationTransformer { public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) { if (testMethod.getName().startsWith("expect")) { annotation.setExpectedExceptions(new Class[] {Exception.class}); } } }
ãã®äŸã§ã¯ãexpectã§å§ãŸããã¹ãã¡ãœããããäŸå€ãã¹ããŒãããããšãæ³å®ããŠããŸãã - IHookable-ãã¹ãã¡ãœããããªãŒããŒã©ã€ãããããå Žåã«ãã£ãŠã¯ã¹ããããããã§ããŸããTestNGã®ãã¥ãŒããªã¢ã«ã§ã¯ãJAASã®ãµã³ãã«ãæäŸãããŠããŸãã
- IInvokedMethodListenerãIInvokedMethodListener2-åã®ãªã¹ããŒã«äŒŒãŠããŸããããã¹ãã¡ãœããã®å®è¡ååŸã«ã³ãŒããå®è¡ããŸã
- IMethodInterceptor-ãã¹ãã®å®è¡é åºãå€æŽã§ããŸãïŒä»ã®ãã¹ãããç¬ç«ããŠãããã¹ãã«ã®ã¿é©çšå¯èœïŒã ãã¥ãŒããªã¢ã«ã«ã¯è¯ãäŸããããŸãã
- IReporter-ãã¹ãŠã®ãã¹ããå®äºããåŸã«å®è¡ãããæ©èœãæ¡åŒµã§ããŸããéåžžããã®æ©èœã¯ãšã©ãŒã¬ããŒãã®çæãªã©ã«é¢é£ä»ããããŠããŸãã ãããã£ãŠãã¬ããŒããšã³ãžã³ãå®è£ ã§ããŸãã
- ITestListener-ãã¹ãã¡ãœããããã®ã»ãšãã©ã®ã€ãã³ãïŒéå§ãçµäºãæåã倱æãªã©ïŒãåŠçã§ãããªã¹ããŒ
- ISuiteListener-åã®ãã®ãšåæ§ã§ãããã¹ã€ãŒãã®å Žåãéå§ã€ãã³ããšçµäºã€ãã³ãã®ã¿ãåãåããŸã
æ§æ
ããã§ã¯ããã¹ãæ§æã«ç§»ããŸãããã ãã¹ããå®è¡ããæãç°¡åãªæ¹æ³ã¯æ¬¡ã®ãããªãã®ã§ãã
final TestNG testNG = new TestNG(true); testNG.setTestClasses(new Class[] {SuperMegaTest.class}); testNG.setExcludedGroups("optional"); testNG.run();
ããããã»ãšãã©ã®å Žåããã¹ãã®å®è¡ã«ã¯XMLãŸãã¯YAMLæ§æã䜿çšãããŸãã XMLæ§æã¯æ¬¡ã®ããã«ãªããŸãã
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="Test suite" parallel="classes" thread-count="10"> <test name="Default tests" verbose="1" annotations="JDK" thread-count="10" parallel="classes"> <parameter name="driver" value="com.mysql.jdbc.Driver"/> <parameter name="url" value="jdbc:mysql://localhost:3306/db"/> <groups> <run> <exclude name="integration"/> </run> </groups> <packages> <package name="com.example.*"/> </packages> </test> <test name="Integration tests" annotations="JDK"> <groups> <run> <include name="integration"/> </run> </groups> <packages> <package name="com.example.*"/> </packages> </test> </suite>
åæ§ã®YAMLèšå®ïŒ
name: YAML Test suite parallel: classes threadCount: 10 tests: - name: Default tests parameters: driver: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/db excludedGroups: [ integration ] packages: - com.example.* - name: Integration tests parameters: driver: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/db includedGroups: [ integration ] packages: - com.example.*
次ã«ããã¹ããå®è¡ããã«ã¯ã次ãå®è¡ããå¿ èŠããããŸãã
final TestNG testNG = new TestNG(true); //final Parser parser = new Parser("testing/testing-testng/src/test/resources/testng.xml"); final Parser parser = new Parser("testing/testing-testng/src/test/resources/testng.yaml"); final List<XmlSuite> suites = parser.parseToList(); testNG.setXmlSuites(suites); testNG.run();
ãããããããã°ã©ã ã§ãã¹ããå®è¡ããå¿ èŠã¯ãããŸãããã ããã«ã¯IDEã®æ©èœã䜿çšã§ããŸãã
æ§æèªäœã«æ»ããŸãããã æé«ã¬ãã«ã§ã¯ããã¹ãã·ãŒã±ã³ã¹ïŒã¹ã€ãŒãïŒãèšå®ãããŸãã 以äžã®ãã©ã¡ãŒã¿ãŒã䜿çšã§ããŸãã
- name-ã¬ããŒãã§äœ¿çšãããåå
- thread-count-ãã¹ãã®å®è¡ã«äœ¿çšãããã¹ã¬ããã®æ°
- data-provider-thread- count-ããŒã¿ãããã€ããŒãããã©ã¬ã«ããŒã¿ãããã€ããŒã®ãã¹ãèªäœã«ããŒã¿ã転éããããã«äœ¿çšãããã¹ã¬ããã®æ°ïŒ @DataProviderïŒparallel = trueïŒ ïŒ
- parallel-次ã®å€ãåãããšãã§ããŸãïŒ
- ã¡ãœãã-ãã¹ãã¡ãœããã¯ç°ãªãã¹ã¬ããã§å®è¡ãããŸããã¡ãœããéã«äŸåé¢ä¿ãããå Žåã¯æ³šæããå¿ èŠããããŸã
- ã¯ã©ã¹-1ã€ã®ã¹ã¬ããã§ã¯åãã¯ã©ã¹ã®ãã¹ãŠã®ã¡ãœããããã ãç°ãªãã¹ã¬ããã§ã¯ç°ãªãã¯ã©ã¹
- ãã¹ã-1ã€ã®ã¹ã¬ããã§ã®1ã€ã®ãã¹ãã®ãã¹ãŠã®ã¡ãœãããç°ãªãã¹ã¬ããã§ã®ç°ãªããã¹ã
- ã¿ã€ã ã¢ãŠã-ãã¹ãã倱æãããšã¿ãªããããŸã§ã®æéã泚éã®å Žåãšåãã§ããããã¹ãŠã®ãã¹ãã¡ãœããã«é©çšãããŸã
- junit-JUnit 3ãã¹ã
- 泚é-javadocã®å Žåãããã¯ã¬ãããæ§æã«äœ¿çšãããŸã
- parameter- @Parametersã«ãã£ãŠäœ¿çšããããã©ã¡ãŒã¿ãŒ
- packages-ãã¹ãã¯ã©ã¹ãæ¢ãããã±ãŒãž
- ãªã¹ããŒ-ãªã¹ããŒã圌ãã®å©ããåããŠTestNGã®æ©èœãæ¡åŒµããããšãå¯èœã§ãã
- method-selectors-ãã¹ãçšã®ã»ã¬ã¯ã¿ãŒãIMethodSelectorã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ããå¿ èŠããããŸã
- ã¹ã€ãŒããã¡ã€ã«-ä»ã®æ§æãã¡ã€ã«ãå«ããããšãã§ããŸã
<test name="Default tests" verbose="1" annotations="JDK" thread-count="10" parallel="classes"> <!-- some staff here --> <groups> <run> <exclude name="integration"/> </run> </groups> <!-- some staff here --> </test>
ãã®äŸã§ã¯ããã¹ãã«ã¯çµ±åã°ã«ãŒãã®äžéšã§ã¯ãªããã¹ãã®ã¿ãå«ãŸããŸãã
ããã§ããã¹ãã«ã¯ãã¹ãã¯ã©ã¹ãå«ããããšãã§ãããã¹ãã¯ã©ã¹ã«ã¯ãã¹ãã¡ãœãããå«ãã/é€å€ããããšãã§ããŸãã
<test name="Integration tests"> <groups> <run> <include name="integration"/> </run> </groups> <classes> <class name="com.example.PrioritiesTest"> <methods> <exclude name="third"/> </methods> </class> </classes> </test>
ãããã«
ãã®ãã°ããããã¬ãŒã ã¯ãŒã¯ã«ã€ããŠèšããããšã¯ããã ãã§ã¯ãããŸãã; 1ã€ã®èšäºã§ãã¹ãŠãç¶²çŸ ããããšã¯éåžžã«å°é£ã§ãã ããããç§ã¯ãã®äœ¿çšã®äž»ãªãã€ã³ããæããã«ããããšããŸããã ãã¡ãããããã§ã¯ããªã¹ããŒã¡ã«ããºã ãä»ã®ãã¬ãŒã ã¯ãŒã¯ãšã®çµ±åããã¹ãã®æ§æã«ã€ããŠããå°ã話ãããšãã§ããŸããããã®èšäºã¯æ¬ã«å€ããããã¹ãŠãããããŸããã ããããç§ã¯ãã®èšäºã誰ãã«ãšã£ãŠæçšã§ãããèšãããããšã¯TestNGããŸãã¯å°ãªããšããã¹ããæžãããã®DDTãã¯ããã¯ã䜿çšããããã«èªè ãå±ãŸãããšãé¡ã£ãŠããŸãã
ããã§äŸãèŠã€ããããšãã§ããŸã ã