仲éã®ããã°ã©ããŒã«èªåã®ã³ãŒãã«å¯ŸããŠããã«ç°ãªãã»ã«ããã¹ããäœæããããã«å§ãããšã圌ãã¯ãã°ãã°ãããè€éã§éå±ãªä»äºã ãšäžå¹³ãèšãã ãããŠãããã€ãã®ç¹ã§åœŒãã¯æ£ããã å®éãåŸæ¥ã®åäœãã¹ãã䜿çšããå Žåãå€ãã®å Žåãåã
ã®åäœã®ã±ãŒã¹ããã§ãã¯ããããã«å€ãã®ã³ãŒããèšè¿°ããå¿
èŠããããŸãã ã¯ãããã¹ãã®è³ªã¯ãç¹ã«è€éãªã·ã¹ãã ã§ãäºçŽ°ãªãŠãŒã¹ã±ãŒã¹ã倧æåãåãããšããç¹ã«çåãæèµ·ããŸããããã¹ããæžãããšã誰
ãèããŠããªãããè€éãªã·ããªãªã§ã¯ãäžå¿«ãªåé¡ãçºçããŸãã
QuickCheckã§é·ãé䜿çšãããŠãããã¹ãæ¹æ³ã«ã€ããŠèããããšããããŸããããããæ£ããè¡ãã«ã¯æçµçãªããã·ã¥ãååã§ã¯ãããŸããã§ããã ãã®æšé²åã¯ããã®çŽ æŽãããå³æžé€šã®èè
ã§ãããžã§ã³ã»ãã¥ãŒãºããã®
ãã®ãã¬ãŒã³ããŒã·ã§ã³ã§ããã
QuickCheckã¢ãããŒããšã¯
ã¢ãããŒãã®æ¬è³ªã¯éåžžã«ç°¡åã«èª¬æã§ããŸãããã¹ãäŸãäœæããã®ã§ã¯ãªãã
ä»»æã®å
¥åããŒã¿ã«å¯Ÿããã·ã¹ãã ã®åäœã決å®ãã
ã«ãŒã«ãèšå®ã
ãŸã ã ã©ã€ãã©ãªèªäœã¯ãå€æ°ã®ã©ã³ãã ãªå
¥åããŒã¿ãçæããã³ãŒãã®åäœã確ç«ãããã«ãŒã«ã«æºæ ããŠãããã©ããã確èªããŸãã ããã§ãªãå Žåã¯ããã¹ãã®äŸã瀺ãããŸãã
ããã¯ææã§ããïŒ ããªãã
ãããã
åçŽãªbydoprogrammerã¯ãHaskellã§ãErlangã§ããªããããäžè¬çãªèšèªã§æžããŠãã人ã«ããã®å¥è·¡ã«ã©ã®ãããªåŽé¢ããã¢ãããŒãã§ããŸããïŒ ããšãã°ãJavaã§ããã°ã©ãã³ã°ãããšãã®ã»ããå¿«é©ã§ãã é¢ä¿ãããŸããïŒ Googleã¯ãJUnitã«ã¯
JUnit-QuickCheckãšåŒã°ãã察å¿ãããã©ã°ã€ã³ãããããšãã»ãŒå³åº§ã«ç€ºåããŠããŸãã
ããã°ã©ãã³ã°ãžã®æ°ããã¢ãããŒããè©Šãæè¯ã®éžæè¢ã¯ãæ¢ç¥ã®ãã®ãæžãããšã§ãã ã ããç§ã¯
ãããŒãã»ããŒãã£ã³ããå€å
žçãª
çŽ å æ°ã«ã¿ãåã£ãã ç§ã®èšäºãæãäžããåã«ãããã«ãããããç解ããããšããå§ãããŸãã
è¡ãã
ãŸãã空ã®ãããžã§ã¯ããäœæããŸãã XMLãã¡ã€ã«ã®ã·ãŒãã§èªè
ã
飜ããããªãããã«ãããã«ã¯
Gradleã䜿çšããŸãã ããã«ããããããžã§ã¯ãã®èª¬æå
šäœãããã€ãã®è¡ã«åãŸããŸãã
apply plugin: 'java' repositories { mavenCentral() } dependencies { testCompile ( "junit:junit:4.11", "org.hamcrest:hamcrest-all:1.3", "org.junit.contrib:junit-theories:4.11", "com.pholser:junit-quickcheck-core:0.4-beta-1", "com.pholser:junit-quickcheck-generators:0.4-beta-1" ) }
åäžæ¯ã¯ããã§ã¯å¶ç¶ã§ã¯ãããŸããã ããã§JUnitãå¿
èŠãªçç±ã説æããå¿
èŠã¯ãããŸããããæ®ãã®äŸåé¢ä¿ã«ã€ããŠããã€ã説æããŸãã
- Hamcrestã䜿çšããŠãçŸããèªã¿ãããassert-sãèšè¿°ããŸãã
- ãã©ã°ã€ã³ã¯JUnit-Theoriesã®ã¿ã§åäœãããããJUnit-Theoriesãå¿
èŠã§ãïŒJUnitã®çµã¿èŸŒã¿ããŒãžã§ã³ã®Theoryã§äžå¿«ãªãã°ããŸã ä¿®æ£ãããŠããªãããïŒ
- junit-quickcheck-coreãããžã§ã¯ããšjunit-quickcheck-generatorsãããžã§ã¯ãã«ã¯ããã¹ãå€ãçæããããã«çŽæ¥äœ¿çšããã¯ã©ã¹ãå«ãŸããŠããŸãã
TDDã®ååã«åŸã£ãŠãæãåçŽãªçè«ããå§ããŸããããã«ããããã£ãŒãããã¯ã«ãŒããæ©èœããŠããããšããã°ãã確èªã§ããŸãã
import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import com.pholser.junit.quickcheck.ForAll; import org.junit.contrib.theories.Theories; import org.junit.contrib.theories.Theory; import org.junit.runner.RunWith; @RunWith(Theories.class) public class PrimeFactorsTest { @Theory public void allOk(@ForAll Integer number) { assertThat(true, is(true)); } }
ãã®ç°¡åãªããªãã¯ã«ãããæéã倧å¹
ã«ç¯çŽã§ããŸãã TDDã䜿çšããŠãã人ãè€éãªãã¹ããäœæããã®ã«å€ãã®æéãè²»ãããŠããã®ãããèŠãããŸãããæçµçã«å®è¡ãããšãå®å
šã«ç¡é¢ä¿ãªåé¡ãåå ã§æ©èœããªãããšãããããŸãïŒäŸåé¢ä¿ã¯ããŠã³ããŒããç»é²ããããŠããŸããJDKãã€ã³ã¹ããŒã«ããããããžã§ã¯ããæ£ããæ§æãããŠããªããã³ãŒããæ£ããèšè¿°ãããŠããªãããã®ä»ã®å€ãã®ã°ããããšã©ãŒããããŸãïŒã ããã¯åžžã«éåžžã«ã€ã©ã€ã©ããåäœãããªãºã ãæ··ä¹±ãããŸãã ãŸã TDDãè©ŠãããšããŠãããããã®æ°äººã«å¯ŸåŠããããšã¯ç¹ã«å°é£ã§ãã
ãããã£ãŠãç§èªèº«ã¯
åžžã«æãåçŽã§ãæãäºçŽ°ãªãã¢ãããã¯ãªãã¹ãããå§ããŠãåãããšãããããšããå§ãããŸãã ããªãã¯ãã ãããå®è¡ããç§ããããééãããšãã«èŠããã®ããã§ãã¯ãããããèœã¡ããšããèŠãå¿
èŠããããŸãã ããã¯ãç§ã®ã·ã¹ãã ã
æŠéã®æºåãã§ããŠããããšãæå³ããRed-Green-Refactorãµã€ã¯ã«ã劚ãããã®ã¯äœããããŸããã
æåã®äœæ¥çè«
çŽ æ°ãèå¥ããæ¹æ³ã®åé¡ã«ç
©ããããªãããã«ïŒç§ã®ã³ãŒãã¯ãããè¡ãå¿
èŠããããŸãïŒïŒãåã«
æ¢ç¥ã®æ°ãé
åã«æã¡èŸŒã¿ãŸãã æããã«ããªã¹ãã®å¶éã®ããããã¹ãããæ°å€ã®ç¯å²ãå¶éããå¿
èŠããããŸãã ãã®åé¡ã¯åŸã»ã©ä¿®æ£ããŸãã äž»ãªããšã«æ°ãåãããªãããã«ããããã«ãã³ãŒãã«ã€ã³ããŒããèšè¿°ããŸãããã³ãŒãèªäœã«éå®ããŸãã
@Theory public void primeNumberIsItsOwnFactor(@ForAll @InRange(minInt = 1, maxInt = 50) Integer number) { List<Integer> firstPrimeNumbers = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47); assumeThat(number, isIn(firstPrimeNumbers)); List<Integer> factors = PrimeFactors.extract(number); assertThat(factors, hasItem(number)); }
JUnit-QuickCheckãããžã§ã¯ãã®
@ForAll
ããã³
@InRange
ã䜿çšããŠãæå®ãããééã§ä¹±æ°ãèªåçã«çæããŸãã 次ã«ã
assumeThat
é¢æ°ã䜿çšããŠããããããã«ãã£ã«ã¿ãŒåŠçããåŸç¶ã®ã³ãŒããé
åã§æå®ããæ°å€ã§ã®ã¿æ©èœãã
assumeThat
ã«ããŸãã
assumeThat
ãš
assertThat
ã®éãã¯ã次ã®çªå·ããã¹ãã«å€±æããå Žåãæåã®é¢æ°ããã¹ããåæ¢ãïŒæ¬¡ã®äŸã«é²ãïŒã2çªç®ããšã©ãŒãéç¥ããïŒãããŠåŸç¶ã®ãã¹ãŠã®äŸã§ãã¹ããåæ¢ããïŒããšã§ãã ãã¹ãã§ä»®å®ã䜿çšããããšã¯ãæ¡ä»¶åŒã䜿çšããŠå€ããã£ã«ã¿ãªã³ã°ããããšãããæ
£çšçã§ãã
ãã®ãã¹ãã¯æåã«è©²åœããŸããïŒ
extract
ã¡ãœããã®å®è£
ããªãããïŒãä¿®æ£ã¯ç°¡åã§ãã ãã¹ãŠã®ãã¹ãã«åæ Œãããœãªã¥ãŒã·ã§ã³ã¯ç°¡åã§ãã
public class PrimeFactors { public static List<Integer> extract(Integer number) { return Arrays.asList(number); } }
äºåã«é©ãããinãããããªãã§ãã ããã ãã®ã³ãŒã
ã¯ä»æ§ã«åŸã£ãŠå®å
šã«æ©èœ
ãã 50ãè¶
ããªãçŽ æ°ãçŽ å æ°ã«å解ããŸãã ã³ãŒãã«ä»ã®æ°å€ãæäœããæ¹æ³ãæããã«ã¯ãæ°ããçè«ãæžããŠãã ããã
ã¹ã±ã«ãã³ã§èãäœã
æ°ã®èŠå ã®ã»ããã«ã¯ã©ã®ãããªç¹æ§ããããŸããïŒ æããã«ããããã®ç©ã¯æ°ãã®ãã®ãšçãããªããã°ãªããŸããã
@Theory public void productOfFactorsShouldBeEqualToNumber(@ForAll @InRange(minInt = 2, maxInt = 50) Integer number) { List<Integer> factors = PrimeFactors.extract(number); Integer product = 1; for (Integer factor: factors) product = product * factor; assertThat(product, is(number)); }
ãã®çè«ã¯...èœã¡ãŸããïŒ ãããŠå®éãã³ãŒããæ°å€èªäœãè¿ãå Žåãåžžã«ããã§ãã å°ç
ããŠãå¥ã®çè«ãä»åã¯ããæåããŸããã
@Theory public void everyFactorShouldBeSimple(@ForAll @InRange(minInt = 2, maxInt = 50) Integer number) { List<Integer> factors = PrimeFactors.extract(number); assertThat(factors, everyItem(isIn(firstPrimeNumbers))); }
åèŠçŽ ã¯åçŽã§ãªããã°ãªããŸããïŒåçŽãªèŠçŽ ã®ãªã¹ãã«èŒã£ãŠããŸãïŒããã®ãããçè«ã¯å®å®ããŠå®æçã«äœäžãå§ããŸãã ãããŠãããã¯ãŸãã«ç§ãã¡ãå¿
èŠãšãããã®ã§ãã ããšãã°ã次ã®ãšã©ãŒãçºçãããšããŸãã
org.junit.contrib.theories.internal.ParameterizedAssertionError: everyFactorShouldBeSimple("10" <from 10>) at org.junit.contrib.theories.Theories$TheoryAnchor.reportParameterizedError(Theories.java:215) at org.junit.contrib.theories.Theories$TheoryAnchor$1$1.evaluate(Theories.java:169) at org.junit.contrib.theories.Theories$TheoryAnchor.runWithCompleteAssignment(Theories.java:153) at org.junit.contrib.theories.Theories$TheoryAnchor.runWithAssignment(Theories.java:142) ...
ãã®æ°ã®é€æ°ãèŠã€ããããšãã§ããæãç°¡åãªã³ãŒããæžããŸãããã
public class PrimeFactors { public static List<Integer> extract(Integer number) { if (number % 2 == 0) return Arrays.asList(2, number / 2); return Arrays.asList(number); } }
ãã¹ããå床å®è¡ããŸãã ãããã¯ãèŠã€ãã£ãæ°ããå€ã«èªåçã«è©²åœããŸãã
org.junit.contrib.theories.internal.ParameterizedAssertionError: everyFactorShouldBeSimple("15" <from 15>) at org.junit.contrib.theories.Theories$TheoryAnchor.reportParameterizedError(Theories.java:215) at org.junit.contrib.theories.Theories$TheoryAnchor$1$1.evaluate(Theories.java:169) at org.junit.contrib.theories.Theories$TheoryAnchor.runWithCompleteAssignment(Theories.java:153) ...
圌ãããã¯ããŸãããïŒ
public class PrimeFactors { public static List<Integer> extract(Integer number) { if (number % 2 == 0) return Arrays.asList(2, number / 2); if (number % 3 == 0) return Arrays.asList(3, number / 3); return Arrays.asList(number); } }
ãã¹ããäœåºŠãç¹°ãè¿ãå®è¡ããŸããæ°ããå€ãèŠã€ãããã³ã«ãå®è£
ã該åœããŸãã ãã ãããã¹ãã«åæ Œããããã«
çŽ æ°ãè¿ãããšã¯ã§ããŸããã ãããè¡ããšã以åã®çè«ïŒæ°å€ã®ç©ããã§ãã¯ããïŒãç Žç¶»ãå§ããŸãã ãããã£ãŠãæ£ããã¢ã«ãŽãªãºã ã段éçã«å®è£
ããå¿
èŠããããŸãã
åŸã
ã«ïŒãããŠå®éãéåžžã«è¿
éã«ïŒãã®äžé£ã®ãããã³ã°ã¯ãæåã®æ£ãã
決å®ã«ã€ãªãããŸãã
public class PrimeFactors { public static List<Integer> extract(Integer number) { List<Integer> factors = new ArrayList<>(); for (int divisor = 2; divisor <=7; divisor++) { while ((number > divisor) && (number % divisor == 0)) { factors.add(divisor); number = number / divisor; } } factors.add(number); return factors; } }
ãã¡ããããæ£ããå€æããšããèšèã¯
ããã®æ®µéã§ãã¹ãŠã®ãã¹ã
ã«å®å®ããŠåæ Œããããšã ããæå³ããŸãã ãã ããæããã«äžè¬çãªã±ãŒã¹ã«ã¯é©ããŠããŸããã
å°ãäŒæ©ããŠåå°ããå¿
èŠããããŸãã ããèªäœãçŸåšã®ã³ãŒãã®
åäŸãéžæããçè«ã¯ãéåžžã«äŸ¿å©ãªãã®ã§ããããšãå€æããŸããã ã³ãŒããæäœããããã»ã¹ã¯ãé«éã§æ£ç¢ºã§ããªãããŒãªãã³ããæäŸãããããããšã®ãã³ãã³ã«å€ãããŸãã æ°ããäŸã¯ã³ãŒããå£ãããšã«ã€ããŠèããæéãè²»ããå¿
èŠã¯ãããŸããããªããªãããããã¯èªåã§çãŸããããã§ãã 代ããã«ãã¢ã«ãŽãªãºã èªäœã«ã€ããŠã®èãã«å®å
šã«éäžãããããŒã¢ãŒãã§ãããæœãããšãã§ããŸãã ããã¯ãã³ãããã§ãã®
ãããªå€§ããªé£èºãçºçããçç±ã®äžéšã説æããŠããŸãã ããã¯ãäžéã¹ãããã匷åãããŠå®å
šãªã³ãããã圢æããã«ã¯ãã³ãŒããéåžžã«éãçæããããšããã ãã§ãã
ãããŸã§ã®ãšããããã¹ãŠãéåžžã«ã¯ãŒã«ãªããã§ãã ç§ãã¡ã¯
ã»ãã®2ã3ã®çè«ãæžãããããã¯åèªåçã«ç§ãã¡ã®ã¢ã«ãŽãªãºã ãè²ãŠãŸããã ãã®çŸããã§ã¯ãªãã§ããïŒ ãã ãã次ã«äœãèµ·ãããèŠãŠã¿ãŸãããã
ã·ã§ãŒããã³ãããæé·ããæã§ã
幞çŠæã¯åŸã
ã«éããç®ã¯åæ段éã§æ
éã«æåããéãè§ã«æ³šæãæãå§ããŸãã ãã¡ããããã®ã³ãŒãã¯ä»æ§ã«åŸã£ãŠåäœããŸããããã®ä»æ§ã¯2ã50ã®æ°å€ã«å¯ŸããŠã®ã¿å®çŸ©ãããŠããŸãã ãã®ééã§ãããã°ã©ã ãªãã§å®è¡ã§ããŸããé ã®äžã§ãã¹ãŠãæ°ããã ãã§ãã
ç¶ããŸãããã ãã¹ãŠã®çè«ã§äžéã10åäžããŸãïŒ
@Theory public void primeNumberIsItsOwnFactor(@ForAll @InRange(minInt = 2, maxInt = 500) Integer number) { ... } @Theory public void productOfFactorsShouldBeEqualToNumber(@ForAll @InRange(minInt = 2, maxInt = 500) Integer number) { ... } @Theory public void everyFactorShouldBeSimple(@ForAll @InRange(minInt = 2, maxInt = 500) Integer number) { ... }
çªç¶ ãæ°ããåé¡ãçºçããŸããç§ãã¡ã®çè«ã¯ã47ãè¶
ããçŽ æ°ãããããšãèªèããŠããŸããïŒãã£ãšã
ãŠãŒã¯ãªãããç¥ã£ãŠãã人ã¯ããŸããïŒã çŽ æ°ã決å®ããæ°ããæ¹æ³ãèãåºãå¿
èŠããããŸãã
æšæºã®Javaã©ã€ãã©ãªãŒã«ãããå°ãããŸãããŸãïŒãŸãã¯ãã¹ãŠãæ£çŽã§ããïŒïŒããŸãã
æ¢è£œã®ã·ã³ãã«ãªå®è£
ã䜿çšããŸãã ã³ãŒãã®çŸãããšåäžæ§ã«éåããªãããã«ã察å¿ãããããã£ãŒã®åœ¢åŒã§äœæããŸãã
@Theory public void primeNumberIsItsOwnFactor(@ForAll @InRange(minInt = 2, maxInt = 500) Integer number) { assumeThat(number, isProbablySimple()); List<Integer> factors = PrimeFactors.extract(number); assertThat(factors, hasItem(number)); } @Theory public void productOfFactorsShouldBeEqualToNumber(@ForAll @InRange(minInt = 2, maxInt = 500) Integer number) { ... } @Theory public void everyFactorShouldBeSimple(@ForAll @InRange(minInt = 2, maxInt = 500) Integer number) { List<Integer> factors = PrimeFactors.extract(number); assertThat(factors, everyItem(isProbablySimple())); } private Matcher<Integer> isProbablySimple() { return new BaseMatcher<Integer>() { @Override public boolean matches(Object item) { return (item instanceof Integer) && (BigInteger.valueOf((Integer) item).isProbablePrime(5)); } @Override public void describeTo(Description description) { description.appendText("prime number"); } }; }
ããã§ãã³ãŒãã¯å€§ããªæ°å€ã®å解ã«åœãŠã¯ãŸããŸãã ãããä¿®æ£ããæãæ¥ãŸããïŒ
public class PrimeFactors { public static List<Integer> extract(Integer number) { List<Integer> factors = new ArrayList<>(); for (int divisor = 2; divisor <= number; divisor++) { ...
å€ãã«ãŒãå¢çïŒ7ïŒã
number
ã«ä¿®æ£ãããã¹ãŠãåã³æ©èœããããã«æãããŸãã
å°ãã ãæ®ã£ãŠããŸãããã¹ãã®å¢çãããã«åºããçµæã楜ããããã§ãã ãããŠãçªç¶ã®é©ããç§ãã¡ãåŸ
ã£ãŠããŸã...
å³ããçŸå®ã«çŽé¢
çŸå®ã¯
ãã®ãããª
ãã®ã§ãïŒ
@Theory public void primeNumberIsItsOwnFactor(@ForAll @InRange(minInt = 2, maxInt = Integer.MAX_VALUE) Integer number) { ... } @Theory public void productOfFactorsShouldBeEqualToNumber(@ForAll @InRange(minInt = 2, maxInt = Integer.MAX_VALUE) Integer number) { ... } @Theory public void everyFactorShouldBeSimple(@ForAll @InRange(minInt = 2, maxInt = Integer.MAX_VALUE) Integer number) { ... }
ãã¹ãã®äžéã500ãã
Integer.MAX_VALUE
ïŒ2 ^
Integer.MAX_VALUE
ïŒã«å¢ãããšããã«ããã¹ãã
éçŸå®çã«é·ãåäœãå§ããŸããã åãã¹ãã®1åã åé¡ã¯äœã§ããïŒ äœãæªãã®ïŒ
QuickCheckã¹ã¿ã€ã«ã®ãã¹ãã®äºæããªãå¯äœçš
ã¯ããã¹ããããã³ãŒãã®é床ã«å¯Ÿããæ床ã§ã ã ãã ããèããŠã¿ããšãããã¯éåžžã«è«ççã§ããã³ãŒããæé©åãããŠããããå®è¡é床ãé
ãå Žåã100ååŒã³åºããšããã®éæé©æ§ã100åãèŠãããããªããŸãã ãå€å
žçãªãåäœãã¹ãã§ã¯ããã®ã¹ããŒããŠã³ã¯ããã»ã©é¡èã§ã¯ãããŸããããããã§ã¯ãã¹ãŠã®æ å
ã«çŸããŠããŸãã
ã³ãŒãå
ã®ãã©ã°ãèŠã€ããå¿
èŠãããå Žåã¯ã©ãããŸããïŒ 2ã€ã®ãªãã·ã§ã³ããããŸãããããã¡ã€ã©ãŒãæã«åãã枬å®å€ãååŸããã
ã粟æ»ã®æ¹æ³ã§ãšã©ãŒãæ¢ããŸãã
ããããç§ãã¡ã®ã³ãŒãã§ã¯ãç¹å¥ãªããšã¯äœãèŠãŠããŸããããã¹ãŠãèŠããŠããŸãã åé¡ã¯ãç§ãã¡ãããŸãã«ãé·ãéãµã€ã¯ã«ãèµ°ã£ãŠããŠãç¡é§ã«é»æ°ãç¡é§ã«ããŠããããšã§ãã å åå解ã¢ã«ãŽãªãºã ã«ç²ŸéããŠãã人ãªã誰ã§ããäžããããæ°ã®å¹³æ¹æ ¹ãè¶
ããªãå åããã§ãã¯ããã ãã§ååã§ããããšãèŠããŠããŸãã èŠããŠããªã人ã¯ã
ããããããã«è¡ãããšãã§ããŸãã
ä¿®æ£ãé©çšããŸãã ç¹°ãè¿ããŸãããã«ãŒãã®äžéãå€æŽããŸãããä»åã¯
Math.sqrt(number)
ãŸãã
public class PrimeFactors { public static List<Integer> extract(Integer number) { List<Integer> factors = new ArrayList<>(); for (int divisor = 2; divisor <= Math.sqrt(number) + 1; divisor++) { ...
ããã¯äœæ¥ã®çµæã«ã©ã®ããã«åœ±é¿ããŸãããïŒ ãã¹ãã¯åã³è¿
éã«æ©èœãå§ãããã®éãã¯æ¬åœã«å°è±¡çã§ãã
ä»ããã¹ãŠã倧äžå€«ã§ãïŒ ãã¹ãŠã®ãã¹ãã«åæ Œããã³ãŒãã¯ãã£ããããŠããŠãèå³æ·±ãäœéšãåŸãããŸãããHabrã«é¢ããèšäºãæžãæãæ¥ãŸãããïŒ ãããŠãå¥ã®èããç§ã®é ã«å¿ã³èŸŒã¿ãŸã...
ãã¹ãããã¹ããã
åæ¢ãç§ã®å人ãç§ã¯èªåèªèº«ã«èšããããªãã¯ãµã€ã¯ã«ã®å¢çæ¡ä»¶ãæ£ããæžãçããŸãããïŒ æ°å€ã®ã«ãŒãã«1ãè¿œå ããããšã¯æ¬åœã«å¿
èŠã§ããããããšãäžèŠã§ããïŒ
äºçŽ°ãªè³ªåã®ããã§ãã ãããã100ã®ãã¹ãå€ã§å®è¡ããããã¹ãããããŸãïŒ åœŒãã¯ããã§èª°ãééã£ãŠãããã瀺ããŸãã
ã«ãŒãã®å
é ã§ã+1ããæžç®ãïŒ
divisor <= Math.sqrt(number);
ïŒããã¹ããå®è¡ããŸãã
çŽ æŽãããã圌ãã¯éããŸãïŒ
divisor < Math.sqrt(number);
ïŒããã1ã€ãŠããããåã
divisor < Math.sqrt(number);
ã
ãã¹ãã«åã³åæ ŒããŸããïŒ
ãªã«ïŒ
ãããŠãããã§ç§ã¯ããäžåºŠèããªããã°ãªããŸããã§ããã ããã«æªãããšã«ã
public class PrimeFactors { public static List<Integer> extract(Integer number) { List<Integer> factors = new ArrayList<>(); for (int divisor = 2; divisor < Math.sqrt(number) - 2; divisor++) { ...
ç§ã¯æããã«ééã£ãã³ãŒããæžããŸããïŒ9çªã§ãä¹æ°ãèŠã€ãããŸããïŒ
ãããã¹ãã§ã¯ãã¹ãŠãããŸããã£ãŠãããšèšãããŠããŸã ã ç§ã¯ããããåã³éå§ããŸã-圌ãã¯åã³ãã¹ãŠãããŸããã£ãŠãããšèšããŸãã ç§ã¯ããããåã³èµ·åããŸã-äœåºŠãæåããŸãã ãã©ãŒã«ã¯éåžžã«ãŸãã«ããçºçããããã¹ãã§ãšãã©ãçºèŠããã誀ã£ãã¢ã«ãŽãªãºã ã®åäŸã¯ãå°æ¥ã®å®è¡ã®ããã«ä¿åãããŸããã
ãã®ãã¹ãåäœã®çç±ã¯äœã§ããïŒ
ãã¹ãã®å¢çã
Integer.MAX_VALUE
ã«å¢ããããšã§ãããã©ãŒãã³ã¹ã®åé¡ãèŠã€ããŠä¿®æ£ããããšãã§ããŸããããæ°ããnewã«é¥ããŸããã ããªãã¯ã¯ããã¹ãã§ãããã®ç¯å²èšå®ã䜿çšãããšã
ã»ãšãã©ã®å Žåã倧ããªæ°å€ã䜿çšãããããšã§ãïŒååžãåäžã«ååžããããïŒã ãããŠãã³ãŒãã«å°å
¥ãããæ¬ é¥ã¯ãçŽ æ°ã®å¹³æ¹ã«ã®ã¿çŸããŸãïŒèª¬æãå¿
èŠãšããªãããšãé¡ã£ãŠããŸãïŒã
æ®å¿µãªããšã«ãç§ã¯ããå°ãããŒãã
ãŠæ¢åã®ä»æ§ã®
ã³ããŒãäœæãããããæåãããœãªã¥ãŒã·ã§ã³ãæãä»ãããšãã§ããŸããã§ããããåã³çãå¢çç·ã§ã®ã¿ã
@Theory public void everyFactorShouldBeSimple(@ForAll @InRange(minInt = 2, maxInt = Integer.MAX_VALUE) Integer number) { List<Integer> factors = PrimeFactors.extract(number); assertThat(factors, everyItem(isProbablySimple())); } @Theory public void everyFactorShouldBeSimpleEspeciallyForSmallNumbers(@ForAll @InRange(minInt = 2, maxInt = 200) Integer number) { everyFactorShouldBeSimple(number); }
äžåšçšã«èŠããŸãããå°ãªããšããã«ãŒããé§åããã®ã«å¿
èŠãªæ£ç¢ºãªäžéãèŠã€ããããšãã§ããŸãïŒ
divisor <= Math.sqrt(number)
ïŒã
ãã®ïŒäžèŠïŒç°¡åãªäŸã§ãç§ãã¡ã«åºäŒã£ããã¹ãŠã®çºèŠããŸãšããŠãŸãšããŠã¿ãŸãããã
çµæãšããŠäœãåŸãã®ã
ãªãã¿ã®ãªãå°åã§ã®1åã®å®éšã§ããå€ãã®çºèŠããããŸãã QuickCheckã¢ãããŒãã®ãã¹ãŠã®æ©èœã1ã€ã®ãã³ãã«ã«éããŠè©äŸ¡ããããšããŸãã
ã©ã³ããã¯ä»æ§
確ãã«ããã®ãããªããšããããŸãã ç§ã¯3ã€ã®çè«ã®ã¿ãæžããªããã°ãªããããããããã¢ã«ãŽãªãºã ã®1ã€ã®æ©èœããã¹ãããŸããã ããã¯ãæ§ããŒãžã§ã³ã®kataã§çºçãã12åã®åŸæ¥ã®åäœãã¹ããããèããå°ãªãã§ãã ãã®æ©èœã¯ããã®ææ³ã®æ確ãªãã©ã¹ã§èšè¿°ããŸãã
æ€èšŒå¯èœãªããããã£ãæ
éã«çå®ããå¿
èŠæ§
çè«ãããŸãæ©èœããããã«ã¯ãå
¥åãã©ã¡ãŒã¿ãŒã«é¢ããŠäžå€ã§ããæ€èšŒã®ããã®
å®æ§çç¹æ§ã
èãåºããªããã°ãªããŸããã æã«ã¯ããã¯æ¬åœã«è€éã«ãªãããšããããŸãã ãã¹ãã³ãŒãå
ã§ãã¹ãã¢ã«ãŽãªãºã ãå®å
šã«å®è£
ããå¿
èŠãããããã«æããããããããŸããã
äžèšã®äŸã§ã¯ã
isProbablePrime
ã¡ãœããã䜿çšããããšãã§ããŸããã
isProbablePrime
ã¡ãœããã¯ãé«éãã¥ãŒãªã¹ãã£ãã¯ã¢ã«ãŽãªãºã ã䜿çšããŠãç°¡åã«ããããã«çªå·ã
äžæ£ç¢ºã«ãã§ãã¯ããŸãã ãã ãããã®ãããªã¢ã«ãŽãªãºã ãååšããªãå Žåãæ€èšŒãªãã·ã§ã³ã¯ã©ããªããŸããïŒ å®éãå®çŸ©äžãçŽ æ°ã¯é€æ°ã®ãªãæ°ã§ãã ãããŠãæ°ã®åçŽãã確èªããã«ã¯ã
ãããé€æ°ã«
åå²ããå¿
èŠããããŸãã
ããã¯ãããããQuickCheckãã¹ãã§æãé£ããç¬éã§ãã çè«ã§äœ¿çšããããã®åªããäžå€åŒãäœæããããšãããã«é£ããããç解ããã«ã¯ããããªãç 究ãå¿
èŠã§ãã
é
ãã³ãŒãæ床
äžæ¹ã§ãããã¯è¯ãããšã§ãããªããªããã³ãŒããæé©ã§ãªãããšãããã«ç€ºåã§ããããã§ãã äžæ¹ãååãšããŠã³ãŒãã倧å¹
ã«é«éåã§ããªãå Žåã¯ããã¹ãã®é
ãåäœãåãå
¥ãããããã¹ããã©ã¡ãŒã¿ãŒãšããŠäœ¿çšãããã©ã³ãã å€ã®æ°ãæžããå¿
èŠããããŸãã ãŸããã©ã³ãã ãªå€ã®æ°ãæžãããšããã¹ãã«ãã£ãŠã³ãŒãå
ã®æœåšçãªæ¬ é¥ãèŠã€ãããšããèªä¿¡ãé©åãªçšåºŠã«äœäžããŸãã
ãã®çç±ããããšã³ãããŒãšã³ãã®ãã¹ãã«QuickCheckã䜿çšããããšã¯æè¯ã®ã¢ã€ãã¢ã§ã¯ãªããããããªããšãã§ã«æšæž¬ãããšæããŸãã ãã ããæ¬åœã«ããã
å Žåã¯ããè©Šãããšãã§ããŸã ã
å¢çæ¡ä»¶ã®åœ±é¿ãåããªã
ããããããã¯JUnit-QuickCheckã©ã€ãã©ãªã®ç¹å®ã®æ©èœã§ãããä»ã®èšèªã§ã¯ãã®ç¶æ³ã®ã»ããåªããŠããŸãã ãŸãã¯ããã¹ãçšã«éžæããç¹å®ã®äŸã®æ©èœã§ããã ããã§ããããã¯ãã©ã€ãã©ãªãç§ãã¡ã®ããã«æçšã«éžæããã©ã³ãã ãªå€ã«åžžã«è»œãäŸåããã¹ãã§ã¯ãªãããšã瀺ããŠããŸãã ããã§ããé ã䜿ã£ãŠäžçæžåœèããæžãããã³ãŒãã®æ£ç¢ºããå確èªããå¿
èŠããããŸãã
QuickCheckã¯TDDã«ã䜿çšã§ããŸãïŒ
æèŠã¯ç°ãªããŸãããéåžžã«çŸå®çã§ãã çè«ãããå°ãªãïŒãããŠãããããããå€ãã®ã±ãŒã¹ããã¹ãããïŒãšããäºå®ã«ãããå®çšçãªã³ãŒãã«å°ããã¹ãã¡ãœããã®ãã§ãŒã³ãæ§ç¯ããã®ã¯ç°¡åã§ãã äžæ¹ãã³ãŒããæ°ãã«è¿œå ãããçè«ãééãããããã«ããŸãã«ã倧ããªã¹ããããèžãå¿
èŠãããå Žåãããã¯åé¡ã«ãªããŸãã ãããã人ã
ã¯å€å
žçãªTDDã§ãã®ãããªåé¡ã«ééããŸãïŒãããŠãããã解決ããæ¹æ³ãèŠã€ããããåççã«TDDãæãå§ããŸãïŒã
ã³ãŒãããã¹ãããå ŽåãåŸæ¥ã®ãã¹ãã±ãŒã¹ãšQuickCheckã¹ã¿ã€ã«ã®ãã©ã¡ãŒã¿ãŒåãããçè«ã®çµã¿åãããé©åã«æ©èœããå¯èœæ§ããããŸãã ç§ã¯ééããªããã®åéã§ç§ã®ç 究ãç¶ããèå³æ·±ãçºèŠãå
±æããããšããŸãã