рдЬрд╛рд╡рд╛ рдореЗрдВ рдкрд░реАрдХреНрд╖рдгред рд╕реНрдкреЙрдХ рдлреНрд░реЗрдорд╡рд░реНрдХ


рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ JUnit рдФрд░ TestNG рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦреЛрдВ рдореЗрдВ, рдореИрдВрдиреЗ рдкрд░реАрдХреНрд╖рдг-рд╕рдВрдЪрд╛рд▓рд┐рдд рд╡рд┐рдХрд╛рд╕ (TDD) рдФрд░ рдбреЗрдЯрд╛-рдЪрд╛рд▓рд┐рдд рдкрд░реАрдХреНрд╖рдг (DDT) рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ред рд▓реЗрдХрд┐рди рдПрдХ рдФрд░ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реИ рдЬреЛ рд╕рдХреНрд░рд┐рдп рд░реВрдк рд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдпрддрд╛, рд╡реНрдпрд╡рд╣рд╛рд░-рд╕рдВрдЪрд╛рд▓рд┐рдд рд╡рд┐рдХрд╛рд╕ (рдмреАрдбреАрдбреА) рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣рд╛ рд╣реИред рдпрд╣ рдЯреАрдбреАрдбреА рддрдХрдиреАрдХ рдХрд╛ рдРрд╕рд╛ рд╡рд┐рдХрд╛рд╕ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХреЛ рдХреБрдЫ рд╕рд┐рд╕реНрдЯрдо рдШрдЯрдХреЛрдВ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд░реВрдк рдореЗрдВ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ рджреЗрдЦрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдЯреАрдбреАрдбреА рдкрд░реАрдХреНрд╖рдг рдпрд╛ рд╡рд┐рдзрд┐ рдЬреИрд╕реА рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдмреАрдбреАрдбреА рдХреЗ рд▓рд┐рдП рдпрд╣ рдПрдХ рд╡рд┐рдирд┐рд░реНрджреЗрд╢ рдФрд░ рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ рд╣реИрдВред рдЗрд╕ рддрдХрдиреАрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рд╣рдмреНрд░ рдкрд░ рдкрд╣рд▓реЗ рд╣реА рдмрд╛рдд рдХреА рдЬрд╛ рдЪреБрдХреА рд╣реИ:

рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг JUnit рдФрд░ TestNG рджреЛрдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ BDD рдХреЗ рд▓рд┐рдП рд╕рд┐рд▓рд╡рд╛рдпрд╛ рдЧрдпрд╛ рдЕрдиреНрдп рдЙрдкрдХрд░рдг рд╣реИрдВред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдЗрд╕ рддрд░рд╣ рдХреЗ рдврд╛рдВрдЪреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реВрдВрдЧрд╛ред рдЗрд╕реЗ рд╕реНрдкреЙрдХ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рди рдХреЗрд╡рд▓ рдмреАрдбреАрдбреА рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреЛ рдЬреЛрдбрд╝рддреА рд╣реИ, рдмрд▓реНрдХрд┐ рдЧреНрд░реВрд╡реА рдХреЗ рдлрд╛рдпрджреЗ рднреА рд╣реИрдВред рд╣рд╛рдВ, рд╣рд╛рдВ, рдЧреНрд░реВрд╡реАред рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЧреНрд░реВрд╡реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЬрд╛рд╡рд╛ рдХреЛрдб рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднреА рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрдкрдпреЛрдЧ рдХреЗ рдЙрджрд╛рд╣рд░рдг рд╕реНрдкреНрд░рд┐рдВрдЧ, рдЧреНрд░реЗрд▓реНрд╕, рдЯреЗрдкреЗрд╕реНрдЯреНрд░реА 5 рд╣реИрдВред рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ? рдлрд┐рд░ рдкрдврд╝реЗред


рд╡реНрдпрд╡рд╣рд╛рд░-рд╕рдВрдЪрд╛рд▓рд┐рдд рд╡рд┐рдХрд╛рд╕


рддреЛ, рдореИрдВ рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛рддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рдХреНрдпрд╛ рд╣реИред рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рдХреНрдпрд╛ рдХреЛрдИ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рд╣реИ рдЬреЛ рдЪреАрдВрдЯреА рдкреИрдЯрд░реНрди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреА рд╣реИ (рдпреЗ рдлрд╛рдЗрд▓реЗрдВ рд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИрдВ)? - рдХреЛрдИ 1 рдФрд░ рдХреЗрд╡рд▓ 1 рд╡рд░реНрдг, * - рдХрд┐рд╕реА рднреА рд╡рд░реНрдг рдХреА рдХреЛрдИ рднреА рд╕рдВрдЦреНрдпрд╛, ** - рдХреЛрдИ рднреА рдкрдеред рдпрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

