1

I am working on some email automation and I have a separate test class for each language, kind of like this:

@isTest public class EnglishEmailTest {
    @isTest public static void test1() {
        ...
    }
    ...
}

@isTest public class GermanEmailTest {
    @isTest public static void test1() {
        ...
    }
    ...
}

@isTest public class SpanishEmailTest {
    @isTest public static void test1() {
        ...
    }
    ...
}

I am trying to get these tests to work all together in another class. It would look something like this:

@isTest public class AllEmailTest {
    @isTest public static void testAll() {
        EnglishEmailTest.test1();
        ...

        GermanEmailTest.test1();
        ...

        SpanishEmailTest.test1();
        ...

    }
}

I currently have something similar to this set up, but I keep getting DMLExceptions:

System.DmlException: Insert failed. First exception on row 0; first error: DUPLICATE_VALUE, duplicate value found: <unknown> duplicates value on record with id: <unknown>: []

The weird thing is that they all work fine separately, but once I combine them into one test class it causes problems.

Is there something I'm doing wrong?

2
  • the isTest context is only triggered once I believe, so even though you have isTest around the sub tests they are all still firing in the same session on the same stack, as opposed to firing separately and then refreshing the stack for each test. Oct 22, 2019 at 18:28
  • 2
    Why would you want one test to run several tests. Your question, while well written, seems to convey a fundamental misunderstanding of how unit testing works, and you've got a bit of an apparent XY Problem going on. Please edit your question to clarify your end goal that led you to this testing pattern.
    – Adrian Larson
    Oct 22, 2019 at 18:46

1 Answer 1

1

Your objective is a little misguided relative to the structure of Apex unit test classes and methods.

A unit test class is little more than a container, whose scope can be made useful to you - you can use the class to group related unit tests, and associate them with a @testSetup data factory method they use in common to perform setup prior to running the test.

Each unit test method represents a single test that's run in isolation from all other tests in terms of what data it can see, what limits it consumes, and what has happened in its transaction (each method runs in a separate transaction).

Running multiple unit test methods inside another unit test method doesn't really make sense. It breaks isolation, and hence results in errors like the one you're seeing as multiple tests attempt to insert similar setup data inside the same isolated context. You really don't want to do that. It makes your tests fragile and unreliable.

What you can do is group related unit test methods in a single class:

@isTest public class EmailTests {
    @isTest public static void testEnglishEmail() {
        ...
    }
    @isTest public static void testGermanEmail() {
        ...
    }
    @isTest public static void testSpanishEmail() {
        ...
    }
    ...
}

That gives you the semantic grouping you want (and, optionally, the chance to share an @testSetup method) while preserving critical test isolation for each run.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .