18

Problem

Its quite a common problem I would like to think. Adding new code translates into regression - existing test cases become obsolete. Dependencies within the code mean even if you know how to fix this particular regression, there could be indirect regression at n more places in both directions - Afferent and Efferent.

Requirement

I have a shop running SVN, Maven+Nexus,Sonar,Jenkins and JIRA,QC,QTP. All in all a good CI environment.

With every new build I'll have new cases of regression. I want to find Java package dependencies in both directions and to update the test cases properly so as to cover all types of regression - direct and indirect. This is more of a problem as my unit test coverage is not even approaching 50% and automation of integration tests is not keeping pace with the development.

My options

  1. SONAR
  2. Google CodePRo
  3. JArchitect
  4. Jtest ( Had a discussion with the vendor Parasoft. They do not have a tool for this)
  5. Leverage the existing environment I have with, lets say, an Atlassian plugin
  6. Kalisitck (Vendor demo - Nice tool - involves a learning curve and cost)
  7. Coverity (Like Kalistick - learning curve and complex installation.Very expensive license.
  8. Any other open source/paid ?

JArchitect, SONAR and CodePro will give you a simple Matrix like this or this. Which satisfies half of my requirement by telling me which user and used-by classes are impacted. What I want is go 1 step further and have the tool tell me which corresponding test cases are impacted and if I need to update and/or execute them so as to cover my regression risks.

Kalistick, Coverity and maybe others might do what I want - they are heavy to setup and configure, grow with your system slowly so are not productive right away, come with a cost and need a learning curve.

Short question

Which tool(s) from above to use in my setup considering all factors like installation, learning curve, cost, availability or any other parameter.



I have already read the FAQ section on , few threads like Static Analysis tool recommendation for Java? , https://stackoverflow.com/questions/3716203/automatic-code-quality-and-architecture-quality-static-code-analysis and What is the fascination with code metrics? and many linked ones, but they don't answer my specific question.

bad_coder
  • 11,289
  • 20
  • 44
  • 72
Pulak Agrawal
  • 2,481
  • 4
  • 25
  • 49
  • 1
    It would be better to ask this on http://programmers.stackexchange.com/ – Ted Hopp Nov 09 '12 at 06:19
  • @TedHopp but this not really a programming question. this is more about getting advice from experts and suggestion on methodology, approach and experiences. You still think this should be moved ? While all related questions are on SO ? – Pulak Agrawal Nov 09 '12 at 06:24
  • 1
    It's not clear if this is a question about methodologies or tools. If you want to know about programming tools, then SO is the right place. If it's about development methodologies, then programmers is a better place. – Ted Hopp Nov 09 '12 at 06:45
  • @TedHopp edited to make it suitable for SO – Pulak Agrawal Nov 09 '12 at 06:48
  • 3
    I think this article at SCAM2012 was about Google's solution to the problem you present. http://research.google.com/pubs/pub38275.html If so, the fact that it's a research article about an in-house solution is rather bad news for you: you may not find any off-the-shelf solution. – Pascal Cuoq Nov 11 '12 at 11:31
  • @PascalCuoq 1 up for this .. pretty insightful articles on SCAM2012 – Pulak Agrawal Nov 14 '12 at 02:44
  • @PascalCuoq question updated. – Pulak Agrawal Nov 14 '12 at 02:52
  • You're a little unclear on what you want to do. I'm guessing you want to understand what part of the code is tested by which regression tests, so when a code change is made you can determine which tests need attention? ([Pascal may be surprised that] I haven't read the SCAM paper yet; only so many hours in the day). – Ira Baxter Jan 03 '13 at 06:33
  • @IraBaxter ur guess is correct. I thought was pretty clear in explaining – Pulak Agrawal Jan 03 '13 at 06:45

7 Answers7

2

With JDepend you can analyse dependencies between packages and even create unit tests to assure dependencies or integrate it with Fitnesse to have a nice dependency-table-test. This may help, if your tests are in specific packages...

Pulak Agrawal
  • 2,481
  • 4
  • 25
  • 49
wrm
  • 1,898
  • 13
  • 24
  • Thanks for the idea - I am going to evaluate this combination now. But when you say **if your tests are in specific packages...** do you mean unit tests only ? As I am looking more towards integration/functional tests – Pulak Agrawal Jan 04 '13 at 09:34
  • i said this because you can assert only package-to-package dependencies, not class-to-class (as would be needed, if your tests are e.g. in only one package (which probably is not the case)) – wrm Jan 04 '13 at 10:26
  • Jdepend is good, and I even got it running from a Jenkins plugin, but still this integration is not the best solution for me. You have contributed to my understanding of the problem itself even if I haven't got a final answer. Thanks – Pulak Agrawal Jan 09 '13 at 07:07
2

I'm a huge fan of Sonar myself, since you already have it running, and working in your CI environment, that would be my suggestion. I'm not quite sure how Sonar's Dependency Cycle Matrix doesn't already do what you want, or rather what it is you want in addition to that.

Mikkel Løkke
  • 3,710
  • 23
  • 37
  • thanks Mikkel. I have updated the question to make it clearer. This feature does half my job by telling me dependencies, but not relevant test cases hmmm.. lets us say SONAR integrated with QC and then this `Dependency Cycle Matrix` gave me a hyperlink to a corresponding test case. – Pulak Agrawal Jan 04 '13 at 09:31
  • You have contributed to my understanding of the problem itself even if I haven't got a final answer. Thanks – Pulak Agrawal Jan 09 '13 at 07:05
2

If I read the question correctly, you want a tool that analyses source code and determines which tests don't need to be rerun.

First thing to consider is what's the problem with always running all the tests? That's what CI means. If you can't run all your unit tests in 15 minutes and all your integration/stress tests overnight, resolve whatever issue causes that to be the case, probably by buying some hardware.

Failing that, the only thing that can track potential test regression is coverage analysis (e.g. http://www.eclemma.org/). Given even basic OO design, let alone dependency injection, static package or class dependencies are at best meaningless, and probably actively misleading, in terms of what changes can cause what tests to fail. And that's ignoring the case where the problem is A should be calling B, and isn't. However, cross-reference changed files with called files and if there is no intersection, maybe not rerunning the test is arguably safeish - the remaining failures will be things like some code adding an event handler where there wasn't one before.

I don't think there is a free tool to do this, but it should be scriptable from Jenkins/Emma/Git. Or use one of the integrated solutions like Kalistick. But I'd be sceptical that it could efficiently beat human judgement based on communication with the development team as to what they are trying to do.

On a vaguely related note, the simple tool the Java world actually needs, but doesn't afaik exist, is an extension to junit that runs a set of tests in dependency order, and stop on the first error. That would provide a little bit of extra help to let a developer focus on the most likely source of a regression.

soru
  • 5,464
  • 26
  • 30
  • About your last paragraph. It does exist. It's called TestNG and it's a replacement of junit instead of an extension. See [this](http://testng.org/doc/documentation-main.html#dependent-methods) for details. It doesn't stop but skips the dependent tests if an earlier test fails – Hilikus Jan 04 '13 at 15:43
  • That isn't what I meant at all - you have to specify the 'dependency' at the test level as an annotation. That's just a roundabout way of writing a test suite. I was talking about something that analysed the code jdepend style and concluded it should run CurrencyValueTest before DerivativeTest. – soru Jan 04 '13 at 17:13
  • @soru nice way to present the question; your understanding is correct. But, its based on the assumption that my tests (unit and integration) is completely written AND automated by Selenium/QTP etc, which is not true in my case. Meaning my shop is not pure CI yet, not the testing part at least. I have updated the question to reflect this now. Thanks – Pulak Agrawal Jan 07 '13 at 02:32
  • Given manual testing, then I don't think the probem can be solved by a tool, because the tool won't know what is in the manual tests. – soru Jan 07 '13 at 11:24
  • Actually it can be , like I have mentioned , by Kalistick and Coverity. – Pulak Agrawal Jan 08 '13 at 03:13
  • 1
    Ah I see, they work by taking code coverage of a manual test as it is executed. That makes dependency tracking redundant - either code was called during the test, or it wasn't. – soru Jan 08 '13 at 10:40
  • You have contributed to my understanding of the problem itself even if I haven't got a final answer. Thanks – Pulak Agrawal Jan 09 '13 at 07:08
2

You can find up-to Class level dependencies using Classycle-Dependency Checker. And the section - Check Classes Dependency in the guide might help in your case. However, normally using a static analysis tool we analyze either source codebase (e.g.: Project->src directory) or test codebase (e.g.: Project->test directory) but not both. But in your case it seems that you want to find out dependencies between source and test code too. So, executing an appropriate dependency analysis tool by providing the input path as the parent path of both src and test (e.g.: project root directory) is may be what you need (e.g.: using dependencies find out -> if source X changes, what dependent classes in tests get impacted by that change).

2

The best tool you can find for your problem is actually not a tool, but a practise. I strongly suggest you read about Test Driven Development (see Lasse Koskela's book), and Specification by Example (see Gojko Adzic's books, they're great).

Using these practises will fundamentally change two things:

  1. You will have a test coverage close to 100%
  2. The tests will become first class citizens and will be the centre point of your code

The reason why I find this relevant to your question is that your scenario hints for the exact opposite role of the tests: people will perform changes in code and they'll then think "oh, no...now I have to go figure out what I broke in those damn tests".

From my experience, tests should not be overlooked or considered "lower grade code". And while my answer points to a methodology change that will only have visible results on the long run, it might help avoid the issue altogether in the future.

mmalmeida
  • 1,037
  • 9
  • 27
  • 2
    I am aware of TDD-XP-agile :) - a strategic solution and a long-term CI goal. What I want right now is a solution-in-a-conventional-waterfall-project-with-limited-budget-and-slow-changing-FS-company. – Pulak Agrawal Jan 07 '13 at 09:42
  • You have contributed to my understanding of the problem itself even if I haven't got a final answer. Thanks – Pulak Agrawal Jan 09 '13 at 07:06
2

Some tools which might help. Note not all of them intergrate with CI.

iPlasma is a great tool

CodePro is an Eclipse Plugin which help in detecting code and design problems (e.g. duplicated code, classes that break encapsulation, or methods placed in a wrong class). (Now acquired by Google )

Relief is a tool visualizing the following parameters of Java projects: size of a package, i.e. how many classes and interfaces it contains the kind of item being visualized (Packages and classes are represented as boxes, interfaces and type's fields as spheres). how heavy an item is being used (represented as gravity, i.e. distance of center) number of dependancies (represented as depth).

Stan4j is a commercial tool that costs a couple of hundred $. It is targeting only Java projects, comes very close to (or a little better reports than? not sure) Sonar. It has a good Eclipse integration.

Intellij Dependency Analysis

From what I could understand from your problem is that - you need to track two OO metrics - Efferent Coupling (Ca) and Afferent Couplings (Ce). With this you can narrow down to the required packages. You can explore the oppurtunity of writing an eclipse plugin which on every build - can highlight the required classes based on the Ca, Ce metrics.

Pulak Agrawal
  • 2,481
  • 4
  • 25
  • 49
basav
  • 1,453
  • 10
  • 18
2

You can figure out which tests are relevant by tracking what code they touch. You can track what code they touch by using test coverage tools.

Most test coverage tools build an explicit set of locations that a running test executes; that's the point of "coverage". If you organize your test running to execute one unit test at a time, and then take a snapshot of the coverage data, then you know for each test what code it covers.

When code is modified, you can determine the intersection of the modified code and what an individual test covers. If the intersection is non-empty, you surely need to run that test again, and likely you'll need to update it.

There are a several practical problems with making this work.

First, it is often hard to figure out how the test coverage tools record this positioning data. Second, you have to get the testing mechanism to capture it on per test basis; that may be awkward to organize, and/or the coverage data may be clumsy to extract and store. Third, you need to compute the intersection of "code modified" with "code covered" by a test; this is abstractly largely a problem in intersecting big bit vectors. Finally, capturing "code modified" is bit tricky because sometimes code moves; if location 100 in a file was tested, and the line moves in the file, you may not get comparable position data. That will lead to false positives and false negatives.

There are test coverage tools which record the coverage data in an easily captured form, and can do the computations. Determine code changes is trickier; you can use diff but the moved code will confuse the issue somewhat. You can find diff tools that compare code structures, which identify such moves, so you can get better answers.

If you have source code slicers, you could compute how the output tested is (backward slice-)dependent on the input; all code in that slice affects the test, obviously. I think the bad news here is that such slicers are not easy to get.

Ira Baxter
  • 93,541
  • 22
  • 172
  • 341
  • thanks.. you have articulated the theoretical solution well, hence I am awarding the bounty to you. Though it sill is not a direct answer for me so not accepting as one. Everybody here has contributed to my understanding of the problem itself even if I haven't got a final answer. Thanks to all – Pulak Agrawal Jan 09 '13 at 07:04