{"id":11291,"date":"2016-02-08T21:18:18","date_gmt":"2016-02-08T21:18:18","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/visualstudioalm\/?p=11291"},"modified":"2019-02-14T17:36:21","modified_gmt":"2019-02-15T01:36:21","slug":"parallel-and-context-sensitive-test-execution-with-visual-studio-2015-update-1","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/devops\/parallel-and-context-sensitive-test-execution-with-visual-studio-2015-update-1\/","title":{"rendered":"Parallel and Context Sensitive Test Execution with Visual studio 2015 Update 1"},"content":{"rendered":"<p>(Editors Note:\u00a0 One of the most popular series of blog posts on the ALM Blog was <a href=\"http:\/\/blogs.msdn.com\/b\/dpenorway\/archive\/2016\/01\/17\/visual-studio-2015-update-1-forbedret-ytelse-parallel-unit-testing-og-kontekst-sensitiv-test-eksekvering.aspx\">Terje\u2019s<\/a> posts on Unit Testing.\u00a0 So when he asked to republish his <a href=\"http:\/\/blogs.msdn.com\/b\/dpenorway\/archive\/2016\/01\/17\/visual-studio-2015-update-1-forbedret-ytelse-parallel-unit-testing-og-kontekst-sensitiv-test-eksekvering.aspx\">Norwegian post<\/a> on the ALM blog the answer was of course an enthusiastic <strong>YES!<\/strong>.\u00a0 A little off topic this post also highlights we need a post on executing parallel test runs with the new \u201cRun Functional Test Task\u201d as that paradigm is different using separate machines and \u201ctest containers\u201d (think assemblies))<\/p>\n<p>&nbsp;<\/p>\n<h2>Visual studio 2015 Update 1 : Parallel and Context Sensitive Test Execution<\/h2>\n<p>Visual Studio 2015 Update 1 contains a bunch of improvements and bug fixes.\u00a0 In\u00a0 this post we will have a look at two of the performance improvements, that may give a significant impact on your overall\u00a0 development performance.<\/p>\n<h2>Parallel test execution<\/h2>\n<p>In Visual Studio 2015 Update 1 the test engine can execute test assemblies in parallel.\u00a0\u00a0 This can improve your test performance significantly.\u00a0 This is off by default, so you need to enable it.<\/p>\n<p>The system runs the test assemblies in parallel on as many cores as you specify, and of course, up to the maximum number of cores on your machine.\u00a0 If you only have a single test project you will of course have no benefit of this.\u00a0 This is a solution for the slightly larger projects.<\/p>\n<p>It is independent of the type of test framework you use, and therefore works with both MSTest, <a href=\"https:\/\/www.nuget.org\/packages\/NUnit\/2.6.4\" target=\"_blank\">NUnit 2<\/a>,\u00a0 <a href=\"https:\/\/www.nuget.org\/packages\/NUnit\/\" target=\"_blank\">NUnit 3<\/a> and <a href=\"https:\/\/www.nuget.org\/packages\/xunit\" target=\"_blank\">XUnit<\/a>.<\/p>\n<p>This mechanism is completely independent on whether the underlying framework supports parallelism or not.<\/p>\n<p>To turn on the feature, you must use a runsettings file, which you must enable in Visual Studio.\u00a0 The easy way to get a correct runsettings file in, is to use\u00a0 one of <a href=\"https:\/\/visualstudiogallery.msdn.microsoft.com\/1cc3863b-f15f-4107-bb05-3586fd65540b\" target=\"_blank\">these templates<\/a>, note that you need at least version 3.1 of these.\u00a0 When you have this item extension installed, you have 3 templates, and if you\u2019re just after the parallelism, use the one named Parallel.<\/p>\n<p>Do as follow:<\/p>\n<p>Select Solution, Right click and choose Add\/New item<\/p>\n<p>You will now see a list like the one below:<\/p>\n<p><img decoding=\"async\" src=\"\" alt=\"\" width=\"802\" height=\"194\" \/><\/p>\n<p>Select Parallel and you will see an instance of it under Solution Items in your solution.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/6\/2019\/05\/image_thumb151.png\"><img decoding=\"async\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px\" title=\"image_thumb15\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2016\/02\/image_thumb15_thumb.png\" alt=\"image_thumb15\" width=\"564\" height=\"364\" border=\"0\" \/><\/a><\/p>\n<p>That\u2019s all it takes to enable parallel execution !<\/p>\n<p>Just remember to activate it under the Visual Studio Test menu, do like this:<\/p>\n<p><img decoding=\"async\" src=\"\" alt=\"\" width=\"864\" height=\"380\" \/><\/p>\n<p>(1)\u00a0 Go to\u00a0 Select Test Settings file from the top menu\u00a0 Test\/Test settings.<\/p>\n<p>(2)\u00a0 Then select the wanted Runsettings file,\u00a0 in this case I named it Parallel2.runsettings.<\/p>\n<p>(3) Verify on the same menu that it is selected and checked.<\/p>\n<p>&nbsp;<\/p>\n<h5>The parameters:<\/h5>\n<p>Looking at the content of the runsettings file, we see this:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/6\/2019\/05\/image_thumb51.png\"><img decoding=\"async\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px\" title=\"image_thumb5\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2016\/02\/image_thumb5_thumb.png\" alt=\"image_thumb5\" width=\"867\" height=\"233\" border=\"0\" \/><\/a><\/p>\n<p>There is only one item here we can change, the MaxCpuCount value.\u00a0 It controls how many parallel processes we can run.\u00a0 The value 0 means \u201crun as much as you can, limited by availability of cores on your machine\u201d.\u00a0 The value 1 means it will run sequentially, that is the same as the default with only one process activated.\u00a0 Any other number will limit at that number, or the number of available cores on your machine.<\/p>\n<h5>Why don\u2019t we include Code Coverage?<\/h5>\n<p>You might have noticed that in the description for Parallel it says code coverage is not included. This means that when you activate this runsetting, you will not active code coverage during the same run.\u00a0 The other two templates do exactly that, it doesn\u2019t really give you any benefits.<\/p>\n<p>If you activate the Code Coverage the performance will be reduced, because code coverage also needs to run, and it runs sequentially after the test runs, and will therefore increase the overall time significantly.\u00a0 And, it will not give you anything you really need.<\/p>\n<p>The fact that you don\u2019t active Code Coverage does not imply that you can\u2019t run code coverage from Team Explorer \u2013 you can!\u00a0 Further, the results from this code coverage run is not used in the Test Explorer \u2013 strangely enough.\u00a0\u00a0 The activation done in the two other templates just activate a background code coverage run, which results are just stored in a code coverage result file under the Test Results folder.<\/p>\n<p><img decoding=\"async\" src=\"\" alt=\"\" width=\"901\" height=\"133\" \/><\/p>\n<p>This file doesn\u2019t really give you any benefits in Visual Studio, but is useful if you want these coverage data into another program , one good example is <a href=\"http:\/\/www.ndepend.com\/\" target=\"_blank\">NDepend<\/a>.<\/p>\n<p>One benefit is that this coverage section not only enables the background run of code coverage, but also sets up the <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/jj159530.aspx\" target=\"_blank\">filtering of the code coverage data<\/a>, and this might be interesting for you. These filters will also take effect when you run the Test Explorer \u201cAnalyze code coverage from selected tests\u201d<\/p>\n<p>In the linked article above there is a bunch of settings for code coverage, instead of using these, just use the template CompleteRunSettings, which includes this, plus the other settings.\u00a0 The XML in the linked article is not up to date.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/6\/2019\/05\/image_thumb91.png\"><img decoding=\"async\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px\" title=\"image_thumb9\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2016\/02\/image_thumb9_thumb.png\" alt=\"image_thumb9\" width=\"821\" height=\"304\" border=\"0\" \/><\/a><\/p>\n<p>The templaten CompleteRunsettings has the MaxCpuCount set to 0, it will then run as parallel as possible.<\/p>\n<p>The templaten CoverageNoParallel is nearly identical, with exactly the same fields and settings, except the MaxCpuCount\u00a0 which is set to 1, thus sequential test running.<\/p>\n<p>There is also an <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/jj635153.aspx\" target=\"_blank\">MSDN artikkel<\/a> about configuration of unit tests which are more correct,m but it doesn\u2019t contain bthe same detailed information as the link above.\u00a0 In this however, all fields are explained.<\/p>\n<h2>Test project for parallel runs<\/h2>\n<p>I have made a simple test project for parallel runs.\u00a0\u00a0 It has 4 test projects, with one test each, and each test runs for 5 seconds.\u00a0\u00a0 You can download the source code\u00a0 <a href=\"https:\/\/github.com\/OsirisTerje\/ParallelTestExecutionSample\" target=\"_blank\">from here<\/a>, and then run the tests yourself.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/6\/2019\/05\/SNAGHTML4c90bb3b_thumb3.png\"><img decoding=\"async\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px\" title=\"SNAGHTML4c90bb3b_thumb3\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2016\/02\/SNAGHTML4c90bb3b_thumb3_thumb.png\" alt=\"SNAGHTML4c90bb3b_thumb3\" width=\"750\" height=\"719\" border=\"0\" \/><\/a><\/p>\n<p>(1)\u00a0 Running without settings at all. It is then runs sequentially, and we see the total time is 26 seconds.\u00a0 Since each test uses 5 seconds we have a 6 seconds overhead.<\/p>\n<p>(2) Running with CodeCoverageNoParallel, which is identical to the old runsettings file, we will, get code coverage run in addition, but no parallel runs.\u00a0 The total time increases to 31 seconds.<\/p>\n<p>(3) We then uses the complete settings, using both CodeCoverage and Parallel.\u00a0 The total time then decreases to 18 seconds.<\/p>\n<p>(4) And finally using only Parallel without code coverage, we\u2019re down in 12 seconds.<\/p>\n<p>So from (4) to (1), we gain more than a 2:1 in performance.\u00a0 That is pretty good!<\/p>\n<p>The machine this was tested on has more cores \u2013 8 in all, but it also runs a bunch of other programs, so not all cores can be made available for the testing processes.\u00a0 You will gain some, but not equal to the number of cores \u2013 in practice.\u00a0 Anyway, a gain of 2:1 is pretty good and pretty significant in your daily work.<\/p>\n<h5>Parallel on build server<\/h5>\n<p>Does this work on a build server?\u00a0 The answer is Yes, in a build definition you can define which runsettingfile to run, so this will also have an effect on the build server run.\u00a0 But, do you really want that?\u00a0\u00a0 That all depends on how you many build servers you have, how they are configured, and how many check-ins\/commits you have.\u00a0\u00a0 That si, how loaded your build servers are.\u00a0 Normally you set up a build agent to run one per core on the machine.\u00a0 If you have many build definitions and many commits\/Checkins happening continuously during the day, the build agents will be pretty busy., then there will be little benefit in setting up the tests to run in parallel in addition, as they will \u201csteal\u201d cores from the other builds.\u00a0\u00a0 There can also be an overhead that eat up all your gain.<\/p>\n<p>If you, on the other hand, have a builds machine that is not that much loaded, and not so many commits continuously, then by all means \u2013 why not?\u00a0 Grab the extra performance by running your tests in parallel.<\/p>\n<p>There are also other ways to run in parallel, see <a href=\"http:\/\/blogs.msdn.com\/b\/visualstudioalm\/archive\/2015\/07\/30\/speeding-up-test-execution-in-tfs.aspx\" target=\"_blank\">this article<\/a> for a different approach.<\/p>\n<h2>Context sensitive test execution<\/h2>\n<p>Context sensitive test execution is new in Update 1 \u2013 so what is that?\u00a0\u00a0 Under given circumstances, the new Test Explorer will only test the assemblies that it detects tests code that you have changed.<\/p>\n<p>This means that if you work with a certain piece of code in a given module of your system,\u00a0 and your code is distributed over multiple modules, then for each build, only the code that you changes is being build. That is the normal incremental build which is by default.\u00a0 New is that also only the tests touching this code is being run, and then not the tests for code that has not been touched.\u00a0 It is pretty obvious that for larger systems this can mean a pretty dramatic speedup in the test run performance.<\/p>\n<p>There is one condition for this to work:\u00a0 You must activate \u201cRun tests after build\u201d.<\/p>\n<p>You do this either in the Test Explorer (1) or from the top menu Test\/Test Settings\/Run Tests after Build (2).<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/6\/2019\/05\/SNAGHTML4cb5284e_thumb2.png\"><img decoding=\"async\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px\" title=\"SNAGHTML4cb5284e_thumb2\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2016\/02\/SNAGHTML4cb5284e_thumb2_thumb.png\" alt=\"SNAGHTML4cb5284e_thumb2\" width=\"909\" height=\"187\" border=\"0\" \/><\/a><\/p>\n<p>The effect of this can be seen in the screenshots below:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/6\/2019\/05\/image_thumb141.png\"><img decoding=\"async\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px\" title=\"image_thumb14\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2016\/02\/image_thumb14_thumb.png\" alt=\"image_thumb14\" width=\"916\" height=\"425\" border=\"0\" \/><\/a><\/p>\n<p>(1) Activate \u201cRun tests after build\u201d<\/p>\n<p>(2) Do some code changes<\/p>\n<p>(3) Just select Build,\u00a0 or use the keyboard shortcut<\/p>\n<p>(4) Just the touched test are being run, the other ones are shown dimmed green.\u00a0\u00a0 They ran green the last time they were run, but they were not run this time, because no code what changed that affected them. .<\/p>\n<p>If you have larger projects this can give a significant gain in performance, and make your turn around from build through test back to edit mode much faster \u2013 and that is what is important during development, right?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>(Editors Note:\u00a0 One of the most popular series of blog posts on the ALM Blog was Terje\u2019s posts on Unit Testing.\u00a0 So when he asked to republish his Norwegian post on the ALM blog the answer was of course an enthusiastic YES!.\u00a0 A little off topic this post also highlights we need a post on [&hellip;]<\/p>\n","protected":false},"author":81,"featured_media":45953,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1,252],"tags":[],"class_list":["post-11291","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","category-testing"],"acf":[],"blog_post_summary":"<p>(Editors Note:\u00a0 One of the most popular series of blog posts on the ALM Blog was Terje\u2019s posts on Unit Testing.\u00a0 So when he asked to republish his Norwegian post on the ALM blog the answer was of course an enthusiastic YES!.\u00a0 A little off topic this post also highlights we need a post on [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/11291","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/users\/81"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/comments?post=11291"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/11291\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media\/45953"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media?parent=11291"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/categories?post=11291"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/tags?post=11291"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}