{"id":636,"date":"2009-01-08T19:13:36","date_gmt":"2009-01-08T18:13:36","guid":{"rendered":"http:\/\/www.navision-blog.de\/2009\/01\/08\/how-i-do-continuous-integration-part-3-running-automated-unittests\/"},"modified":"2009-01-08T19:15:12","modified_gmt":"2009-01-08T18:15:12","slug":"how-i-do-continuous-integration-part-3-running-automated-unittests","status":"publish","type":"post","link":"http:\/\/www.navision-blog.de\/blog\/2009\/01\/08\/how-i-do-continuous-integration-part-3-running-automated-unittests\/","title":{"rendered":"How I do Continuous Integration with my C# \/ F# projects &#8211; part III: Running automated UnitTests"},"content":{"rendered":"<p>In the last two posts I showed how to set up a Subversion (<a href=\"http:\/\/www.navision-blog.de\/2009\/01\/08\/how-i-do-continuous-integration-part-i-setting-up-source-control\/\">part I: Setting up Source Control<\/a>) and a TeamCity server (<a href=\"http:\/\/www.navision-blog.de\/2009\/01\/08\/how-i-do-continuous-integration-part-ii-continuous-integration-server\/\">part II: Setting up a Continuous Integration Server<\/a>). <\/p>\n<p>This time I will show how we can integrate <a href=\"http:\/\/www.nunit.org\/index.php\">NUnit<\/a> to run automated test at each build. <em>TeamCity supports all major Testing Frameworks (including MS Test) but I will concentrate on NUnit here.<\/em><\/p>\n<blockquote>\n<p>&quot;NUnit is a unit-testing framework for all .Net languages. Initially ported from <a href=\"http:\/\/www.junit.org\">JUnit<\/a>, the current production release, version 2.4, is the fifth major release of this xUnit based unit testing tool for Microsoft .NET. It is written entirely in C# and has been completely redesigned to take advantage of many .NET language features, for example custom attributes and other reflection related capabilities. NUnit brings xUnit to all .NET languages.&quot;<\/p>\n<p align=\"right\">[<a href=\"http:\/\/www.nunit.org\">product homepage<\/a>] <\/p>\n<\/blockquote>\n<h5>Creating a TestProject<\/h5>\n<p>First of all download and install NUnit 2.4.8 (or higher) from <a title=\"http:\/\/www.nunit.org\/index.php\" href=\"http:\/\/www.nunit.org\/.\">http:\/\/www.nunit.org\/.<\/a><\/p>\n<p>Now we add a small function to our F# source code:<\/p>\n<pre class=\"code\"><span style=\"color: blue\">let rec <\/span>factorial = <span style=\"color: blue\">function  \n  <\/span>| 0 <span style=\"color: blue\">-&gt; <\/span>1\n  | n <span style=\"color: blue\">when <\/span>n &gt; 0 <span style=\"color: blue\">-&gt; <\/span>n * factorial (n-1)\n  | _ <span style=\"color: blue\">-&gt; <\/span>invalid_arg <span style=\"color: maroon\">&quot;Argument not valid&quot;<\/span><\/pre>\n<p>This is the function we want to test. We add a new C# class library to our solution (e.g. \u201cTestCITestLib\u201d \ud83d\ude09 ) and add a reference to <em>nunit.framework<\/em>. Inside this new TestLibrary we add a TestClass with the following code:<\/p>\n<pre class=\"code\"><span style=\"color: blue\">namespace <\/span>TestCITestLib\n{\n    <span style=\"color: blue\">using <\/span>NUnit.Framework;\n\n    [<span style=\"color: #2b91af\">TestFixture<\/span>]\n    <span style=\"color: blue\">public class <\/span><span style=\"color: #2b91af\">FactorialTest\n    <\/span>{\n        [<span style=\"color: #2b91af\">Test<\/span>]\n        <span style=\"color: blue\">public void <\/span>TestFactorial()\n        {\n            <span style=\"color: #2b91af\">Assert<\/span>.AreEqual(1, <span style=\"color: #2b91af\">Program<\/span>.factorial(0));\n            <span style=\"color: #2b91af\">Assert<\/span>.AreEqual(1, <span style=\"color: #2b91af\">Program<\/span>.factorial(1));\n            <span style=\"color: #2b91af\">Assert<\/span>.AreEqual(120, <span style=\"color: #2b91af\">Program<\/span>.factorial(5));\n        }\n\n        [<span style=\"color: #2b91af\">Test<\/span>]\n        <span style=\"color: blue\">public void <\/span>TestFactorialException()\n        {\n            <span style=\"color: #2b91af\">Program<\/span>.factorial(-1);\n        }\n    }\n}<\/pre>\n<p>To ensure the build runner is able to compile our solution we put the nunit.framework.dll near to our TestProject and commit our changes.<\/p>\n<p><img loading=\"lazy\" class=\"bordered\" title=\"Adding Nunit.framework.dll\" style=\"display: inline\" height=\"513\" alt=\"Adding Nunit.framework.dll\" src=\"http:\/\/www.navision-blog.de\/images\/HowIdoContinuousIntegrationwithmyCFproje_F40E\/image.png\" width=\"500\" \/><\/p>\n<h5>Configure TeamCity for UnitTesting<\/h5>\n<p>The next step is to tell TeamCity that the build runner should run our UnitTests:<\/p>\n<p><img loading=\"lazy\" class=\"bordered\" title=\"Configure build runner for NUnit\" style=\"display: inline\" height=\"450\" alt=\"Configure build runner for NUnit\" src=\"http:\/\/www.navision-blog.de\/images\/HowIdoContinuousIntegrationwithmyCFproje_F40E\/image_3.png\" width=\"500\" \/><\/p>\n<p>If we now run the build we should get the following error:<\/p>\n<p><img loading=\"lazy\" class=\"bordered\" title=\"UnitTest error during automated build\" style=\"display: inline\" height=\"188\" alt=\"UnitTest error during automated build\" src=\"http:\/\/www.navision-blog.de\/images\/HowIdoContinuousIntegrationwithmyCFproje_F40E\/image_4.png\" width=\"500\" \/><\/p>\n<p>Our second test function failed, because we didn\u2019t expect the <em>System.ArgumentException<\/em>. We can fix this issue by adding the corresponding attribute to the Testfunction:<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">Test<\/span>,\n <span style=\"color: #2b91af\">ExpectedException<\/span>(<span style=\"color: blue\">typeof<\/span>(System.<span style=\"color: #2b91af\">ArgumentException<\/span>))]\n<span style=\"color: blue\">public void <\/span>TestFactorialException()\n{\n    <span style=\"color: #2b91af\">Program<\/span>.factorial(-1);\n}0<\/pre>\n<p><img loading=\"lazy\" class=\"bordered\" title=\"Tests passed\" style=\"display: inline\" height=\"75\" alt=\"Tests passed\" src=\"http:\/\/www.navision-blog.de\/images\/HowIdoContinuousIntegrationwithmyCFproje_F40E\/image_5.png\" width=\"500\" \/><\/p>\n<h5>Configure the build output<\/h5>\n<p>At this point we have a minimalistic Continuous Integration infrastructure. Every time someone performs a Commit on our repository a automated build will be started and the sources will be tested against the given UnitTests. Now we should concentrate on getting our build output \u2013 the artifacts. The term artifact is usually used to refer to files or directories produced during a build. Examples of such artifacts are:<\/p>\n<ul>\n<li>Binaries (*.exe, *.dll) <\/li>\n<li>Software packages and installers (*.zip, *.msi) <\/li>\n<li>Documentation files (e.g. help files) <\/li>\n<li>Reports (test reports, coverage reports, \u2026) <\/li>\n<\/ul>\n<p>At this time we are only interested in the binaries (this means CITestLib.dll). We can add the following artifact definition to our TeamCity project:<\/p>\n<p><img loading=\"lazy\" class=\"bordered\" title=\"Configure artifacts in TeamCity\" style=\"display: inline\" height=\"293\" alt=\"Configure artifacts in TeamCity\" src=\"http:\/\/www.navision-blog.de\/images\/HowIdoContinuousIntegrationwithmyCFproje_F40E\/image_6.png\" width=\"500\" \/><\/p>\n<p>If we now rebuild our solution the build runner collects the configured artifacts and stores them with all build information:<\/p>\n<p><img loading=\"lazy\" class=\"bordered\" title=\"Collected artifacts\" style=\"display: inline\" height=\"329\" alt=\"Collected artifacts\" src=\"http:\/\/www.navision-blog.de\/images\/HowIdoContinuousIntegrationwithmyCFproje_F40E\/image_7.png\" width=\"500\" \/><\/p>\n<p>Next time I will show how we can add more artifacts \u2013 e.g. an automated documentation.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the last two posts I showed how to set up a Subversion (part I: Setting up Source Control) and a TeamCity server (part II: Setting up a Continuous Integration Server). This time I will show how we can integrate NUnit to run automated test at each build. TeamCity supports all major Testing Frameworks (including [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[12,23,448,29,3],"tags":[492,664,498,500,219,190,499,458,285,174],"_links":{"self":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts\/636"}],"collection":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/comments?post=636"}],"version-history":[{"count":1,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts\/636\/revisions"}],"predecessor-version":[{"id":637,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts\/636\/revisions\/637"}],"wp:attachment":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/media?parent=636"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/categories?post=636"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/tags?post=636"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}