I have some pet theories about code coverage which I'd like to explain first before I get on to answering the question.
First some context:
- There are many sorts of Code coverage, but I'm only going to talk about line coverage, but you should be able to substitute a different sort.
- From the question: "...someone checks in new code without unit tests and code coverage drops..." which is related to the similar: "Some one (refactors/eliminates duplication/replaces an algorithm and) removes tested code and coverage drops."
- Coverage should be measured as the result of running a single suite of tests. That is, not by running the application and stimulating it from the outside.
- Coverage as a percentage is very misleading.
I had a think about this and really you only want to know how many lines of code are NOT covered.
See my comment to this answer: Ensure minimal coverage on new Subversion commits
- Coverage should be as high as possible.
The question talks about "...improvement without allowing backsliding..."
- 100% coverage is possible.
I've done it, albeit with a library.
I have a theory that you should divide your code into just two divisions as far as code coverage is concerned:
- A division where all the code is 100% covered.
- A division where no code is covered.
Either division could be constituted by a number of projects, but members of a division should be files (given that both Java and C# have source files) and preferably whole folders of files. You could have one set of project in the first division and another set in the second division.
Now the report of lack of coverage is just the number of lines in the second division.
The mode of operation should be that you are testing your code as you go and code simply falls into the 100% coverage division. However, if you find a tricky piece of code which your brain just can't find a way to test, you should refactor so that the bits that aren't tested move into the second division. Alternatively you may get a brainwave and be able to find a test which raises the second division above 0%, at which point you refactor the code over to the first division. This means that every check-in maintains my theoretical invariant.
Now, back to the question:
No, I don't know TeamCity at all apart from a brief look at the JetBrains website, so I don't know how to update the coverage, but according to my theory it should be 100% or nothing, so can you set limits per project? If you can, then a fixed limit of 100% works for the first division.
If you can get two divisions you may want to do the automatic update thing with a lines of code metric for the second division, progressively lower is better.