public abstract class PathUtils { public static boolean matchAntPath(final String path, final String pattern) { // ... } public static boolean matchAntPattern(final String path, final String pattern) { // ... } } 

рджреЛрдиреЛрдВ рд╡рд┐рдзрд┐рдпрд╛рдВ рдпрд╣ рдЬрд╛рдВрдЪрддреА рд╣реИрдВ рдХрд┐ рдкрд╛рд░рд┐рдд рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкреИрдЯрд░реНрди рд╕реЗ рдореЗрд▓ рдЦрд╛рддреА рд╣реИ рдпрд╛ рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рдореИрдЪрдЕрдирдЯреИрдВрдЯ рд╡рд┐рдзрд┐ рдХреЗрд╡рд▓ рд╕реНрдерд╛рдиреАрдп рдкреИрдЯрд░реНрди рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдП рдмрд┐рдирд╛ рдкрде рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рддреА рд╣реИ, рдореИрдЪрдСрдирдкреИрде рдкреВрд░рд╛ рд░рд╛рд╕реНрддрд╛ рд▓реЗрддрд╛ рд╣реИред рдЯреАрдбреАрдбреА рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреЗ рдмрд╛рдж, рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд░реАрдХреНрд╖рдг рдЗрдирдкреБрдЯ рдбреЗрдЯрд╛ рдХреЗ рдХреБрдЫ рд╕реЗрдЯ рдФрд░ рдЕрдкреЗрдХреНрд╖рд┐рдд рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рдХреБрдЫ рд╕реЗрдЯ рдХреЗ рд╕рд╛рде рдмрдирд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

 public class TestPathUtils extends Assert { @Test(dataProvider = "matchAntPatternData") public void testMatchAntPattern(final String pattern, final String text, final boolean expected) { final boolean actual = PathUtils.matchAntPattern(text, pattern); assertEquals(actual, expected); } @Test(dataProvider = "matchAntPathData") public void testMatchAntPath(final String pattern, final String path, final boolean expected) { final boolean actual = PathUtils.matchAntPath(path, pattern); assertEquals(actual, expected); } } 

рд╢рд╛рдпрдж рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдлреЗрдВрдХреЗ рдЬрд╛рдиреЗ рдкрд░ рдЧрд▓рдд рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЛ рднреА рдпрд╣рд╛рдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛ред рдЕрдм рдЗрд╕реЗ рдмреАрдбреАрдбреА рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рджреЗрдЦрддреЗ рд╣реИрдВред
рдПрдХ рдкрд░реАрдХреНрд╖рдг рд╕рд┐рд░реНрдл рдПрдХ рдкрд░реАрдХреНрд╖рд╛ рдирд╣реАрдВ рд╣реИ, рдмрд▓реНрдХрд┐ рдПрдХ рд╡рд┐рдирд┐рд░реНрджреЗрд╢ рд╣реИ, рдФрд░ рдЗрд╕рдореЗрдВ рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХрд╛ рд╕рдорд╛рд╡реЗрд╢ рд╣реИред PathUtils рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рд╣рд╛рдЗрд▓рд╛рдЗрдЯ рдХрд░реЗрдВ :

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкреНрд░рддреНрдпреЗрдХ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреА рдЕрдкрдиреА рд╕рддреНрдпрд╛рдкрди рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╣реЛрддреА рд╣реИ, рдЖрдорддреМрд░ рдкрд░ рджреА рдЧрдИ рд╢рд░реНрддреЛрдВ рдХреЛ рдЗрд╕рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рджрд┐рдпрд╛ - рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреА рд╢реБрд░реБрдЖрдд рдХреЗ рд▓рд┐рдП рд╕реЗрдЯрд┐рдВрдЧреНрд╕, рдЬрдм - рдХрд╛рд░рдг, рддрдм - рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд▓рд┐рдП рд╢рд░реНрддред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

 Given: PathUtils --- When: matchAntPattern(null, "some string") --- Then: NullPointerException should be thrown 

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдкрд░реАрдХреНрд╖рдг рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛:

