{"id":106,"date":"2010-10-14T14:10:00","date_gmt":"2010-10-14T13:10:00","guid":{"rendered":"https:\/\/pagan-gerbil.net\/?p=106"},"modified":"2010-10-14T14:10:00","modified_gmt":"2010-10-14T13:10:00","slug":"learning-unit-testing-i-the-basics","status":"publish","type":"post","link":"https:\/\/www.pagan-gerbil.net\/?p=106","title":{"rendered":"Learning Unit Testing I &#8211; The Basics"},"content":{"rendered":"<p>Right, so I\u2019ve chosen my project and I\u2019m ready to begin. I\u2019ll skip past the introduction, straight to page 8 of the rulebook. The characteristics section. This is basically a class layout, nothing too heavy, so I\u2019ll start off by creating Model.cs:<\/p>\n<pre class=\"code\"><span style=\"color: blue\">class <\/span><span style=\"color: #2b91af\">Model\n<\/span>{\n<span style=\"color: blue\">public string <\/span>Name { <span style=\"color: blue\">get<\/span>; <span style=\"color: blue\">set<\/span>; }\n<span style=\"color: blue\">public int <\/span>WeaponSkill { <span style=\"color: blue\">get<\/span>; <span style=\"color: blue\">set<\/span>; }\n<span style=\"color: blue\">public int <\/span>BallisticSkill { <span style=\"color: blue\">get<\/span>; <span style=\"color: blue\">set<\/span>; }\n<span style=\"color: blue\">public int <\/span>Strength { <span style=\"color: blue\">get<\/span>; <span style=\"color: blue\">set<\/span>; }\n<span style=\"color: blue\">public int <\/span>Toughness { <span style=\"color: blue\">get<\/span>; <span style=\"color: blue\">set<\/span>; }\n<span style=\"color: blue\">public int <\/span>Wounds { <span style=\"color: blue\">get<\/span>; <span style=\"color: blue\">set<\/span>; }\n<span style=\"color: blue\">public int <\/span>Initiative { <span style=\"color: blue\">get<\/span>; <span style=\"color: blue\">set<\/span>; }\n<span style=\"color: blue\">public int <\/span>Attacks { <span style=\"color: blue\">get<\/span>; <span style=\"color: blue\">set<\/span>; }\n<span style=\"color: blue\">public int <\/span>Leadership { <span style=\"color: blue\">get<\/span>; <span style=\"color: blue\">set<\/span>; }\n}<\/pre>\n<p><span style=\"font-family: verdana; background-color: #ffffff\">Nothing really testable here yet. No point in testing basic getters and setters.<\/span><\/p>\n<p>Next up is a description of the turn structure \u2013 this calls for a game manager of some sort. How about GameManager.cs, with an enum (TurnPhase)?<\/p>\n<pre class=\"code\"><span style=\"color: blue\">class <\/span><span style=\"color: #2b91af\">GameManager\n<\/span>{\n<span style=\"color: #2b91af\">    TurnPhase <\/span>CurrentPhase { <span style=\"color: blue\">get<\/span>; <span style=\"color: blue\">private set<\/span>; }\n<span style=\"color: blue\">    int <\/span>_numberOfPlayers;\n<span style=\"color: blue\">    int <\/span>_currentPlayersTurn;\n}\n<span style=\"color: blue\">enum <\/span><span style=\"color: #2b91af\">TurnPhase\n<\/span>{\nMovement,\nShooting,\nCloseCombat,\nRecovery\n}<\/pre>\n<p>I think I\u2019ll also add in an integer to GameManager to determine the number of players, and the number of the player whose turn it is. That should be enough to track that for now. To increment the turn onwards, though I\u2019m not sure how that will be triggered yet, I need to add some actual logic! This should have a unit test. In proper TDD fashion, the test will be written first.<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>IncrementTurnPhase_RollsBackToMovementPhaseAfterRecovery()\n{\n<span style=\"color: #2b91af\">GameManager <\/span>manager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">GameManager<\/span>();\nmanager.IncrementPhase(); <span style=\"color: green\">\/\/ Go to Shooting\n<\/span>manager.IncrementPhase(); <span style=\"color: green\">\/\/ Go to Close Combat\n<\/span>manager.IncrementPhase(); <span style=\"color: green\">\/\/ Go to Recovery\n<\/span>manager.IncrementPhase(); <span style=\"color: green\">\/\/ Go back to Movement\n<\/span><span style=\"color: #2b91af\">Assert<\/span>.AreEqual(<span style=\"color: #2b91af\">TurnPhase<\/span>.Movement, manager.CurrentPhase);\n}<\/pre>\n<p>This looks about right \u2013 but I\u2019ll need to give GameManager a bit of a tidy up and make things a little more accessible. Now the code to pass that test:<\/p>\n<pre class=\"code\"><span style=\"color: blue\">public void <\/span>IncrementPhase()\n{\n<span style=\"color: blue\">if <\/span>(CurrentPhase == <span style=\"color: #2b91af\">TurnPhase<\/span>.Recovery)\n{\nCurrentPhase = <span style=\"color: #2b91af\">TurnPhase<\/span>.Movement;\n}\n<span style=\"color: blue\">else\n<\/span>{\nCurrentPhase++;\n}\n}<\/pre>\n<p>That\u2019s nice and neat. But I found that without writing any code in that method, it still passes \u2013 since the turn phase is still Movement. Another test to make sure that it only increments one space will probably be in order.<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>IncrementTurnPhase_MovesForwardPhase()\n{\n<span style=\"color: #2b91af\">GameManager <\/span>manager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">GameManager<\/span>();\n<span style=\"color: #2b91af\">TurnPhase <\/span>firstPhase = manager.CurrentPhase;\nmanager.IncrementPhase(); <span style=\"color: green\">\/\/ Go to Shooting\n<\/span><span style=\"color: #2b91af\">TurnPhase <\/span>secondPhase = manager.CurrentPhase;\n<span style=\"color: #2b91af\">Assert<\/span>.AreNotEqual(firstPhase, secondPhase);\n}<\/pre>\n<p>This one does the trick. Makes sure that the phase has changed within the turn.<\/p>\n<p>Finally, the last couple of paragraphs on page 9 say that control alternates between players. I know from experience that there could easily be multiple players, and I want to be ready for that. So the GameManager will increment _currentPlayersTurn every time the turn finishes (after the Recovery phase), and reset the _currentPlayersTurn integer back to 1 when it exceeds _numberOfPlayers.<\/p>\n<p>Once more, write a test to check that it increments at the end of a turn:<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>IncrementTurnPhase_ChangesPlayerAtEndOfTurn()\n{\n<span style=\"color: #2b91af\">GameManager <\/span>manager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">GameManager<\/span>();\n<span style=\"color: blue\">int <\/span>firstTurn = manager.CurrentPlayersTurn;\nmanager.IncrementPhase(); <span style=\"color: green\">\/\/ Go to Shooting\n<\/span>manager.IncrementPhase(); <span style=\"color: green\">\/\/ Go to Close Combat\n<\/span>manager.IncrementPhase(); <span style=\"color: green\">\/\/ Go to Recovery\n<\/span>manager.IncrementPhase(); <span style=\"color: green\">\/\/ Go back to Movement\n<\/span><span style=\"color: blue\">int <\/span>secondTurn = manager.CurrentPlayersTurn;\n<span style=\"color: #2b91af\">Assert<\/span>.AreNotEqual(firstTurn, secondTurn);\n}<\/pre>\n<p>Now to test the next bit, it\u2019ll be necessary to add a proper constructor with a parameter \u2013 number of players. Here\u2019s the test:<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>IncrementTurnPhase_ReturnsToFirstPlayerAfterAllHaveHadTurn()\n{\n<span style=\"color: #2b91af\">GameManager <\/span>manager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">GameManager<\/span>(2);\nmanager.IncrementPhase(); <span style=\"color: green\">\/\/ Go to Shooting\n<\/span>manager.IncrementPhase(); <span style=\"color: green\">\/\/ Go to Close Combat\n<\/span>manager.IncrementPhase(); <span style=\"color: green\">\/\/ Go to Recovery\n<\/span>manager.IncrementPhase(); <span style=\"color: green\">\/\/ Go back to Movement\n<\/span>manager.IncrementPhase(); <span style=\"color: green\">\/\/ Go to Shooting\n<\/span>manager.IncrementPhase(); <span style=\"color: green\">\/\/ Go to Close Combat\n<\/span>manager.IncrementPhase(); <span style=\"color: green\">\/\/ Go to Recovery\n<\/span>manager.IncrementPhase(); <span style=\"color: green\">\/\/ Go back to Movement\n<\/span><span style=\"color: #2b91af\">Assert<\/span>.AreEqual(1, manager.CurrentPlayersTurn);\n}<\/pre>\n<p>And the code that passes both of those tests:<\/p>\n<pre class=\"code\"><span style=\"color: blue\">public <\/span>GameManager(<span style=\"color: blue\">int <\/span>numberOfPlayers)\n{\nNumberOfPlayers = numberOfPlayers;\nCurrentPlayersTurn = 1;\n}\n<span style=\"color: blue\">public void <\/span>IncrementPhase()\n{\n<span style=\"color: blue\">if <\/span>(CurrentPhase == <span style=\"color: #2b91af\">TurnPhase<\/span>.Recovery)\n{\nCurrentPhase = <span style=\"color: #2b91af\">TurnPhase<\/span>.Movement;\n<span style=\"color: blue\">if <\/span>(CurrentPlayersTurn == NumberOfPlayers)\n{\nCurrentPlayersTurn = 1;\n}\n<span style=\"color: blue\">else\n<\/span>{\nCurrentPlayersTurn++;\n}\n}\n<span style=\"color: blue\">else\n<\/span>{\nCurrentPhase++;\n}\n}<\/pre>\n<p>After adding the requirement for a number of players to the other tests, all the tests so far pass. There is, as I\u2019ve been warned, more test code than real code (67 lines in GameManagerTests compared to 40 in GameManager) but seeing all those little green ticks is definitely a psychological boost. As I\u2019ve neatly finished page 9 and the \u2018Rules\u2019 section, I will start the \u2018Movement\u2019 section next time. This will have a bit more design than the fairly sparse classes here, and a bit more deliberation over where to put particular bits of code. I know a big idea of TDD is to write, then refactor, but I don\u2019t want to do too much refactoring. It could become quite a hassle, especially later in the day. We\u2019ll see when we get there!<\/p>\n<p><em>This is a learning project I am documenting in order to teach myself TDD and unit testing \u2013 as I publish this, I have already written many parts in advance but I want to know what I\u2019m doing wrong! If you see improvements or corrections, either to the code or the process, please leave a comment and let me know! Introduction to this project can be found <a href=\"http:\/\/pagan-gerbil.net\/blog\/post.aspx?id=dfe72ad8-e4e9-48b4-ada3-6247abb5aa71\" target=\"_blank\" rel=\"noopener\">here<\/a>.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Right, so I\u2019ve chosen my project and I\u2019m ready to begin. I\u2019ll skip past the introduction, straight to page 8 of the rulebook. The characteristics section. This is basically a class layout, nothing too heavy, so I\u2019ll start off by creating Model.cs: class Model { public string Name { get; set; } public int WeaponSkill &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.pagan-gerbil.net\/?p=106\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Learning Unit Testing I &#8211; The Basics&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14],"tags":[43,62,63,64],"series":[73],"_links":{"self":[{"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=\/wp\/v2\/posts\/106"}],"collection":[{"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=106"}],"version-history":[{"count":0,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=\/wp\/v2\/posts\/106\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=106"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=106"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=106"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Fseries&post=106"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}