9

When writing code that interacts with external resources (such as using a web service or other network operation), I often structure the classes so that it can also be "stubbed" using a file or some other input method. So then I end up using the stubbed implementation to test other parts of the system and then one or two tests that specifically test calling the web service.

The problem is I don't want to be calling these external services either from Jenkins or when I run all of the tests for my project (e.g. "gradle test"). Some of the services have side effects, or may not be accessible to all developers.

Right now I just uncomment and then re-comment the @Test annotation on these particular test methods to enable and disable them. Enable it, run it manually to check it, then remember to comment it out again.

// Uncomment to test external service manually
//@Test
public void testSomethingExternal() {

Is there is a better way of doing this?

EDIT: For manual unit testing, I use Eclipse and am able to just right-click on the test method and do Run As -> JUnit test. But that doesn't work without the (uncommented) annotation.

Brad Peabody
  • 10,917
  • 9
  • 44
  • 63
  • It's not clear whether you're wanting an automated "profile" of unit tests that you can switch back and forth between or just a cleaner way of manually toggling them during development. – chrylis -cautiouslyoptimistic- Sep 06 '13 at 08:21
  • @chrylis What I was trying to do originally was to run an individual test. However, the idea of making a separate profile for these types of tests is probably a better approach. Although I still would want the ability to run some tests separately (in cases where there are side effects, for example - which I try to avoid but is sometimes inevitable). – Brad Peabody Sep 07 '13 at 22:51

4 Answers4

8

I recommend using junit categories. See this blog for details : https://community.oracle.com/blogs/johnsmart/2010/04/25/grouping-tests-using-junit-categories-0.

Basically, you can annotate some tests as being in a special category and then you can set up a two test suites : one that runs the tests of that category and one that ignores tests in that category (but runs everything else)

@Category(IntegrationTests.class)
public class AccountIntegrationTest {

  @Test
  public void thisTestWillTakeSomeTime() {
    ...
   }

  @Test
  public void thisTestWillTakeEvenLonger() {
     ....
  }

}

you can even annotate individual tests"

public class AccountTest {

   @Test
   @Category(IntegrationTests.class)
   public void thisTestWillTakeSomeTime() {
     ...
    }

Anytime I see something manually getting turned on or off I cringe.

sstendal
  • 3,148
  • 17
  • 22
dkatzel
  • 31,188
  • 3
  • 63
  • 67
  • Thanks - this sounds like a good idea. Not sure how this interacts with Gradle or Eclipse, will have to check that out further. – Brad Peabody Sep 07 '13 at 22:52
4

As far as I can see you use gradle and API for JUnit says that annotation @Ignore disables test. I will add gradle task which will add @Ignore for those tests.

pepuch
  • 6,346
  • 7
  • 51
  • 84
3

If you're just wanting to disable tests for functionality that hasn't been written yet or otherwise manually disable some tests temporarily, you can use @Ignore; the tests will be skipped but still noted in the report.

If you are wanting something like Spring Profiles, where you can define rulesets for which tests get run when, you should either split up your tests into separate test cases or use a Filter.

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
  • Interesting. See my edit above - maybe I could make a Filter that detects when I'm running a single test in Eclipse and (un)filters that test method appropriately. (Hadn't thought of this as being like Spring profiles, but yeah it's quite similar.) – Brad Peabody Sep 06 '13 at 08:29
2

You can use @Ignore annotation to prevent them from running automatically during test. If required, you may trigger such Ignored tests manually.

    @Test
    public void wantedTest() {
        return checkMyFunction(10);
    }

    @Ignore
    @Test
    public void unwantedTest() {
        return checkMyFunction(11);
    }

In the above example, unwantedTest will be excluded.

Rounak Datta
  • 442
  • 7
  • 10