 public class PathUtilsSpec extends Assert { @Test public void question_character_should_mean_any_character() { assertTrue(PathUtils.matchAntPattern("abb", "a?b")); assertTrue(PathUtils.matchAntPattern("a1b", "a?b")); assertTrue(PathUtils.matchAntPattern("a@b", "a?b")); assertTrue(PathUtils.matchAntPath("abb", "a?b")); assertTrue(PathUtils.matchAntPath("a1b", "a?b")); assertTrue(PathUtils.matchAntPath("a@b", "a?b")); // ... } @Test public void question_character_should_mean_only_one_character() { assertFalse(PathUtils.matchAntPattern("ab", "a?b")); assertFalse(PathUtils.matchAntPattern("aabb", "a?b")); assertFalse(PathUtils.matchAntPath("ab", "a?b")); assertFalse(PathUtils.matchAntPath("aabb", "a?b")); // ... } @Test public void asterisk_character_should_mean_any_character() { assertTrue(PathUtils.matchAntPattern("abb", "a*b")); assertTrue(PathUtils.matchAntPattern("a1b", "a*b")); assertTrue(PathUtils.matchAntPattern("a@b", "a*b")); assertTrue(PathUtils.matchAntPath("abb", "a*b")); assertTrue(PathUtils.matchAntPath("a1b", "a*b")); assertTrue(PathUtils.matchAntPath("a@b", "a*b")); // ... } @Test public void asterisk_character_should_mean_any_number_of_characters() { assertTrue(PathUtils.matchAntPattern("ab", "a*b")); assertTrue(PathUtils.matchAntPattern("aabb", "a*b")); assertTrue(PathUtils.matchAntPath("ab", "a*b")); assertTrue(PathUtils.matchAntPath("aabb", "a*b")); // ... } @Test public void double_asterisk_character_should_mean_any_path() { assertTrue(PathUtils.matchAntPath("aaa/bbb", "aaa/**/bbb")); assertTrue(PathUtils.matchAntPath("aaa/ccc/bbb", "aaa/**/bbb")); assertTrue(PathUtils.matchAntPath("aaa/c/c/c/bbb", "aaa/**/bbb")); // ... } } 

рдЕрдм Spock рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХред

рдореБрдЦреНрдп рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ


рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдХрд╣рд╛, рдЧреНрд░реВрд╡реА рдореЗрдВ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓рд┐рдЦреА рдЬрд╛рддреА рд╣реИрдВред рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реИ рдпрд╛ рдмреБрд░рд╛? рдЕрдкрдиреЗ рд▓рд┐рдП рдирд┐рд░реНрдгрдп рд▓реЗрдВ, рд╢реБрд░реБрдЖрддреА 15 рдорд┐рдирдЯ рдореЗрдВ рдЧреНрд░реВрд╡реА рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ - рдПрдХ рддреНрд╡рд░рд┐рдд рдЕрд╡рд▓реЛрдХрди ред

рд╡рд┐рдирд┐рд░реНрджреЗрд╢ рдХреЛ spock.lang.Specification рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕рдореЗрдВ рдлрд╝реАрд▓реНрдбреНрд╕, рдлрд╝рд┐рдХреНрдЪрд░ рдореЗрдердб, рдлреАрдЪрд░ рд╕реНрдХреНрд░рд┐рдкреНрдЯ, рд╣реЗрд▓реНрдкрд░ рдореЗрдердб рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред

рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рдлрд╝реАрд▓реНрдб рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рдмреАрдЪ рд╕рд╛рдЭрд╛ рдирд╣реАрдВ рдХреА рдЬрд╛рддреА рд╣реИрдВ, рдЕрд░реНрдерд╛рдд рдПрдХ рдкрд░рд┐рджреГрд╢реНрдп рд╕реЗ рдлрд╝реАрд▓реНрдб рдкрд░рд┐рд╡рд░реНрддрди рджреВрд╕рд░реЗ рдкрд░рд┐рджреГрд╢реНрдп рд╕реЗ рджрд┐рдЦрд╛рдИ рдирд╣реАрдВ рджреЗрдЧрд╛ред рд╕рд╛рдЭрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк @ рд╢реЗрдбрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдиреЛрдЯреЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рд╕реНрдерд╛рдкрдирд╛ рдХреЗ рддрд░реАрдХреЗ рд╣реИрдВ:

рдЕрдиреНрдп рдкрд░реАрдХреНрд╖рдг рд░реВрдкрд░реЗрдЦрд╛рдУрдВ рдХреА рддрд░рд╣, рдЗрди рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдкреНрд░рддреНрдпреЗрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рдЗрдВрд╕реНрдЯреЙрд▓реЗрд╢рди рдХреЛрдб рд▓рд┐рдЦрдиреЗ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╡рд┐рдирд┐рд░реНрджреЗрд╢ рдХрд╛ рдореБрдЦреНрдп рднрд╛рдЧ рд╣реИред рдпрд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдБ рдШрдЯрдХ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд▓рд┐рдЯрд░рд▓реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЙрдиреНрд╣реЗрдВ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рдерд╛рдЧрдд рд╣реИ, рдФрд░ рдЖрдк рдХрд┐рд╕реА рднреА рд╡рд░реНрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдореБрдЦреНрдп рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдирд╛рдо рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЙрддрдирд╛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреНрдпрд╛ рдХрд░рддреА рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ:

