TestCase å±æ§ãªã©ã«ãããã¹ãã³ã¼ãã®ãªãã¡ã¯ã¿ãªã³ã°
æ¨æ¥ã®ãããã¾ã®æ¼ä¼ã¿ã« TDD éå ´ããã£ããã§ããããã¹ãã³ã¼ãã®ãªãã¡ã¯ã¿ãªã³ã°ã«ã¤ãã¦è³å¦ãã£ãã®ã§ã¡ãã£ã¨èªåã®èããã¾ã¨ãã¦ããã¾ãã
ããã«å ããC# 㨠NUnit ã§ã©ã®ããã«ãã¹ãã³ã¼ãããªãã¡ã¯ã¿ãªã³ã°ã§ããããã¨ããã®ãç´¹ä»ãã¾ãã
ã¨ããããã¡ããã¡ã¤ã³ã
ãã¹ãã追å ããéã«è¿½å ãããã¹ãã ããå®è¡ãããå
¨é¨å®è¡ãããã¨ããã®ãæè¦ãåããããã§ããã主ã«åå¥ã«æå®ããã®ãé¢åã¨ããçç±ã§å
¨é¨å®è¡ããæ´¾ã§ãã
å
¨é¨å®è¡ããã¨æéããããï¼ããã¯ãã¯ãåä½ãã¹ããããªãã§ãããéããã¹ãã¯åå²ãã¦åé¢ãã¡ããã¾ãããã
ããã«é¢ãã¦ã¯ã¬ã¬ã·ã¼ã³ã¼ãæ¹åã¬ã¤ã (Object Oriented SELECTION)ãã©ãããæ©ä¼ãããã°ããã辺ã«ã¤ãã¦ãæ¸ãããã¨ããã§ãã
ãã¹ãã³ã¼ãã®ãªãã¡ã¯ã¿ãªã³ã°ã«ã¤ãã¦
ã¾ãããã¹ãã³ã¼ãã®ãªãã¡ã¯ã¿ãªã³ã°ã¯ããã ã¨æãã¾ãã
ã¨ãããããããªãã¨ãããªãã§ãããã
éè¤ãå¤ãæ±ããã¹ãã³ã¼ãã«å¯¾ãã¦æ°ãããã¹ãã®è¿½å ãä¸è¦ãªãã¹ããåé¤ããã®ã¯é¢åã§ãã
ãã¹ãã®è¿½å ãåé¤ãé¢åã«ãªãã¨ããã¹ãããµãã£ã¦ãã¾ãåå ã«ããªã£ã¦ãã¾ãã¾ãã
ãªã®ã§ããã¹ãã³ã¼ãã¯ç¶ºéºã§ããã¹ããªã®ã§ãã
ãã¹ãã³ã¼ãããªãã¡ã¯ã¿ãªã³ã°ãã¾ãããã
ããã§ããªãã¡ã¯ã¿ãªã³ã°ã®å®ç¾©ã確èªãã¦ããã¾ãããã
- ãªãã¡ã¯ã¿ãªã³ã° (åè©)
- å¤é¨ããè¦ãã¨ãã®æ¯ãèããä¿ã¡ã¤ã¤ãç解ãä¿®æ£ãç°¡åã«ãªãããã«ãã½ããã¦ã§ã¢ã®å é¨æ§é ãå¤åããããã¨ã
ãç¥ã
リファクタリング プログラミングの体質改善テクニック (P. 53, 54)
- ãªãã¡ã¯ã¿ãªã³ã° (åè©)
- ä¸é£ã®ãªãã¡ã¯ã¿ãªã³ã°ãè¡ã£ã¦ãå¤é¨ããè¦ãæ¯ãèãã®å¤æ´ãªãã«ãã½ããã¦ã§ã¢ãåæ§ç¯ãããã¨ã
ãã®ããã«ããªãã¡ã¯ã¿ãªã³ã°ã§ã¯å¤é¨ããè¦ãæ¯ãèããéè¦ã§ãã
ã§ã¯ããã¹ãã³ã¼ãã®å¤é¨ããè¦ãæ¯ãèãã¨ã¯ãªãã§ããããï¼
大ãã£ã±ã«è¨ãã¨ããã¹ããæåããã失æããããã§ããã¨æãã¾ãã
ãã¹ãã³ã¼ãã®ãªãã¡ã¯ã¿ãªã³ã°ãããã¹ãããã¹ã¦éã£ã¦ããã¨ãã®ã¿è¡ã£ã¦ãããã¨ããå¶éãä»ããã¨ããã¹ãã³ã¼ããå¤æ´ãã¦ãã©ã®ãã¹ãã失æããªãç¶æ
ãä¿ãããã°ããã¨ãããã¨ã«ãªãã§ããã*1ã
NUnit ã«ãããã¹ãã³ã¼ãã®ãªãã¡ã¯ã¿ãªã³ã°
ãã¦æ¬é¡ã
ä¼å ´ã§ã¯ Test å±æ§ã«ãããã¹ãã§ã確ããããªæãã®ã³ã¼ãã§ããã
// å®éã¯VBã ã£ããã©ãããåãããªã(ãã¨ã«ãªã£ã¦ãã)ã®ã§C#㧠[Test] public void TestFizzBuzz01() { var fizzBuzz = new FizzBuzz(); Assert.AreEqual("1", fizzBuzz.Say(1)); } [Test] public void TestFizzBuzz03() { var fizzBuzz = new FizzBuzz(); Assert.AreEqual("Fizz", fizzBuzz.Say(3)); }
ã§ãããããªãã¡ã¯ã¿ãªã³ã°ãã¦ç¢ºããããã¦ããã¯ãã
FizzBuzz fizzBuzz = new FizzBuzz(); [Test] public void TestFizzBuzz01() { Assert.AreEqual("1", fizzBuzz.Say(1)); } [Test] public void TestFizzBuzz03() { Assert.AreEqual("Fizz", fizzBuzz.Say(3)); }
ä¸é¨éè¤ã¯æ¶ãã¾ãããã©ãããã«æ°ãããã¹ãã追å ããã®ã¯ã¡ãã£ã¨é¢åã§ãããã
TestCase å±æ§ã«ãããªãã¡ã¯ã¿ãªã³ã°
ãã㧠TestCase å±æ§ã®åºçªã§ãããããã¡ããã¾ãããã
[TestCase(1, "1")] [TestCase(3, "Fizz")] public void TestFizzBuzz(int input, string expected) { // å人çãªå好ã«ããAssert.Thatãä½¿ç¨ var fizzBuzz = new FizzBuzz(); Assert.That(fizzBuzz(input), Is.EqualTo(expected)); }
ããã§ããã¹ãã®è¿½å ã»åé¤ã¯æ¥½åã§ãã
[TestCase(1, "1")] [TestCase(3, "Fizz")] [TestCase(5, "Buzz")] public void TestFizzBuzz(int input, string expected) { var fizzBuzz = new FizzBuzz(); Assert.That(fizzBuzz(input), Is.EqualTo(expected)); }
ã§ãããå®éã¯å
¥åãåºåãã³ã³ãã¤ã«æå®æ°ã§ããç¶æ³ã¨ããã®ã¯ãã¾ãããã¾ãã*2ã
ã§ã¯ã©ãããã°ãããããã㧠TestCaseSource å±æ§ã®åºçªã§ãã
TestCaseSource å±æ§ã«ãããªãã¡ã¯ã¿ãªã³ã°ãã® 1
[Test] public void TestFizzBuzz01() { var fizzBuzz = new FizzBuzz(); Assert.That(fizzBuzz.Say(1), Is.EqualTo(new Result("1")); } [Test] public void TestFizzBuzz03() { var fizzBuzz = new FizzBuzz(); Assert.That(fizzBuzz.Say(3), Is.EqualTo(new Fizz()); }
æ£æçãªä¾ã§ãããããã¾ã§ä¾ã¨ãããã¨ã§ãé¡ããã¾ãã
çµæãã³ã³ãã¤ã«æå®æ°ã§ã¯ãªããResult 㨠Fizz ã¨ããå¥ã®å (Result 㨠Fizz ã¯å
±éã®è¦ªãæã¤ããã©ã¡ãããã©ã¡ãããç¶æ¿ãã¦ãã) ã«ãªã£ã¦ãã¾ãã
TestFizzBuzz03 ã
Assert.That(fizzBuzz.Say(3), Is.EqualTo(new Result("Fizz"));
ã®ããã«ãªã£ã¦ããã°ã
[TestCase(1, "1")] public void TestFizzBuzz(int input, string expected) { var fizzBuzz = new FizzBuzz(); Assert.That(fizzBuzz.Say(input), Is.EqualTo(new Result(expected)); }
ã¨ã§ããã®ã§ããã»ã»ã»
ããã§ããã®ä¾ãªããã¹ãã³ã¼ãã§ã¯ãªããããã¯ãã³ã¼ããå¤æ´ããã¨ããæãããã¾ãã
ããããã¾ã§ä¾ã¨è¨ããã¨ã§ä»¥ä¸ç¥ã
ã§ãTestCaseSource å±æ§ã§ããTestCaseSource å±æ§ã使ãã¨ããã®ããã«ãªãã¾ãã
[TestCaseSource("TestCases")] public void TestFizzBuzz(int input, Result expected) { var fizzBuzz = new FizzBuzz(); Assert.That(fizzBuzz.Say(input), Is.EqualTo(expected)); } static object[] TestCases = { new object[] { 1, new Result("1") }, new object[] { 3, new Fizz() }, };
ãã¹ãã追å ããå ´åãTestCases ã«è¿½è¨ããã ãã§ãã
static object[] TestCases = { new object[] { 1, new Result("1") }, new object[] { 3, new Fizz() }, new object[] { 5, new Buzz() }, };
TestCase å±æ§ããå°ã é¢åã«ã¯ãªãã¾ãããããã¹ãã¡ã½ãããå¢ããå ´åã«æ¯ã¹ãã°ã©ãã£ã¦ãã¨ããã¾ããã
TestCaseSource å±æ§ã«ãããªãã¡ã¯ã¿ãªã³ã°ãã® 2
å¼æ°ã 2 ã¤åã TestCaseSource å±æ§ã使ãã¨ããã¹ããæè»ã«è¨è¿°ã§ããããã«ãªãã¾ãã
[TestFixture] class FizzBuzzTest { [TestCaseSource(typeof(FizzBuzzTest), "TestCases")] public Result TestFizzBuzz(int input) { var fizzBuzz = new FizzBuzz(); return fizzBuzz.Say(input); } public static IEnumerable<TestCaseData> TestCases { get { yield return new TestCaseData(1).Returns(new Result("1")); yield return new TestCaseData(3).Returns(new Fizz()); // ç¯å²å¤ã®å¤ã渡ãã¨ä¾å¤ãçºçãããã¨ã確èªãããã¹ã yield return new TestCaseData(0).Throws(typeof(ArgumentOutOfRangeException)); } } }
å¼æ°ã 1 ã¤åããã¼ã¸ã§ã³ã® TestCaseSource å±æ§ããTestCase å±æ§ã§ä¾å¤ãçºçãããã¨ã確èªãããã¹ããè¨è¿°ãããã¨ããå ´åãã©ããã¦ãã¡ã½ãããåããå¿
è¦ãããã¾ã*3 *4ã
ä¾å¤ã®ãã¹ã以å¤ã«ãããã¹ãã®ååãè¨å®ããããã«ãã´ãªãè¨å®ãããã§ãã¾ãã
TestCase å±æ§ãå¼æ°ãä¸ã¤ã ãæå®ãã TestCaseSource å±æ§ããããã¹ãã®è¿½å ãå°ã
é¢åã«ãªãã¾ããããã®æè»æ§ã¯é
åã§ãã
ããã«ãå¯èªæ§åä¸ã®ãããTestCaseData ã®çæé¨åããªãã¡ã¯ã¿ãªã³ã°ãã¦ã¿ã¾ãããã
public static IEnumerable<TestCaseData> TestCases { get { yield return FizzBuzzSay(1).Returns(new Result("1")); yield return FizzBuzzSay(3).Returns(new Fizz()); // ç¯å²å¤ã®å¤ã渡ãã¨ä¾å¤ãçºçãããã¨ã確èªãããã¹ã yield return FizzBuzzSay(0).Throws(typeof(ArgumentOutOfRangeException)); } } static TestCaseData FizzBuzzSay(int input) { return new TestCaseData(input); }
èªã¿ãããããªãã¾ãããã
ãã¹ãã³ã¼ãã®ãªãã¡ã¯ã¿ãªã³ã°ã§ããããã±ã¼ã¹
ãã¹ãã³ã¼ãã®ãªãã¡ã¯ã¿ãªã³ã°ã§ããããã±ã¼ã¹ã¯ã
- ãã¹ãã³ã¼ãèªä½ã®éè¤ã®åé¤ç®ç
- ãã¹ãã³ã¼ãã®å¯èªæ§ã®åä¸ç®ç
- ãã¹ãã«ä½¿ç¨ãããªãã¸ã§ã¯ãã®æ§ç¯ã®éè¤åé¤ç®ç
ã® 3 ã¤ã ã¨æãã¾ãã
ä¸ 2 ã¤ã¯ä¸ã®æ¹æ³ã§ããªãã®é¨åéè¤ãæ¸ãããã¨ãã§ãã¾ããã
ã§ã¯ã3 ã¤ç®ã¯ã©ãã§ãããï¼
3 ã¤ç®ã¯ããªãã¸ã§ã¯ãæ§ç¯ç¨ã®ãã«ãã¯ã©ã¹ããã«ãã¡ã½ãã*5ãä½ã£ã¦ãã¾ãã¾ãããã
ãã®ãã«ãã¯ã©ã¹ããã«ãã¡ã½ããã«å¯¾ãã¦ããã¹ãã³ã¼ããä½ããã¨ããã¯ãããã°ããã§ãããã
ä¾ãã°ãçµæã¨ã㦠XML å½¢å¼ãåºåããå ´åãããããã¹ãã³ã¼ãã«åãè¾¼ãã¨ãã¹ãã³ã¼ããé常ã«è¦ã¥ãããªãã¾ãã
ããã§ãXML æååãçµã¿ç«ã¦ããã«ãã¯ã©ã¹ãä½ã£ã¦ã以ä¸ã®ããã«æ¸ããããã«ãã¾ãã
// <?xml version="1.0" encoding="utf-8"?> // <hoge> // <piyo> // <foo f='foo'> // <bar>hogehoge</bar> // </foo> // </piyo> // <fizz /> // </hoge> Root("hoge").Add("piyo", "foo@f='foo'", "bar;hogehoge") .Add("fizz") .ToString();
ããã¯è¨èªå
DSL ã§ããã
ããã«ããã2 ã¤ç®ã®ãå¯èªæ§ã®åä¸ãéæã§ãã¾ããã
æåã¯ãã¹ãã³ã¼ãç¨ã«ä½ã£ã¦ãããã©ããããããã¯ãã³ã¼ãã§ã便å©ã«ä½¿ãããªãã£ã¦ã¨ãã¯ããããã¯ãã³ã¼ãã«å«ãã¦ãã¾ã£ã¦ãããã§ãããã
*1:ãã®å¶éãä»ããã®ã¯ã失æã®åå ã¯è²ã ã¨èãããããã®éãããå¤é¨ããè¦ãæ¯ãèããã«å«ããã®ãã©ããã¨ããå¾®å¦ãªåé¡ãèããããªãã£ããã
*2:å±æ§ã®å¼æ°ã«ã¯ã³ã³ãã¤ã«æå®æ°ããè¨è¿°ã§ããªã
*3:ãã¹ãã¡ã½ããã®ä¸ã§ if ã§åå²ããã°å¯è½ã ãã©ããã¹ãã³ã¼ãã§ã¯ã§ããéãããã¹ãã§ã¯ãªã
*4:ååä»å¼æ°ã§ã§ããã£ã½ããã©èªã¿ã«ãããªã
*5:ãã«ãããããã£ããã«ããã£ã¼ã«ããªã©ãèãããã