4

I'm building a modular WPF application. Each screen is a highly independent and isolated unit. The only thing shared - shell and a common library with a facade interface for the reusable services (message bus, persistence, window management etc).

Since the modules are loosely coupled it doesn't make sense to retest everything when a single module changed. I want to test only what's changed. If there is a change in a common library - everything should be retested.

From a source control diff you can easily get a list of files changed and thus resolve the projects affected (csproj files has all the files to compile listed). You can also resolve the project dependencies from the csproj files (who's using it, who's affected). All this info should be enough to tell what actually needs testing. So the problem sounds solvable.

Has anyone done this with TeamCity? Any suggestions? I saw there is a solution for Java folks: http://blog.jetbrains.com/teamcity/2012/03/incremental-testing-with-teamcity/

What about the .net realm?

Pasho
  • 488
  • 3
  • 15

1 Answers1

8

You have to create build configurations and that generate artefacts and run tests.

For example you have projects Library, Library.Tests, Portable, Poratble.Tests, App and App.Tests.

You have to create build configuration (eg. Library build) that compiles Library and Library.Test projects. This configuration generates artefactes lets say eg. libtests.zip.

Then you create another build configuration (eg. Run Library Tests and set the snapshot and artefacts dependency on previously created Library build configuration. In this test running configuration you have unpacking the libtests.zip file (gathered from the artefacts dependency) and create a build step (eg. NUnit runner) to run those tests.

Be careful: You want to run tests only when something changes in Library, so under "Version Control Settings" check the Show changes from snapshot dependencies and create new VCS Trigger that will Trigger on changes in snapshot dependencies (also a checkbox).

Then, lets assume Portable is dependent on Library and have its own suite of tests.

Again, you should create build configuration that will compile projects Portable and Portable.Tests and generate artefacts called eg. portabletests.zip

And yet again you create another build configuration for running this tests the same as previous. only this time you should add another snapshot dependency on Build library and Run library tests configuration. With this additional snapshot dependency you will achieve that code is compiled and run only when library build and testrun is OK.

Same goes for App and App.Tests.

So... When change occures in Library the whole set is rebuild and all tests are run (Library.Tests, Portable.Tests, App, App.Tests). When change happens in Portable code, Bulid portables is triggered and Portable.Tests are run and App + App.Tests are recompiles and App.Tests are run.

On this link you can learn more about snapshot and artefacts dependencies in teamcity http://confluence.jetbrains.com/display/TCD8/Configuring+Dependencies

Dejan Dakić
  • 2,418
  • 2
  • 25
  • 39
  • Thanks! This explanation is very useful. One thing I not sure of is the need to define the dependencies manually, configure builds for each module. Feels like a lot of manual work. Project files have all the meta data to auto-generate that build projects structure (teamcity config). I could write a script for that myself if I knew the output structure and format. – Pasho Aug 20 '14 at 11:41
  • From my personal experience, i would not recommend doing this. Setting dependencies manually in teamcity is the way to go, you do not have to build single C# project (csproj). Eg. previously mentioned "Library build" could and should contain several C# projects (eg. Library.Caching, Library.Controls,...) – Dejan Dakić Aug 20 '14 at 11:50
  • And why not? Maximize the amount of work not done. In my case "Library" is a single proj and it's very unlikely to split. There is no practical reason to divide it. I don't like to think much about the future (what if someone want to reuse this). It's more likely that I'll guess it wrong. It's a problem when it's a problem. – Pasho Aug 20 '14 at 12:56
  • 90% of time I only change a single screen without touching the shared code. That's the main problem. Tracking changes in the shared source and triggering rebuild of the dependants is important too. – Pasho Aug 20 '14 at 13:01