 class PathUtilsSpec extends Specification { def "? character should mean any character"() { // ... } def "? character should mean only one character"() { // ... } def "* character should mean any character"() { // ... } def "* character should mean any number of characters"() { // ... } def "** character should mean any path"() { // ... } } 

рдкреНрд░рддреНрдпреЗрдХ рдкрд░рд┐рджреГрд╢реНрдп рдореЗрдВ рдмреНрд▓реЙрдХ рд╣реЛрддреЗ рд╣реИрдВ, рдЬреЛ рд▓реЗрдмрд▓ рджреНрд╡рд╛рд░рд╛ рдЗрдВрдЧрд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ:

рдЕрдм рд╕рдм рдХреБрдЫ рдФрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗред рдПрдХ рдЕрдиреНрдп рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред PathSearcher , рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛, рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЪреАрдВрдЯреА рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред

 public class PathSearcher { public PathSearcher(final String path) {...} public PathSearcher include(final String... patterns) {...} public PathSearcher exclude(final String... patterns) {...} public Set<String> search() {...} } 

рд╣рдо рдЖрд╡рд╢реНрдпрдХрддрд╛ рд▓рд┐рдЦрддреЗ рд╣реИрдВ "рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдкрд░ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреА рдЦреЛрдЬ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП":

 class PathSearcherSpec extends Specification { def "it should search files under the file system"() { given: def searcher = PathSearcher.create(inClasspath("test1")) when: def results = searcher.search(); then: results.containsAll(["1.txt", "2.txt"]); results.size() == 2 } private String inClasspath(path) { return ClassLoader.getSystemResource(path).toExternalForm() } } 

рддреЛ, рдпрд╣ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ - рдПрдХ рдЦреЛрдЬ рдЗрдВрдЬрди рдЬреЛ рдХреНрд▓рд╛рд╕ 1 рд╕реЗ рдЯреЗрд╕реНрдЯ 1 рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдЦреЛрдЬ рдХрд░рддрд╛ рд╣реИ, рдЦреЛрдЬ, рдирд┐рд╖реНрдкрд╛рджрди рд╕реНрдерд┐рддрд┐ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддрд╛ рд╣реИ - рдЦреЛрдЬ рдЗрдВрдЬрди рдХреЛ рд╣рдорд╛рд░реА рдлрд╛рдЗрд▓реЗрдВ рдвреВрдВрдврдиреА рдЪрд╛рд╣рд┐рдПред inClasspath рдПрдХ рд╕рд╣рд╛рдпрдХ рд╡рд┐рдзрд┐ рд╣реИ рдЬреЛ classpath рд╕реЗ рдирд┐рд░рдкреЗрдХреНрд╖ рдлрд╝рд╛рдЗрд▓ рдкрде рд▓реМрдЯрд╛рддреА рд╣реИред

PathUtils рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдиреНрдп рдЙрджрд╛рд╣рд░рдг "рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рдореВрд▓реНрдп рдФрд░ рдЬрд╛рдБрдЪ рдХреА рдЬрд╛рдиреЗ рд╡рд╛рд▓реА рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдЕрд╢рдХреНрдд рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП"

