+ Start a Discussion
jeremy_rjeremy_r 

Setting up tests

The examples for unit testing seem to be mixing the unit tests in with the domain classes.  I don't really like this, as I like to keep test classes separate from the domain classes being tested.  The problem seems to be that if you sepratate your test methods into test classes, Apex expects your test classes to be covered, which turns into an infinite loop. 

Can anyone share what they feel may be a clean and scalable way to do testing with Apex code?

thanks

Jeremy
tyler_jenningstyler_jennings
"Coverage" in most cases means literally "Executed". If your tests do not contain conditional logic (why would they, anyway?), they would always have 100% coverage. We have test classes for a number of triggers & other apex code and we show 100% coverage across all our code.

Does that make sense?

Here's what one of our test classes look like:

public class TestUpdateEscalationGroupTrigger {
static testMethod void escalationGroupAssignedFromOwningQueue() {
Group queue = [select id, name from Group where name = 'CSSD' and type = 'Queue'];
System.assert(queue.id != null);
Case c = new Case();
c.ownerId = queue.id;
insert c;

c = [select id, escalation_group__c from case where id = :c.id];
System.debug(c.Escalation_Group__c);
System.assert(c.Escalation_Group__c == queue.name);
}
}
jeremy_rjeremy_r
If the Test class's methods are all marked with testMethod, I don't think there are any problems.  However, typically there are some helper methods in the test class (setUp(), tearDown(), etc.).  The helper methods are called by the testMethods and would not be marked as testMethod themselves, so I'd assume that the deployment process would count the helper methods as needing to be covered by some other test. 

I also remember someone mentioning that each class has to have at least one test that covers it.  Would this mean that TestXXXCase class would have to be covered?

Message Edited by jeremy_r on 08-28-2007 02:27 PM

tyler_jenningstyler_jennings
That's what I was trying to get across in my first post. Coverage measures the percentage of code executed by your tests, not actually "tested". So your setUp() and tearDown() methods execute within the body of your test method and would therefore always show some percentage of coverage (most likely 100% coverage).

As to your second question, I don't know if it'll complain that your "test" classes must themselves have tests, we haven't done a deployment yet. That would certainly be a major pain for us.
sdudasduda
Here is how I setup my tests:

You can create another APEX class file, and include all of your tests in there (with all of the methods inside the class marked as testMethod)

Then, inside the class you wish to test, make a new testMethod, and have it call all of the methods you've created in the other class.

When you run the tests, the APEX engine will ignore the class with only test methods defined - you dont have to test the test methods! :)

Code:
ex:

File: MyCode.cls

public class MyCode {
    public static String echo(String input) {
       return input;
    }

    static testMethod void testMyCode() {
       TestMyCode.testEcho();
       .... add more here
    }

}

File: TestMyCode.cls

public class TestMyCode {
    static testMethod testEcho() {
       String output = MyCode.echo('Hello');
       System.assertEqual(output, 'Hello');
    }

    ... Add other test methods here
}

 


Message Edited by sduda on 08-28-2007 04:18 PM

jeremy_rjeremy_r
Thanks for the example.  I perfer to keep my classes under test completely seprate from my test classes.  I got excited for a minute after reading your post until I rememberd that testMethods have to be top level and static.  I think I can get by as long as constructors aren't considered to need coverage.


sdudasduda
Yes, they have to be defined as static, however, why would that stop you from testing a class w/ a constructor?
Code:
ex:

File: MyCode.cls

public class MyCode {

    private String data;

    public MyCode( String input ) {
        data = input;
    }

    public getData() {
       return data;
    }

    public static String echo(String input) {
       return input;
    }

    static testMethod void testMyCode() {
       TestMyCode.testAll();
    }

}

File: TestMyCode.cls

public class TestMyCode {
    static testMethod testAll() {
       String output = MyCode.echo('Hello');
       System.assertEqual(output, 'Hello');

       MyCode myCodeObj = new MyCode('Test');
       System.assertEqual( myCodeObj.getData(), 'Test' );


    }

    ... Add other test methods here
}

 

jeremy_rjeremy_r
It wouldn't.  What it does prevent one from doing is having any non-static methods in the Test class, other than constructor (haven't verified this yet).