IntelliJ Community . TestPractices

 
TestPractices 

HOME INDEX SEARCH CHANGES GO  
Test practices : How do you ...

(As usual, feel free to add questions. If you do, please add an anchor)


How do you test a class C?

(top)

  • For each class C => class TestC_C, in the same package
  • if appropriate, it will contain
   
      * test_1_constructors () {..}
      * test_2_isCanonical  () {..} // toString(), equals(), hashCode()
      * test_3_isComparable () {..}

--AlainRavet


How do you name test classes ?

(top)
  • test a class 'A' : => class TestC_A
  • test a functionality : => class Test_Persistence
  • acceptance test (httpunit..) : => class TestAT_027_03 == AT. 3 of the US (User Story) 27
--AlainRavet

  • unit test for class Example: ExampleUnitTest
  • functional test by intention: IntentionTest

That way, ants patternset collects unit tests by matching **/*UnitTest, and acceptance tests with including **/*Test and excluding **/*UnitTest

-- StefanRenz - 07 Jun 2002

I prefer prefixing a unit test class with "test" rather than postfixing. Acceptance tests get prefixed with "accept".

   * testMyClass
   * acceptThisThingDoesSomethingValuableForMyCustomer

That makes tests easier to find with Ctrl-N and also sounds more natural. I don't care about ant because I keep tests and production code in different folders.

-- KirillKalishev


How do you name test methods ?

(top)
  • test + ordernumber + what it tests :
       test_01_constructAnEmptyForm ()

Note: the ordernumber sole purpose it to help failure spotting, as in

       test_01_constructAnEmptyForm ()
       {
           assertTrue ("01.a: form is not empty"    , (new SomeForm(null)).isEmpty() ) ;
           ...
       }

--AlainRavet

In general, avoid relying on the order tests are run. I try to make the intention of the test clear:

  • testConstructEmptyForm()
  • testExecuteWithNullParameter()
  • testReverseArray()

-- StefanRenz - 07 Jun 2002


How do arrange/build your tests suites?

(top)

1°/ I place the tests in the same package - but different source tree - as the code they test:

  • Production code => [%project%]/__src__
  • Test code => [%project%]/__src-test__

2°/ Each package contains

  • 1 TestSuite : AllTests => call all the classes TestC_.. in this package

  • 1 TestSuite : AllAllTests => idem + call all subpackages' AllAllTests
--AlainRavet

I found that putting the unit tests together with the unit they test (i.e. same package, same location) works best. It underlines the fact that the unit test belongs closely to the unit.

Having them in separate directories often times results in the tests not being compiled or run or looked at.

As for putting together suites -- I refuse to maintain something like AllTests, which unfortunately is a common practice. It's a manual maintenance issue, and all too often people forget to add the test without even noticing. I use the <junit> ant task to collect and run all tests.

-- StefanRenz - 07 Jun 2002


When / how often do you run tests?

(top)
  • before writing the code : I work test-first
  • every 2 min. on average, (30 times/hour. (median = 1m.20s, avg=2m.))
It took some time to work that way comfortably, but I won't look back. --AlainRavet

After every finished change. That is, after a refactoring, after a task is finished, after a unit test is written, and before checking in.

-- StefanRenz - 07 Jun 2002


Tips you collected on the way

top

There is a lot of good stuff here and you can find a lot of good info on testing including several frameworks @ www.junit.org --SteveCarter

Example of One Time Execution of Setup and Teardown per test class

import junit.extensions.TestSetup;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;


public class OneTimeSetUpTearDownTemplate extends TestCase {

    public OneTimeSetUpTearDownTemplate(String t) {
        super(t);
    }

    public static class OneTimeTestSetup extends TestSetup {
        public OneTimeTestSetup( TestSuite ts ) {
            super( ts );
        }

        public void setUp() throws Exception {
            System.out.println( "One Time setUp" );
        }

        public void tearDown() throws Exception {
            System.out.println( "One Time tearDown" );
        }
    }

    public void setUp() throws Exception {
        System.out.println( "setUp for every test" );
    }

    public void tearDown() throws Exception {
        System.out.println( "tearDown for every test" );
    }

    public static Test suite() {
        return new OneTimeTestSetup( 
                new TestSuite( OneTimeSetUpTearDownTemplate.class ) 
                );
    }

    public static void main( String[] args ) {
        junit.swingui.TestRunner.main(new String[] { OneTimeSetUpTearDownTemplate.class.getName() } );
    }

    public void test1() throws Exception {
        System.out.println( "test 1" );
    }

    public void test2() throws Exception {
        System.out.println( "test 2" );
    }
}
--SteveCarter

to briefly disable a test method,
I put a 'z' before it's name

  • before : test_bigBugInHere ()
  • after : ztest_bigBugInHere ()
--AlainRavet

when a test method tests too much

  • it's intention is no longer clear
  • it is difficult too give it a good name.
=> I
  • duplicate it [Ctrl-D],
  • place the 1st 'things' tested in the 1st method, and the rest in the 2nd.
  • give them the best name I can find.
If necessary, repeat the process on the 2nd method. --AlainRavet

  • break it into smaller peaces
  • apply the same care as writing "production" code
  • refactor

-- StefanRenz - 07 Jun 2002

If you can't find a good name for a test method

  • it's not testing the good things, or
  • it's testing too much, or
  • it's not testing enough.
or
  • you are just not very good at finding good names. smile
--AlainRavet


What does a test skeleton look like?

Here's my usual unit test case template:

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 * Usual javadocumentation.
 */