 class PathUtilsSpec extends Specification { def "null parameter values are not allowed"() { when: PathUtils.matchAntPattern(null, "some string") then: thrown(NullPointerException) when: PathUtils.matchAntPattern("some string", null) then: thrown(NullPointerException) when: PathUtils.matchAntPath(null, "some string") then: thrown(NullPointerException) when: PathUtils.matchAntPath("some string", null) then: thrown(NullPointerException) } } 

рдпрд╣рд╛рдВ рд╣рдо рдлреЗрдВрдХрд╛ рд╣реБрдЖ (...) рддрд░реАрдХрд╛ рджреЗрдЦрддреЗ рд╣реИрдВ, рдпрд╣ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЕрдкрд╡рд╛рдж рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рд╣реИ, рдиреЛрдЯрдЯреНрд░реЙрди (...) рд╡рд┐рдзрд┐ рдФрд░ noExceptionThrown () рднреА рд╣реИ ред рдЙрдиреНрд╣реЗрдВ рдпрд╣ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдирд╛ рд╣реИ рдХрд┐ рдХреЛрдИ рдЕрдкрд╡рд╛рдж рдирд╣реАрдВ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рддрддреНрдХрд╛рд▓реАрди рднрд╛рдЧ рдореЗрдВ, рдирдХрд▓реА рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рддрд░реАрдХреЛрдВ рдХреА рдЕрдкреЗрдХреНрд╖рд╛рдПрдВ рд╣реЛ рд╕рдХрддреА рд╣реИрдВ, рд▓реЗрдХрд┐рди рдмрд╛рдж рдореЗрдВ рдЙрдирдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХред рдПрдХ рдФрд░ рдЙрджрд╛рд╣рд░рдг:

 class PathUtilsSpec extends Specification { def "? character should mean any character"() { expect: PathUtils.matchAntPattern("abb", "a?b") PathUtils.matchAntPattern("a1b", "a?b") PathUtils.matchAntPattern("a@b", "a?b") PathUtils.matchAntPath("abb", "a?b") PathUtils.matchAntPath("a1b", "a?b") PathUtils.matchAntPath("a@b", "a?b") } } 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЙрджрд╛рд╣рд░рдг рд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЕрдЧрд░ рдХрдм рдФрд░ рдлрд┐рд░ рджреЛрдиреЛрдВ рд╣рд┐рд╕реНрд╕реЛрдВ рдХреЛ рдПрдХ рд╣реА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рддреЛ рдЙрдореНрдореАрдж рдмреНрд▓реЙрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред рдЬрд╣рд╛рдБ рдмреНрд▓реЙрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рдкрд░рд┐рдЪрд╛рд▓рдирд╛рддреНрдордХ рдмрдирд╛рдХрд░ рдЗрд╕ рдкрд░рд┐рджреГрд╢реНрдп рдХреЛ рдмреЗрд╣рддрд░ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

 class PathUtilsSpec extends Specification { def "? character should mean any character"() { expect: PathUtils.matchAntPattern(text, pattern) PathUtils.matchAntPath(text, pattern) where: pattern | text "ab?" | "abc" "ab?" | "ab1" "ab?" | "ab@" "a?b" | "abb" "a?b" | "a1b" "a?b" | "a@b" "?ab" | "aab" "?ab" | "1ab" "?ab" | "@ab" } } 

рдпрд╛ рддреЛ:

 class PathUtilsSpec extends Specification { def "? character should mean any character"() { expect: PathUtils.matchAntPattern(text, pattern) PathUtils.matchAntPath(text, pattern) where: pattern << ["ab?", "ab?", "ab?", "a?b", "a?b", "a?b", "?ab", "?ab", "?ab"] text << ["abc", "ab1", "ab@", "abb", "a1b", "a@b", "aab", "1ab", "@ab"] } } 

рдпрд╛ рддреЛ:

 class PathUtilsSpec extends Specification { def "? character should mean any character"() { expect: PathUtils.matchAntPattern(text, pattern) PathUtils.matchAntPath(text, pattern) where: [pattern, text] << [ ["ab?", "abc"], ["ab?", "ab1"], ["ab?", "ab@"], ["a?b", "abb"], ["a?b", "a1b"], ["a?b", "a@b"], ["?ab", "aab"], ["?ab", "1ab"], ["?ab", "@ab"] ] } } 

рдпрд╛ рдЗрд╕ рддрд░рд╣ рднреА:

 class PathUtilsSpec extends Specification { def "? character should mean any character"() { expect: PathUtils.matchAntPattern(text, pattern) PathUtils.matchAntPath(text, pattern) where: [pattern, text] = sql.execute("select pattern, text from path_utils_test") } } 

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЙрджрд╛рд╣рд░рдгреЛрдВ рд╕реЗ рд╕рдм рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЗрд╕ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛ред рдореИрдВ рд╕рд┐рд░реНрдл рдЗрд╕ рдмрд╛рдд рдкрд░ рдзреНрдпрд╛рди рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдЖрдк рдЙрд╕ рдмреНрд▓реЙрдХ рдореЗрдВ рдЙрди рдлрд╝реАрд▓реНрдбреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рдЬреЛ @Sared рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдирд╣реАрдВ рд╣реИрдВред

рдмрд╛рддрдЪреАрдд


рдЕрдиреНрдп рдмрд╛рддреЛрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд░реВрдкрд░реЗрдЦрд╛ рдЖрдкрдХреЛ рдЕрддрд┐рд░рд┐рдХреНрдд рдирд┐рд░реНрднрд░рддрд╛ рдХреЗ рдмрд┐рдирд╛ рдирдХрд▓реА рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред рдЖрдк рдЗрдВрдЯрд░рдлреЗрд╕ рдФрд░ рдЧреИрд░-рдЕрдВрддрд┐рдо рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдореЛрдХрд╛ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рд░рдЪрдирд╛ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддреА рд╣реИ:

