How do I find all the unit tests that may dir开发者_运维技巧ectly or indirectly call a given method? When I change a method, I wish to know the best tests to run; there must be a tool for this!
As we have lots of interfaces, I am interested in all unit tests that calls a method on an interface when there is at least one path var the implantation method on a class that implements the interface.
Or in other words, I want a list of all unit tests when the tool cannot prove the result is not affected by the method I have changed.
(We are using nUnit on .net and have lots of slow unit tests, it will be many year until we have refactored all our unit tests to be fast)
see also:
- How to find Junit tests that are using a given Java method directly or indirectly
Visual Studio 2010 has this exact feature: http://blogs.msdn.com/b/phuene/archive/2009/12/07/test-impact-analysis-in-visual-studio-2010.aspx
Since you're using nunit, you could try this technique to run MSTest as well: http://msdn.microsoft.com/en-gb/magazine/cc163643.aspx#S4
In the most general case, when you use delegates, lambda expressions, etc., I have the intuition that this problem is equivalent to checking if a given program will finish (the Halting Problem), so I wouldn't hope to find a reasonable answer.
If your real goal is to be able to quickly test if your change broke something, I would recommend:
- refactoring your tests
- setting up a parallel build infrastructure with a cluster of build machines (easier than you might think with modern tools like TeamCity)
What you need is a relation between each test and the code it exercises.
This can be computed statically but it is hard and I don't know any tools that do it. Worse, if you had such a tool, the static analysis to decide what the test affected, might actually take longer than just running the test itself, so this doesn't look like an attractive direction.
However, this can be computed using a test coverage tool. For each individual test, run that test (we presume it passes) and collect the test coverage data. We now have a lot of pairs (t_i,c_i) for "test i has coverage c".
When the code base changes, the test data coverage sets can be consulted. A simple check: if for any (t_i,c_i), if c_i mentions file F, and F has changed, you need to run t_i again. Given test coverage data in almost any representation this is sort of easy to detect in the abstract. Given that most test coverage tools don't specifically tell you how they store the test coverage data, this is harder than it looks in practice.
Actually, what you want ideally is if c_i mentions any programmatic element of F, and that programmatic element has changed, you need to run t_i again.
Our SD Test Coverage tools provide this capability for Java and C#, at the level of methods. You need to set up some scripting to associate the actual test, however you have packaged it, with collected test coverage vectors. As a practical matter this tends to be pretty easy.
You can use VS2010's "View Call Hierarchy" or ReSharpers "ReSharper -> Inspect -> Incoming calls". You can even export the result from ReSharper.
If you want to use automation to achieve your goal, i.e. because this is not a one-time thing, but something you want to integrate into your build process, I suggest, you build your own solution. You could use Reflection or Mono.Cecil on the assemblies and walk the call hierarchy yourself. However, this can be quite time consuming, because you would need to create a complete call hierarchy tree over all your assemblies. Another possibility would be to create a Visual Studio or ReSharper plugin, so you can access the object model they create from your source code.
Basically, what I am saying is: I don't know of any currently existing method to achieve your goal via automation and writing your own solution will be fun but tricky and possibly time consuming, either when developing or running it.
精彩评论