public class FooBarUnitTest extends TestCase {
    
    /* fulfill TestCase contract */
    public FooBarUnitTest( String name ) {
        super( name );
    }

    /* Can be run standalone; probably don't need that with IDEA anymore */
    public static void main( String[] args ) {
        junit.textui.TestRunner.run( suite() );
    }

    /* easy adding of decorators */
    public static Test suite() {
        Test result;
        result = new TestSuite( FooBarUnitTest.class );
        return result;
    }

}

-- StefanRenz - 07 Jun 2002


How do test private methods?

XP-style unit testing dogma insists that you test private, package, protected, and public methods. Testing the public methods which call the private methods is not considered sufficiant. So, how does your test get to your private, protected, or package methods? Common solutions are:

1.) Make all methods public and enforce encapsulation by code audits, etc.

2.) Weaken encapsulation by making all methods public or package, then put your test in the same package as the class it tests.

3.) Make your test class an inner class of the class it tests.

-- Added by WalterMundt

"XP-style unit testing dogma insists..." -XP-style unit testing "dogma" says Test Everything That Could Possibly Break -- SteveQuinlan

I've lived well without testing of every method. Perhaps a better strategy to find a place to test is to ask youreself: "what do I want to see working?" then "I want to have a test for each method".

So I usually don't test private methods. If I want to, perhaps it must be public then? Or, if I made the extract method refactoring to make my code simpler, I would go crazy being asked to test every "extracted" method: I restructure my code often (what includes inlining/extracting methods) so I don't want to rewrite lots of tests just because I changed structure, not behavior (i.e. refactored that).

-- KirillKalishev

4.) Make all normally-private methods protected, then subclass the class with a TestClassName class that has public methodNameForTesting wrappers around all functions. Then you have a seperate ClassNameTest that subclasses TestCase and constructs and uses only the testing version of the class under test.

This keeps reasonably good encapsulation intact, and allows you to separate out your unit tests and keep them in another source tree, if you so desire. Also, it allows you to have different constructors used for testing only (protected constructors that the subclass 'publicizes'). Obviously, the TestClassName class should only be used inside of unit tests, but if you keep seperate source trees this is trivial to enforce. The only disadvantage is that you have to make sure not to have any production derived classes expose too much.

-- WalterMundt - 11 Jun 2002

The first two are not acceptable to me, so I use the third. Here is how my classes look:

class ReallyNeedsTesting {
   private void aMethod(){
   // etc...
   }

   public static void Test() extends TestCase
   {
      private ReallyNeedsTesting testSubject;

      public Test(String name){
      super(name);
      }

      // maybe a setup and teardown

      public void testAMethod(){
         subject.aMethod();
         assertTrue(etc);
      }
   }
}

Test classes are easily excluded from shipping code by telling ant not to include "**/*$Test.class" in the jar.

-- JimHughes - 10 Jun 2002

That

public static void Test() extends TestCase
should be
public static Test extends TestCase
shouldn't it? -- GwynEvans - 14 Aug 2002

To use an inner class, the example should be more like:

class ReallyNeedsTesting {
   private void aMethod(){
   // etc...
   }

   public static class Test extends TestCase
   {
      ...
   }

   ...
}
-- TonySobey - 07 Oct 2003

5.) Write yourself a private test helper class that uses reflection to invoke the method or get the field by name. Using reflection it is possible to temporarily override the access specifier to the method or field.

public static Object invokePrivateMethod( Object closedObject,
      String methodName, Class paramTypes[], Object params[] )
  {
    Object value = null;
    Method method = null;
    Class clazz = closedObject.getClass();
    try
    {
      while ( method == null && clazz != Object.class )
      {
        try
        {
          method = clazz.getDeclaredMethod( methodName, paramTypes );
        }
        catch ( NoSuchMethodException e )
        {
        }
        clazz = clazz.getSuperclass();
      }

      if ( method == null )
      {
        throw new NoSuchMethodException( "Unable to find " + methodName );
      }
      boolean acc = method.isAccessible();
      method.setAccessible( true );
      value = method.invoke( closedObject, params );
      method.setAccessible( acc );
    }
    catch ( Exception e )
    {
      e.printStackTrace();
      throw new RuntimeException( "Exception thrown: " + e.getMessage() );
    }
    return value;
  }
-- JustinHopper - 05 Oct 2002


How do you test UI ?

(top)

That can be a nightmare if you don't implement MVC pattern. If you do, that will be much simpler.

So, here is a basic idea:

  • make sure your application clearly implements MVC pattern
  • make MockObject for the model
  • make a test that instantiates the view and passes the mock there
  • make sure you proved with the test that as you touch the view, it generates a proper set of commands to the model (this is where the mock plays the game)
  • as you've done with that, you can test only the view, which is typically easier