  def dao1 = Mock(UserDAO) UserDAO dao2 = Mock() 

рдЖрдк рд░рд┐рдЯрд░реНрди рд╡реИрд▓реНрдпреВ рдпрд╛ рдРрд╕реА рд╡рд╕реНрддреБрдУрдВ рдХреЗ рддрд░реАрдХреЛрдВ рдХреЛ рдЦреБрдж рд╕реЗ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдЦрдХ рдЗрд╕ рдмрд╛рддрдЪреАрдд рдХреЛ рдХрд╣рддреЗ рд╣реИрдВред

  dao1.findAll() >> [ new User(name: "test1", description: "Test User"), new User(name: "test2", description: "Test User"), new User(name: "test3", description: "Test User") ] dao2.findAll() >> { throw new UnsupportedOperationException() } 

рдмрд╛рддрдЪреАрдд рд╕реНрдерд╛рдиреАрдп ( рддрддреНрдХрд╛рд▓реАрди рдмреНрд▓реЙрдХ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд) рдФрд░ рд╡реИрд╢реНрд╡рд┐рдХ (рдЕрдиреНрдпрддреНрд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд) рд╣реИрдВред рд╕реНрдерд╛рдиреАрдп рдХреЗрд╡рд▓ рддрддреНрдХрд╛рд▓реАрди рдмреНрд▓реЙрдХ рдореЗрдВ рдЙрдкрд▓рдмреНрдз рд╣реИрдВ, рд╡реИрд╢реНрд╡рд┐рдХ рд╣рд░ рдЬрдЧрд╣ рдЙрдкрд▓рдмреНрдз рд╣реИрдВ, рдЙрдирдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░ред рд╕реНрдерд╛рдиреАрдп рдЗрдВрдЯрд░реИрдХреНрд╢рди рдХреЗ рд▓рд┐рдП, рдЖрдк рдЙрдирдХреА рд╢рдХреНрддрд┐ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣ рд╡рд┐рдзрд┐ рдХреЙрд▓ рдХреА рдЕрдкреЗрдХреНрд╖рд┐рдд рд╕рдВрдЦреНрдпрд╛ рд╣реИред

