@@ -1606,16 +1606,86 @@ public class TransferServiceTest {
1606
1606
<section id =" testcontext-ctx-management-caching" >
1607
1607
<title >Context caching</title >
1608
1608
1609
- <para >By default, once an
1610
- <interfacename >ApplicationContext</interfacename > has been loaded
1611
- for a test it will be reused for <emphasis
1609
+ <para >Once the TestContext framework loads an
1610
+ <interfacename >ApplicationContext</interfacename > for a test, that
1611
+ context will be cached and reused for <emphasis
1612
1612
role =" bold" >all</emphasis > subsequent tests that declare the same
1613
- <emphasis >unique</emphasis > context configuration within the same
1614
- process — for example, all tests run in a suite within an IDE or all
1615
- tests run for the same project with a build framework like Ant or
1616
- Maven. Thus the setup cost for loading an application context is
1617
- incurred only once (per test suite), and subsequent test execution
1618
- is much faster.</para >
1613
+ unique context configuration within the same test suite. To
1614
+ understand how caching works, it is important to understand what is
1615
+ meant by <emphasis >unique</emphasis > and <emphasis >test
1616
+ suite</emphasis >.</para >
1617
+
1618
+ <para >An <interfacename >ApplicationContext</interfacename > can be
1619
+ <emphasis >uniquely</emphasis > identified by the combination of
1620
+ configuration parameters that are used to load it. Consequently, the
1621
+ unique combination of configuration parameters are used to generate
1622
+ a <emphasis >key</emphasis > under which the context is cached. The
1623
+ TestContext framework uses the following configuration parameters to
1624
+ build the context cache key:</para >
1625
+
1626
+ <itemizedlist >
1627
+ <listitem >
1628
+ <para ><varname >locations</varname > <emphasis >(from
1629
+ @ContextConfiguration)</emphasis ></para >
1630
+ </listitem >
1631
+
1632
+ <listitem >
1633
+ <para ><varname >classes</varname > <emphasis >(from
1634
+ @ContextConfiguration)</emphasis ></para >
1635
+ </listitem >
1636
+
1637
+ <listitem >
1638
+ <para ><varname >contextLoader</varname > <emphasis >(from
1639
+ @ContextConfiguration)</emphasis ></para >
1640
+ </listitem >
1641
+
1642
+ <listitem >
1643
+ <para ><varname >activeProfiles</varname > <emphasis >(from
1644
+ @ActiveProfiles)</emphasis ></para >
1645
+ </listitem >
1646
+ </itemizedlist >
1647
+
1648
+ <para >For example, if <classname >TestClassA</classname > specifies
1649
+ <literal >{"app-config.xml", "test-config.xml"}</literal > for the
1650
+ <varname >locations</varname > (or <varname >value</varname >) attribute
1651
+ of <interfacename >@ContextConfiguration</interfacename >, the
1652
+ TestContext framework will load the corresponding
1653
+ <interfacename >ApplicationContext</interfacename > and store it in a
1654
+ <varname >static</varname > context cache under a key that is based
1655
+ solely on those locations. So if <classname >TestClassB</classname >
1656
+ also defines <literal >{"app-config.xml",
1657
+ "test-config.xml"}</literal > for its locations (either explicitly or
1658
+ implicitly through inheritance) and does not define a different
1659
+ <interfacename >ContextLoader</interfacename > or different active
1660
+ profiles, then the same
1661
+ <interfacename >ApplicationContext</interfacename > will be shared by
1662
+ both test classes. This means that the setup cost for loading an
1663
+ application context is incurred only once (per test suite), and
1664
+ subsequent test execution is much faster.</para >
1665
+
1666
+ <note >
1667
+ <title >Test suites and forked processes</title >
1668
+
1669
+ <para >The Spring TestContext framework stores application contexts
1670
+ in a <emphasis >static</emphasis > cache. This means that the
1671
+ context is literally stored in a <varname >static</varname >
1672
+ variable. In other words, if tests execute in separate processes
1673
+ the static cache will be cleared between each test execution, and
1674
+ this will effectively disable the caching mechanism.</para >
1675
+
1676
+ <para >To benefit from the caching mechanism, all tests must run
1677
+ within the same process or test suite. This can be achieved by
1678
+ executing all tests as a group within an IDE. Similarly, when
1679
+ executing tests with a build framework such as Ant or Maven it is
1680
+ important to make sure that the build framework does not
1681
+ <emphasis >fork</emphasis > between tests. For example, if the
1682
+ <ulink
1683
+ url =" http://maven.apache.org/plugins/maven-surefire-plugin/test-mojo.html#forkMode" >forkMode</ulink >
1684
+ for the Maven Surefire plug-in is set to <literal >always</literal >
1685
+ or <literal >pertest</literal >, the TestContext framework will not
1686
+ be able to cache application contexts between test classes and the
1687
+ build process will run significantly slower as a result.</para >
1688
+ </note >
1619
1689
1620
1690
<para >In the unlikely case that a test corrupts the application
1621
1691
context and requires reloading — for example, by modifying a bean
@@ -1624,10 +1694,10 @@ public class TransferServiceTest {
1624
1694
<interfacename >@DirtiesContext</interfacename > (see the discussion
1625
1695
of <interfacename >@DirtiesContext</interfacename > in <xref
1626
1696
linkend =" integration-testing-annotations-spring" />). This instructs
1627
- Spring to reload the configuration and rebuild the application
1628
- context before executing the next test. Note that support for the
1629
- <interfacename >@DirtiesContext</interfacename > annotation is
1630
- provided by the
1697
+ Spring to remove the context from the cache and rebuild the
1698
+ application context before executing the next test. Note that
1699
+ support for the <interfacename >@DirtiesContext</interfacename >
1700
+ annotation is provided by the
1631
1701
<classname >DirtiesContextTestExecutionListener</classname > which is
1632
1702
enabled by default.</para >
1633
1703
</section >
0 commit comments