Java has lots of things that help in testing of views. One of them is certainly AWT Robot that can generate native events from both mouse and keyboard. Things like JFCUnit may also help to find widgets to set the Robot on (however, it's not a big deal to implement that yourself)

-- KirillKalishev

Its important to consider the investment verse the payoff when automating UI tests. From my experience, the cost of performing a manual acceptance test from a written script verse automating and maintaining automated tests is usually more cost effective. If your UI is a web page, HTTPUnit is a good framework. Keep in mind if your UI is under constant change or being tweaked often, then developing automated tests can be costly and time consuming since they tend to be brittle and tied directly to text or widgets in the UI.


How do you measure test coverage?

(top)

I use Clover to measure test coverage, but the integration with IDEA is somewhat strained. I have to use ant to compile with clover instrumentation and then I run tests from IDEA with compilation turned off and then go back to ant to run the clover viewer. The process is somewhat error prone (that is what auto-compiling is there to prevent!) and is certainly more tedious than it needs to be.

Isn't there a better way?

-- TedDunning

I am happy to report that the latest Clover releases have a plugin for IDEA that makes this process much, much easier. They still have some fit and finish issues to resolve, but the bottom line is that I can run edit/compile/test/analyze entirely within IDEA without involving Ant at all. The world is a much better place.

-- TedDunning 1 Nov 2004

-- SteveCarter - 30 Oct 2002

You could use Koalog Code Coverage, we give free licenses for open-source projects.

At the moment, we don't integrate with IDEA directly but it shouldn't be difficult to get that done (we already integrate with Ant and we don't instrument the code).

I would be more than happy to participate in an open-source IDEA plugin, if you are interested.

-- YanGeorget - 15 May 2003

black jack internet black jack online black jack jack black free black jack black jack online casino poker online casino poker bingo casino gambling online poker casino poker chips internet casino poker poker casino game free poker free online poker free poker game free strip poker free video poker free texas holdem poker full poker tilt bonus code full poker tilt freeroll full poker tilt .net full poker tilt full poker review tilt internet poker internet poker game internet casino poker internet poker software internet poker site free internet poker online casino online casino gambling best online casino free online casino best online casino gambling online casino review online casino game online poker free online poker online poker game online poker rooms play online poker online video poker online poker tournament pacific poker 888 pacific poker pacific poker download pacific poker .com pacific poker bonus code pacific poker bonus paradise poker paradise poker scam paradise poker bonus code paradise poker net paradise poker .net paradise poker bonus party poker party poker bonus party poker bonus code party poker cheat free party poker poker party supply play poker play online poker play free poker play free poker online learn how to play poker play video poker chip poker chip poker set chip clay poker chip custom poker chip poker trick casino chip poker chip poker chip poker set chip clay poker chip custom poker chip poker trick casino chip poker poker hands winning poker hands rank poker hands best poker hands ranking of poker hands texas holdem poker hands poker room online poker rooms online poker room review poker room review free poker rooms poker rule holdem poker rule texas game poker rule poker rule tournament em hold poker rule texas poker software party poker cheat software free poker software online poker software internet poker software poker room software poker star poker star net poker star .net poker star .com poker star cheat poker star download poker super star poker table poker table supply poker table top how to build a poker table poker table plan poker table for sale folding poker table poker tournament online poker tournament free poker tournament free online poker tournament las vegas poker tournament poker tournament rule strip poker free strip poker video strip poker online strip poker strip poker game free online strip poker holdem poker texas free holdem poker texas holdem online poker texas holdem poker rule texas game holdem poker texas free game holdem poker texas video poker online video poker free video poker video strip poker poker video video poker game poker series world 2005 poker series world 2005 poker result series world game poker series video world machine slot free machine slot free game machine slot free machine play slot download machine slot game machine slot online slot machine buy slot machine buy home slot machine buy video slot machine buy used slot machine buy igt slot machine buy machine slot where buy casino slot machine free machine online slot free game machine online slot free machine online play slot casino free machine online slot free machine online realistic slot free machine online slot video best free machine online slot free slot machine free slot machine game play free slot machine free casino slot machine game free online slot machine free online slot machine game online slot machine free online slot machine play free slot machine play slot machine play free slot machine online play free slot machine game play slot machine online best slot machine to play slot machine for sale casino slot machine for sale video slot machine for sale used slot machine for sale wheel of fortune slot machine for sale antique slot machine for sale casino bonus online casino bonus no deposit casino bonus playtech casino bonus microgaming casino bonus free casino game casino game free online casino game online casino game casino game online casino gambling online casino gambling casino gambling internet online best casino gambling online casino gambling internet sports gambling sports hueyspicks gambling football online betting sports gambling online sports gambling free gambling free gambling tip free gambling money for online casino free online gambling gambling online free game internet gambling internet casino gambling online internet casino gambling internet casion gambling internet gambling poker online gambling online casino gambling internet casino gambling online best online casino gambling online gambling directory aladdin casino aladdin hotel and casino aladdin resort and casino aladdin hotel and casino las vegas aladdin casino las vegas argosy casino argosy casino indiana argosy casino kansas city argosy casino and hotel argosy casino lawrenceburg indiana casino foxwoods casino foxwoods resort casino ct foxwoods casino foxwoods hotel casino foxwoods hotel near free online casino game play free casino game online free online casino slot game free online casino game craps casino free gambling game online mohegan sun casino mohegan sun casino resort mohegan sun casino ct mohegan sun hotel and casino mohegan sun casino connecticut casino morongo morongo casino resort morongo indian casino morongo hotel and casino casino morongo ca casino niagara niagara falls casino seneca niagara casino niagara fallsview casino niagara fallsview casino resort pala casino pala resort and casino pala hotel and casino pala indian casino pala casino resort and spa pala casino san diego casino royale james bond casino royale casino royale las vegas casino royale hotel casino royale movie 2006 casino royale free casino game free online casino game free casino slot machine game free casino slot game play free casino game online play free casino game soaring eagle casino soaring eagle casino and resort soaring eagle casino michigan soaring eagle hotel and casino soaring eagle casino mt pleasant soaring eagle casino concert casino windsor windsor casino hotel casino windsor canada windsor ontario casino casino in windsor canada address casino windsor casino winstar casino oklahoma winstar casino ok thackerville winstar casino in oklahoma winstar casino ok winstar casino hotel winstar pechanga casino pechanga resort and casino pechanga casino temecula pechanga hotel and casino pechanga casino temecula ca

e d i t a t t a c h r e f - b y d i f f s m o r e
Have ideas, requests, problems regarding this site? Send feedback.
Copyright © 2000-2003 by the contributing authors. All materials at intellij.org are the property of the contributing authors.