 class UserCacheSpec extends Specification { def users = [ new User(name: "test1", description: "Test User"), new User(name: "test2", description: "Test User"), new User(name: "test3", description: "Test User") ] def "dao should be used only once for all user searches until invalidated"() { setup: def dao = Mock(UserDAO) def cache = new UserCacheImpl(dao) when: cache.getUser("test1") cache.getUser("test2") cache.getUser("test3") cache.getUser("test4") then: 1 * dao.findAll() >> users } } 

рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣рдо рдЗрд╕ рдореЙрдХ (рд╕реЗрдЯрдЕрдк рдмреНрд▓реЙрдХ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ UserDAO рдХреЗ рд▓рд┐рдП рдПрдХ рдирдХрд▓реА рдФрд░ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ UserCache рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рддреЗ рд╣реИрдВ ред рдлрд┐рд░ рд╣рдо рдирд╛рдо ( рдЬрдм- рдмреНрд▓реЙрдХ) рдХреЗ рджреНрд╡рд╛рд░рд╛ рдХрдИ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдЦреЛрдЬрддреЗ рд╣реИрдВ рдФрд░ рдЕрдВрдд рдореЗрдВ рдЬрд╛рдБрдЪрддреЗ рд╣реИрдВ рдХрд┐ рдЦреЛрдЬрд╛ рдЧрдпрд╛ рддрд░реАрдХрд╛ рдЬреЛ рддреИрдпрд╛рд░ рдкрд░рд┐рдгрд╛рдо рджреЗрддрд╛ рд╣реИ рдЙрд╕реЗ рдХреЗрд╡рд▓ 1 рдмрд╛рд░ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред
рдмрд╛рддрдЪреАрдд рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реБрдП, рдЖрдк рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

  1 * dao.findAll() >> users (1..4) * dao.findAll() >> users (2.._) * dao.findAll() >> users (_..4) * dao.findAll() >> users _.findAll() >> users dao./find.*/(_) >> users 

рдпрд╣рд╛рдБ рдФрд░ рдкрдврд╝реЗрдВ

рдЕрддрд┐рд░рд┐рдХреНрдд рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдврд╛рдВрдЪреЗ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрд╣реБрдд рд╕рд╛рд░реА рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рд╣реИрдВред рд▓реЗрдХрд┐рди рдЕрдиреНрдп рд░реВрдкрд░реЗрдЦрд╛рдУрдВ рдХреА рддрд░рд╣, рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗ рд╡рд┐рд╕реНрддрд╛рд░ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╣реИрдВ:

 class InternalExtensionsSpec extends Specification { @FailsWith(NumberFormatException) @Unroll("#featureName (#data)") def "integer parse method should throw exception for wrong parameters"() { Integer.parseInt(data) where: data << ["Hello, World!!!", "0x245", "1798237199878129387197238"] } @Ignore @Timeout(3) def "temporary disabled feature"() { setup: sleep(20000) } } 

рдЕрдиреНрдп рдврд╛рдВрдЪреЗ рдХреЗ рд╕рд╛рде рдПрдХреАрдХрд░рдг рдЕрд▓рдЧ-рдЕрд▓рдЧ рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдХрд┐рдП рдЧрдП рд╣реИрдВ:

рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдФрд░ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд, рдЕрдЧрд░ рдЖрдкрдХреЛ рдЕрдкрдиреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЖрдк рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗ рд╡рд┐рд╕реНрддрд╛рд░ рдХреЗ рд▓рд┐рдП рдореБрдЦреНрдп рд╡рд░реНрдЧ:

рдЕрдкрдирд╛ рд╕реНрд╡рдпрдВ рдХрд╛ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдПрдХ IGlobalExtension рдпрд╛ IAnnotationDrivenExtension рд╡рдВрд╢рдЬ рд╡рд░реНрдЧ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдЖрдкрдХреЗ IMethodInterceptor рдХреЛ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╡рд┐рдирд┐рд░реНрджреЗрд╢ рдШрдЯрдХреЛрдВ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдЕрдВрдд рдореЗрдВ , рдореЗрдЯрд╛ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЛ META-INF / Services / org.spockframework.runtime.extension.IGlobal рдореЗрдВ рдЬреЛрдбрд╝ рджреЗрдВред , IAnnotationDrivenExtension рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдПрдиреЛрдЯреЗрд╢рди рдХреЛ @ExtensionAnnotation (extension_class) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдиреЛрдЯреЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдПрдХ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЬреЛ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдХрдИ рдмрд╛рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ:

 @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) @ExtensionAnnotation(RepeatExtension.class) public @interface Repeat { int value() default 1; } public class RepeatExtension extends AbstractAnnotationDrivenExtension<Repeat> { @Override public void visitFeatureAnnotation(Repeat annotation, FeatureInfo feature) { feature.addInterceptor(new RepeatInterceptor(annotation.value())); } } public class RepeatInterceptor extends AbstractMethodInterceptor{ private final int count; public RepeatInterceptor(int count) { this.count = count; } @Override public void interceptFeatureExecution(IMethodInvocation invocation) throws Throwable { for (int i = 0; i < count; i++) { invocation.proceed(); } } } 


 class CustomExtensionsSpec extends Specification { @Repeat(10) def "custom extension"() { expect: Integer.parseInt("123") == 123 } } 


рдкрд░реАрдХреНрд╖рдг рдЪрд▓ рд░рд╣рд╛ рд╣реИ


рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рдХрд┐ рд╕реНрдкреЙрдХ рдкрд░реАрдХреНрд╖рдг JUnit Launcher ( рд╕реНрдкреБрддрдирд┐рдХ ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЪрд▓рд╛рдП рдЬрд╛рддреЗ рд╣реИрдВ, рд╡реЗ рд╡рд┐рднрд┐рдиреНрди рдЖрдИрдбреАрдИ рдХреЗ рддрд╣рдд рдареАрдХ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ (рдЬреИрд╕рд╛ рдХрд┐ рд▓реЗрдЦрдХ рдХрд╣рддреЗ рд╣реИрдВ, рдореИрдВрдиреЗ рдХреЗрд╡рд▓ рд╡рд┐рдЪрд╛рд░ рдХреЗ рддрд╣рдд рдЬрд╛рдВрдЪ рдХреА)ред рдЖрдк рдЪреАрдВрдЯреА, рдорд╛рд╡реЗрди, рдЧреНрд░реЗрдбреЗрд▓ рд╕реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рдкреНрд░рдХреНрд╖реЗрдкрдг рдХреЛ рднреА рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдЬрд╛рдирдХрд╛рд░реА рдпрд╣рд╛рдВ рдкрд╛рдИ рдЬрд╛ рд╕рдХрддреА рд╣реИ ред
рдореИрдВ рдЕрдкрдиреЗ рд▓рд┐рдП рдпрд╣ рдЬреЛрдбрд╝реВрдВрдЧрд╛, рдореИрдВрдиреЗ рдорд╛рд╡реЗрди рдХреЗ рддрд╣рдд рд╡рд┐рдиреНрдпрд╛рд╕ рдХреЛ рдереЛрдбрд╝рд╛ рдмрдврд╝рд╛ рджрд┐рдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рд▓реЗрдЦрдХреЛрдВ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд maven3 рдХреЗ рддрд╣рдд рдХрд╛рдо рдирд╣реАрдВ рдХрд┐рдпрд╛ред рдпрд╣рд╛рдБ рдореЗрд░рд╛ рд╡рд┐рдиреНрдпрд╛рд╕ рд╡рд┐рдХрд▓реНрдк рд╣реИ:

 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.example</groupId> <artifactId>testing-example</artifactId> <version>1.0-SNAPSHOT</version> </parent> <groupId>com.example</groupId> <artifactId>testing-spock</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>Testing Spock Framework Example</name> <description> This is an example application that demonstrates Spock Framework usage. </description> <dependencies> <dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> <version>${groovy-version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.spockframework</groupId> <artifactId>spock-core</artifactId> <version>${spock.version}</version> <scope>test</scope> </dependency> </dependencies> <build> <testResources> <testResource> <directory>src/test/groovy</directory> </testResource> <testResource> <directory>src/test/resources</directory> </testResource> </testResources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <includes> <include>**/*Spec.groovy</include> </includes> </configuration> </plugin> <plugin> <groupId>org.codehaus.gmaven</groupId> <artifactId>gmaven-plugin</artifactId> <version>${gmaven-version}</version> <configuration> <providerSelection>${gmaven-provider}</providerSelection> </configuration> <executions> <execution> <goals> <goal>testCompile</goal> </goals> </execution> </executions> <dependencies> <dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> <version>${groovy-version}</version> </dependency> </dependencies> </plugin> </plugins> </build> <properties> <groovy-version>1.7.10</groovy-version> <gmaven-version>1.3</gmaven-version> <gmaven-provider>1.7</gmaven-provider> <spock.version>0.5-groovy-1.7</spock.version> </properties> </project> 


рдирд┐рд╖реНрдХрд░реНрд╖


рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рдореИрдВ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдЗрд╕ рдЕрджреНрднреБрдд рдврд╛рдВрдЪреЗ рд╕реЗ рдорд┐рд▓рд╛, рдореБрдЭреЗ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдЕрдиреБрднрд╡ рдирд╣реАрдВ рд╣реИ, рдореИрдВ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдХреЗ рд╕рд╛рде рдХрд╣ рд╕рдХрддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рдХреНрд╖рдорддрд╛рдУрдВ рдореЗрдВ рд╣реАрди рдирд╣реАрдВ рд╣реИ, рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдХреБрдЫ рдкрд╣рд▓реБрдУрдВ рдореЗрдВ рдЕрдиреНрдп рд░реВрдкрд░реЗрдЦрд╛рдУрдВ рдХреЛ рдкрд╛рд░ рдХрд░рддрд╛ рд╣реИред рдореБрдЭреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЧреНрд░реВрд╡реА рдкрд░ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрдирд╛ рдкрд╕рдВрдж рдерд╛, рдореБрдЭреЗ рдмреАрдбреАрдбреА рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджреЗрд╢рд┐рдд рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрдирд╛ рдкрд╕рдВрдж рдерд╛ред рдЗрд╕рд▓рд┐рдП, рдореИрдВ рдЖрдкрдХреЛ рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВред

рдЙрджрд╛рд╣рд░рдг рдпрд╣рд╛рдВ рджреЗрдЦреЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ ред

рд╕рд╛рд╣рд┐рддреНрдп


Source: https://habr.com/ru/post/In137561/


All Articles